148 lines
5.0 KiB
Diff
148 lines
5.0 KiB
Diff
commit e6a9381f78605072cab52447fce35eaa98c1e75c
|
|
Author: Brian <brian@yutani.localnet.net>
|
|
Date: Mon Feb 26 11:37:37 2007 -0700
|
|
|
|
Do proper framebuffer refcounting in _mesa_make_current().
|
|
|
|
Also, added DeletePending field to gl_framebuffer used when a window has been
|
|
deleted, but there still may be rendering contexts attached to the
|
|
gl_framebuffer object.
|
|
|
|
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
|
|
index 9b3759b..1245c10 100644
|
|
--- a/src/mesa/main/context.c
|
|
+++ b/src/mesa/main/context.c
|
|
@@ -95,6 +95,7 @@
|
|
#include "fbobject.h"
|
|
#include "feedback.h"
|
|
#include "fog.h"
|
|
+#include "framebuffer.h"
|
|
#include "get.h"
|
|
#include "glthread.h"
|
|
#include "glapioffsets.h"
|
|
@@ -1666,6 +1667,8 @@ void
|
|
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
|
|
GLframebuffer *readBuffer )
|
|
{
|
|
+ GET_CURRENT_CONTEXT(oldCtx);
|
|
+
|
|
if (MESA_VERBOSE & VERBOSE_API)
|
|
_mesa_debug(newCtx, "_mesa_make_current()\n");
|
|
|
|
@@ -1690,6 +1693,15 @@ _mesa_make_current( GLcontext *newCtx, G
|
|
_glapi_set_context((void *) newCtx);
|
|
ASSERT(_mesa_get_current_context() == newCtx);
|
|
|
|
+ if (oldCtx) {
|
|
+ if (oldCtx->WinSysDrawBuffer) {
|
|
+ _mesa_dereference_framebuffer(&oldCtx->WinSysDrawBuffer);
|
|
+ }
|
|
+ if (oldCtx->WinSysReadBuffer) {
|
|
+ _mesa_dereference_framebuffer(&oldCtx->WinSysReadBuffer);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (!newCtx) {
|
|
_glapi_set_dispatch(NULL); /* none current */
|
|
}
|
|
@@ -1703,6 +1715,8 @@ _mesa_make_current( GLcontext *newCtx, G
|
|
ASSERT(readBuffer->Name == 0);
|
|
newCtx->WinSysDrawBuffer = drawBuffer;
|
|
newCtx->WinSysReadBuffer = readBuffer;
|
|
+ drawBuffer->RefCount++;
|
|
+ readBuffer->RefCount++;
|
|
|
|
/*
|
|
* Only set the context's Draw/ReadBuffer fields if they're NULL
|
|
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
|
|
index 4651974..d061d22 100644
|
|
--- a/src/mesa/main/framebuffer.c
|
|
+++ b/src/mesa/main/framebuffer.c
|
|
@@ -166,6 +166,8 @@ _mesa_initialize_framebuffer(struct gl_f
|
|
|
|
_glthread_INIT_MUTEX(fb->Mutex);
|
|
|
|
+ fb->RefCount = 1;
|
|
+
|
|
/* save the visual */
|
|
fb->Visual = *visual;
|
|
|
|
@@ -198,7 +200,6 @@ void
|
|
_mesa_destroy_framebuffer(struct gl_framebuffer *fb)
|
|
{
|
|
if (fb) {
|
|
- _glthread_DESTROY_MUTEX(fb->Mutex);
|
|
_mesa_free_framebuffer_data(fb);
|
|
_mesa_free(fb);
|
|
}
|
|
@@ -216,6 +217,8 @@ _mesa_free_framebuffer_data(struct gl_fr
|
|
|
|
assert(fb);
|
|
|
|
+ _glthread_DESTROY_MUTEX(fb->Mutex);
|
|
+
|
|
for (i = 0; i < BUFFER_COUNT; i++) {
|
|
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
|
|
if (att->Renderbuffer) {
|
|
@@ -605,21 +608,25 @@ update_color_draw_buffers(GLcontext *ctx
|
|
GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
|
|
GLuint count = 0;
|
|
GLuint i;
|
|
- /* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
|
|
- * can specify writing to two or four color buffers (for example).
|
|
- */
|
|
- for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
|
- const GLuint bufferBit = 1 << i;
|
|
- if (bufferBit & bufferMask) {
|
|
- struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
|
- if (rb) {
|
|
- fb->_ColorDrawBuffers[output][count] = rb;
|
|
- count++;
|
|
- }
|
|
- else {
|
|
- /*_mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");*/
|
|
+ if (!fb->DeletePending) {
|
|
+ /* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
|
|
+ * can specify writing to two or four color buffers (for example).
|
|
+ */
|
|
+ for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
|
|
+ const GLuint bufferBit = 1 << i;
|
|
+ if (bufferBit & bufferMask) {
|
|
+ struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
|
|
+ if (rb) {
|
|
+ fb->_ColorDrawBuffers[output][count] = rb;
|
|
+ count++;
|
|
+ }
|
|
+ else {
|
|
+ /*
|
|
+ _mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");
|
|
+ */
|
|
+ }
|
|
+ bufferMask &= ~bufferBit;
|
|
}
|
|
- bufferMask &= ~bufferBit;
|
|
}
|
|
}
|
|
fb->_NumColorDrawBuffers[output] = count;
|
|
@@ -635,7 +642,7 @@ static void
|
|
update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
|
|
{
|
|
(void) ctx;
|
|
- if (fb->_ColorReadBufferIndex == -1) {
|
|
+ if (fb->_ColorReadBufferIndex == -1 || fb->DeletePending) {
|
|
fb->_ColorReadBuffer = NULL; /* legal! */
|
|
}
|
|
else {
|
|
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
|
|
index e8f0f45..422d176 100644
|
|
--- a/src/mesa/main/mtypes.h
|
|
+++ b/src/mesa/main/mtypes.h
|
|
@@ -2243,6 +2243,7 @@ struct gl_framebuffer
|
|
_glthread_Mutex Mutex; /**< for thread safety */
|
|
GLuint Name; /* if zero, this is a window system framebuffer */
|
|
GLint RefCount;
|
|
+ GLboolean DeletePending;
|
|
|
|
GLvisual Visual; /**< The framebuffer's visual.
|
|
Immutable if this is a window system buffer.
|