From e6a9381f78605072cab52447fce35eaa98c1e75c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 26 Feb 2007 11:37:37 -0700 Subject: 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. --- src/mesa/main/framebuffer.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/mesa/main/framebuffer.c') diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 465197401b7..d061d22d9b8 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -166,6 +166,8 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) _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_framebuffer *fb) 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, struct gl_framebuffer *fb) 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 { -- cgit v1.2.3 From f30e31276304696558abffdd9a6e3df21d41c0f5 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 27 Feb 2007 11:09:28 -0700 Subject: assert that fb->RefCount==0 in _mesa_free_framebuffer_data() --- src/mesa/main/framebuffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/main/framebuffer.c') diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index d061d22d9b8..3fe70f449c2 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -216,6 +216,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) GLuint i; assert(fb); + assert(fb->RefCount == 0); _glthread_DESTROY_MUTEX(fb->Mutex); -- cgit v1.2.3 From 593802c0b0f451299ac2598c6de61e884fb44830 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Mar 2007 09:49:15 -0700 Subject: Take care of texObj reference in _mesa_free_framebuffer_data() --- src/mesa/main/framebuffer.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/mesa/main/framebuffer.c') diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 3fe70f449c2..dabc96d91d9 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -223,16 +223,21 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; if (att->Renderbuffer) { - struct gl_renderbuffer *rb = att->Renderbuffer; - /* remove framebuffer's reference to renderbuffer */ - _mesa_dereference_renderbuffer(&rb); - if (rb && rb->Name == 0) { - /* delete window system renderbuffer */ - _mesa_dereference_renderbuffer(&rb); + _mesa_dereference_renderbuffer(&att->Renderbuffer); + } + if (att->Texture) { + /* render to texture */ + att->Texture->RefCount--; + if (att->Texture->RefCount == 0) { + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + ctx->Driver.DeleteTexture(ctx, att->Texture); + } } } att->Type = GL_NONE; att->Renderbuffer = NULL; + att->Texture = NULL; } /* unbind depth/stencil to decr ref counts */ -- cgit v1.2.3 From a510bc3ee1a696da120c09ee4ec33dc033f671ac Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Mar 2007 10:07:59 -0700 Subject: Fix/improve framebuffer object reference counting. Use _mesa_reference_framebuffer() and _mesa_unreference_framebuffer() functions to be sure reference counting is done correctly. Additional assertions are done too. Note _mesa_dereference_framebuffer() renamed to "unreference" as that's more accurate. --- src/mesa/drivers/allegro/amesa.c | 2 +- src/mesa/drivers/dri/fb/fb_dri.c | 6 +--- src/mesa/drivers/dri/ffb/ffb_xmesa.c | 2 +- src/mesa/drivers/dri/gamma/gamma_xmesa.c | 2 +- src/mesa/drivers/dri/i810/i810screen.c | 3 +- src/mesa/drivers/dri/i915/intel_screen.c | 3 +- src/mesa/drivers/dri/i915tex/intel_screen.c | 3 +- src/mesa/drivers/dri/i965/intel_screen.c | 3 +- src/mesa/drivers/dri/mach64/mach64_screen.c | 2 +- src/mesa/drivers/dri/mga/mga_xmesa.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 2 +- src/mesa/drivers/dri/r128/r128_screen.c | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 2 +- src/mesa/drivers/dri/s3v/s3v_xmesa.c | 2 +- src/mesa/drivers/dri/savage/savage_xmesa.c | 2 +- src/mesa/drivers/dri/sis/sis_screen.c | 2 +- src/mesa/drivers/dri/tdfx/tdfx_screen.c | 2 +- src/mesa/drivers/dri/trident/trident_context.c | 2 +- src/mesa/drivers/dri/unichrome/via_screen.c | 2 +- src/mesa/drivers/glide/fxapi.c | 4 +-- src/mesa/drivers/osmesa/osmesa.c | 3 +- src/mesa/drivers/svga/svgamesa.c | 1 - src/mesa/drivers/x11/xm_api.c | 4 +-- src/mesa/main/context.c | 25 +++++++------- src/mesa/main/fbobject.c | 32 ++++++------------ src/mesa/main/framebuffer.c | 46 ++++++++++++++++++-------- src/mesa/main/framebuffer.h | 6 +++- src/mesa/main/rbadaptors.c | 6 ++-- src/mesa/main/renderbuffer.c | 23 +++++++------ src/mesa/main/renderbuffer.h | 2 +- 30 files changed, 101 insertions(+), 97 deletions(-) (limited to 'src/mesa/main/framebuffer.c') diff --git a/src/mesa/drivers/allegro/amesa.c b/src/mesa/drivers/allegro/amesa.c index 594668affda..518211ccf46 100644 --- a/src/mesa/drivers/allegro/amesa.c +++ b/src/mesa/drivers/allegro/amesa.c @@ -338,7 +338,7 @@ void AMesaDestroyBuffer(AMesaBuffer buffer) { if (buffer->Screen) destroy_bitmap(buffer->Screen); if (buffer->Background) destroy_bitmap(buffer->Background); - _mesa_destroy_framebuffer(buffer->GLBuffer); + _mesa_unreference_framebuffer(&buffer->GLBuffer); free(buffer); } diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c index 08b52b4d8f7..a6d7590eff7 100644 --- a/src/mesa/drivers/dri/fb/fb_dri.c +++ b/src/mesa/drivers/dri/fb/fb_dri.c @@ -480,11 +480,7 @@ fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)driDrawPriv->driverPrivate; - - _mesa_free(mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data); - _mesa_destroy_framebuffer(mesa_framebuffer); - driDrawPriv->driverPrivate = NULL; + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 215aaf8ffba..4c5323d230e 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -392,7 +392,7 @@ ffbCreateBuffer(__DRIscreenPrivate *driScrnPriv, static void ffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c index e8922b15036..f41682cea71 100644 --- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c +++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c @@ -97,7 +97,7 @@ gammaCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static void diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index ebe2615fe87..f64c10a9ae0 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -398,8 +398,7 @@ i810CreateBuffer( __DRIscreenPrivate *driScrnPriv, static void i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - /* _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); */ - _mesa_dereference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index 942e1e9c226..67e176a1c6f 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -449,8 +449,7 @@ static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - /* _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); */ - _mesa_dereference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index bc538902b4c..ac83254593b 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -609,8 +609,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, static void intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) { - /* _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); */ - _mesa_dereference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 06e5d0c5bd7..5dac50df32c 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -457,8 +457,7 @@ static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - /* _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); */ - _mesa_dereference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 1014b8acd52..4e9e216e7db 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -435,7 +435,7 @@ mach64CreateBuffer( __DRIscreenPrivate *driScrnPriv, static void mach64DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index f024f73eb6a..67a6f8bdf09 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -831,7 +831,7 @@ mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static void diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 24e77750f93..e00080fce1e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -202,7 +202,7 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, static void nouveauDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static int diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 4f1b20aadd7..880dee85c25 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -357,7 +357,7 @@ r128CreateBuffer( __DRIscreenPrivate *driScrnPriv, static void r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index fc5aa114621..abb14faaa13 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -901,7 +901,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } #if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c index c451f7452bf..c66fd6dac31 100644 --- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c +++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c @@ -131,7 +131,7 @@ s3vCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void s3vDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static void diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index ad79b9235c1..f859217069c 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -710,7 +710,7 @@ savageCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void savageDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } #if 0 diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 8f52cfe098e..89d734ba786 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -233,7 +233,7 @@ sisCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static void sisCopyBuffer( __DRIdrawablePrivate *dPriv ) diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 646f5126eb0..1f9ff4e30ca 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -233,7 +233,7 @@ tdfxCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void tdfxDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c index dbbd1ac0c69..8dc7f0dc781 100644 --- a/src/mesa/drivers/dri/trident/trident_context.c +++ b/src/mesa/drivers/dri/trident/trident_context.c @@ -279,7 +279,7 @@ tridentCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void tridentDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } static void diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index 28e1f9451e6..90f76be44d4 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -320,7 +320,7 @@ viaCreateBuffer(__DRIscreenPrivate *driScrnPriv, static void viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - _mesa_destroy_framebuffer((GLframebuffer *)(driDrawPriv->driverPrivate)); + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); } diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c index e535e739b31..00b9d29fac1 100644 --- a/src/mesa/drivers/glide/fxapi.c +++ b/src/mesa/drivers/glide/fxapi.c @@ -728,7 +728,7 @@ errorhandler: FREE(fxMesa->fogTable); } if (fxMesa->glBuffer) { - _mesa_destroy_framebuffer(fxMesa->glBuffer); + _mesa_unreference_framebuffer(&fxMesa->glBuffer); } if (fxMesa->glVis) { _mesa_destroy_visual(fxMesa->glVis); @@ -828,7 +828,7 @@ fxMesaDestroyContext(fxMesaContext fxMesa) fxDDDestroyFxMesaContext(fxMesa); /* must be before _mesa_destroy_context */ _mesa_destroy_visual(fxMesa->glVis); _mesa_destroy_context(fxMesa->glCtx); - _mesa_destroy_framebuffer(fxMesa->glBuffer); + _mesa_unreference_framebuffer(&fxMesa->glBuffer); fxTMClose(fxMesa); /* must be after _mesa_destroy_context */ FREE(fxMesa); diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index c4fc8821e50..96b9b5c1741 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -1303,7 +1303,8 @@ OSMesaDestroyContext( OSMesaContext osmesa ) _swrast_DestroyContext( &osmesa->mesa ); _mesa_destroy_visual( osmesa->gl_visual ); - _mesa_destroy_framebuffer( osmesa->gl_buffer ); + _mesa_unreference_framebuffer( &osmesa->gl_buffer ); + _mesa_free_context_data( &osmesa->mesa ); _mesa_free( osmesa ); } diff --git a/src/mesa/drivers/svga/svgamesa.c b/src/mesa/drivers/svga/svgamesa.c index 0dd9a144fe8..d1385875690 100644 --- a/src/mesa/drivers/svga/svgamesa.c +++ b/src/mesa/drivers/svga/svgamesa.c @@ -433,7 +433,6 @@ void SVGAMesaDestroyContext( SVGAMesaContext ctx ) if (ctx) { _mesa_destroy_visual( ctx->gl_vis ); _mesa_destroy_context( ctx->gl_ctx ); - _mesa_destroy_framebuffer( ctx->gl_buffer ); free( ctx ); if (ctx==SVGAMesa) { SVGAMesa = NULL; diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 2cd7d8a6ca1..a42de72827f 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -485,8 +485,8 @@ xmesa_free_buffer(XMesaBuffer buffer) /* mark as delete pending */ fb->DeletePending = GL_TRUE; - /* Dereference. If count = zero we'll really delete the buffer */ - _mesa_dereference_framebuffer(&fb); + /* Unreference. If count = zero we'll really delete the buffer */ + _mesa_unreference_framebuffer(&fb); return; } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 1245c10cc2c..135c814c0a6 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1408,6 +1408,13 @@ _mesa_free_context_data( GLcontext *ctx ) if (ctx == _mesa_get_current_context()) { _mesa_make_current(NULL, NULL, NULL); } + else { + /* unreference WinSysDraw/Read buffers */ + _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); + _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); + _mesa_unreference_framebuffer(&ctx->DrawBuffer); + _mesa_unreference_framebuffer(&ctx->ReadBuffer); + } _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); @@ -1694,12 +1701,8 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, ASSERT(_mesa_get_current_context() == newCtx); if (oldCtx) { - if (oldCtx->WinSysDrawBuffer) { - _mesa_dereference_framebuffer(&oldCtx->WinSysDrawBuffer); - } - if (oldCtx->WinSysReadBuffer) { - _mesa_dereference_framebuffer(&oldCtx->WinSysReadBuffer); - } + _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer); + _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer); } if (!newCtx) { @@ -1713,20 +1716,18 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, ASSERT(drawBuffer->Name == 0); ASSERT(readBuffer->Name == 0); - newCtx->WinSysDrawBuffer = drawBuffer; - newCtx->WinSysReadBuffer = readBuffer; - drawBuffer->RefCount++; - readBuffer->RefCount++; + _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); + _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); /* * Only set the context's Draw/ReadBuffer fields if they're NULL * or not bound to a user-created FBO. */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { - newCtx->DrawBuffer = drawBuffer; + _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { - newCtx->ReadBuffer = readBuffer; + _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); } newCtx->NewState |= _NEW_BUFFERS; diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index a99ff9dc97e..6608eefc6c0 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -602,7 +602,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) oldRb = ctx->CurrentRenderbuffer; if (oldRb) { - _mesa_dereference_renderbuffer(&oldRb); + _mesa_unreference_renderbuffer(&oldRb); } ASSERT(newRb != &DummyRenderbuffer); @@ -639,7 +639,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) /* But the object will not be freed until it's no longer * bound in any context. */ - _mesa_dereference_renderbuffer(&rb); + _mesa_unreference_renderbuffer(&rb); } } } @@ -998,12 +998,6 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) } _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb); } - _glthread_LOCK_MUTEX(newFb->Mutex); - if (bindReadBuf) - newFb->RefCount++; - if (bindDrawBuf) - newFb->RefCount++; - _glthread_UNLOCK_MUTEX(newFb->Mutex); } else { /* Binding the window system framebuffer (which was originally set @@ -1020,22 +1014,16 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) */ if (bindReadBuf) { - struct gl_framebuffer *oldFb = ctx->ReadBuffer; - if (oldFb && oldFb->Name != 0) { - _mesa_dereference_framebuffer(&oldFb); - } - ctx->ReadBuffer = newFb; + _mesa_unreference_framebuffer(&ctx->ReadBuffer); + _mesa_reference_framebuffer(&ctx->ReadBuffer, newFb); } if (bindDrawBuf) { - struct gl_framebuffer *oldFb = ctx->DrawBuffer; - if (oldFb && oldFb->Name != 0) { - /* check if old FB had any texture attachments */ - check_end_texture_render(ctx, oldFb); - /* check if time to delete this framebuffer */ - _mesa_dereference_framebuffer(&oldFb); - } - ctx->DrawBuffer = newFb; + /* check if old FB had any texture attachments */ + check_end_texture_render(ctx, ctx->DrawBuffer); + /* check if time to delete this framebuffer */ + _mesa_unreference_framebuffer(&ctx->DrawBuffer); + _mesa_reference_framebuffer(&ctx->DrawBuffer, newFb); if (newFb->Name != 0) { /* check if newly bound framebuffer has any texture attachments */ check_begin_texture_render(ctx, newFb); @@ -1083,7 +1071,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) /* But the object will not be freed until it's no longer * bound in any context. */ - _mesa_dereference_framebuffer(&fb); + _mesa_unreference_framebuffer(&fb); } } } diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index dabc96d91d9..c97d2f0077b 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -78,7 +78,7 @@ set_depth_renderbuffer(struct gl_framebuffer *fb, struct gl_renderbuffer *rb) { if (fb->_DepthBuffer) { - _mesa_dereference_renderbuffer(&fb->_DepthBuffer); + _mesa_unreference_renderbuffer(&fb->_DepthBuffer); } fb->_DepthBuffer = rb; if (rb) { @@ -96,7 +96,7 @@ set_stencil_renderbuffer(struct gl_framebuffer *fb, struct gl_renderbuffer *rb) { if (fb->_StencilBuffer) { - _mesa_dereference_renderbuffer(&fb->_StencilBuffer); + _mesa_unreference_renderbuffer(&fb->_StencilBuffer); } fb->_StencilBuffer = rb; if (rb) { @@ -223,7 +223,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; if (att->Renderbuffer) { - _mesa_dereference_renderbuffer(&att->Renderbuffer); + _mesa_unreference_renderbuffer(&att->Renderbuffer); } if (att->Texture) { /* render to texture */ @@ -236,7 +236,6 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) } } att->Type = GL_NONE; - att->Renderbuffer = NULL; att->Texture = NULL; } @@ -247,25 +246,44 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) /** - * Decrement the reference count on a framebuffer and delete it when + * Set *ptr to point to fb, with refcounting and locking. + */ +void +_mesa_reference_framebuffer(struct gl_framebuffer **ptr, + struct gl_framebuffer *fb) +{ + assert(ptr); + assert(!*ptr); + assert(fb); + _glthread_LOCK_MUTEX(fb->Mutex); + fb->RefCount++; + _glthread_UNLOCK_MUTEX(fb->Mutex); + *ptr = fb; +} + + +/** + * Undo/remove a reference to a framebuffer object. + * Decrement the framebuffer object's reference count and delete it when * the refcount hits zero. - * Note: we pass the address of a pointer and set it to NULL if we delete it. + * Note: we pass the address of a pointer and set it to NULL. */ void -_mesa_dereference_framebuffer(struct gl_framebuffer **fb) +_mesa_unreference_framebuffer(struct gl_framebuffer **fb) { - GLboolean deleteFlag = GL_FALSE; + assert(fb); + if (*fb) { + GLboolean deleteFlag = GL_FALSE; - _glthread_LOCK_MUTEX((*fb)->Mutex); - { + _glthread_LOCK_MUTEX((*fb)->Mutex); ASSERT((*fb)->RefCount > 0); (*fb)->RefCount--; deleteFlag = ((*fb)->RefCount == 0); - } - _glthread_UNLOCK_MUTEX((*fb)->Mutex); + _glthread_UNLOCK_MUTEX((*fb)->Mutex); + + if (deleteFlag) + (*fb)->Delete(*fb); - if (deleteFlag) { - (*fb)->Delete(*fb); *fb = NULL; } } diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index 7f3254fe8ea..4d76f3a90f7 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -43,7 +43,11 @@ extern void _mesa_free_framebuffer_data(struct gl_framebuffer *buffer); extern void -_mesa_dereference_framebuffer(struct gl_framebuffer **fb); +_mesa_reference_framebuffer(struct gl_framebuffer **ptr, + struct gl_framebuffer *fb); + +extern void +_mesa_unreference_framebuffer(struct gl_framebuffer **fb); extern void _mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb, diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c index 313c8d43d62..60f4948becf 100644 --- a/src/mesa/main/rbadaptors.c +++ b/src/mesa/main/rbadaptors.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *rb) /* Decrement reference count on the buffer we're wrapping and delete * it if refcount hits zero. */ - _mesa_dereference_renderbuffer(&rb->Wrapped); + _mesa_unreference_renderbuffer(&rb->Wrapped); /* delete myself */ _mesa_delete_renderbuffer(rb); diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index 6b18d60baff..1cc95a7d3b4 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -2089,32 +2089,33 @@ _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName) if (!rb) return; - _mesa_dereference_renderbuffer(&rb); + _mesa_unreference_renderbuffer(&rb); fb->Attachment[bufferName].Renderbuffer = NULL; } /** - * Decrement the reference count on a renderbuffer and delete it when + * Decrement a renderbuffer object's reference count and delete it when * the refcount hits zero. - * Note: we pass the address of a pointer and set it to NULL if we delete it. + * Note: we pass the address of a pointer. */ void -_mesa_dereference_renderbuffer(struct gl_renderbuffer **rb) +_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb) { - GLboolean deleteFlag = GL_FALSE; + assert(rb); + if (*rb) { + GLboolean deleteFlag = GL_FALSE; - _glthread_LOCK_MUTEX((*rb)->Mutex); - { + _glthread_LOCK_MUTEX((*rb)->Mutex); ASSERT((*rb)->RefCount > 0); (*rb)->RefCount--; deleteFlag = ((*rb)->RefCount == 0); - } - _glthread_UNLOCK_MUTEX((*rb)->Mutex); + _glthread_UNLOCK_MUTEX((*rb)->Mutex); + + if (deleteFlag) + (*rb)->Delete(*rb); - if (deleteFlag) { - (*rb)->Delete(*rb); *rb = NULL; } } diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h index 74ca43c57ab..e1a0a559792 100644 --- a/src/mesa/main/renderbuffer.h +++ b/src/mesa/main/renderbuffer.h @@ -99,7 +99,7 @@ extern void _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName); extern void -_mesa_dereference_renderbuffer(struct gl_renderbuffer **rb); +_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb); extern struct gl_renderbuffer * _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name); -- cgit v1.2.3 From 1a6baf092b4c31d5fd30c934f1a17d69c9689f12 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Mar 2007 16:26:02 -0700 Subject: unreference old framebuffer, if needed, in _mesa_reference_framebuffer() --- src/mesa/main/framebuffer.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/mesa/main/framebuffer.c') diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index c97d2f0077b..3136a950e08 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -253,6 +253,13 @@ _mesa_reference_framebuffer(struct gl_framebuffer **ptr, struct gl_framebuffer *fb) { assert(ptr); + if (*ptr == fb) { + /* no change */ + return; + } + if (*ptr) { + _mesa_unreference_framebuffer(ptr); + } assert(!*ptr); assert(fb); _glthread_LOCK_MUTEX(fb->Mutex); -- cgit v1.2.3