From 5fdd149f7310387d1393f5ecfd99e9885205bcf01d8422f07f8648814a75e3a6 Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Fri, 27 Apr 2007 15:47:02 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/Mesa?expand=0&rev=11 --- Mesa-6.5.2-fix_radeon_cliprect.diff | 237 ++++++++ Mesa-6.5.2.tar.bz2 | 3 + Mesa.changes | 5 + Mesa.spec | 45 +- MesaDemos-6.5.3rc4.tar.gz | 3 - MesaLib-6.5.3rc4.tar.gz | 3 - bug-211314-patch-1.diff | 99 ++++ bug-211314-patch-10.diff | 19 + bug-211314-patch-11.diff | 218 +++++++ bug-211314-patch-2.diff | 594 ++++++++++++++++++++ bug-211314-patch-3.diff | 29 + bug-211314-patch-4.diff | 24 + bug-211314-patch-5.diff | 26 + bug-211314-patch-6.diff | 30 + bug-211314-patch-7.diff | 23 + bug-211314-patch-8.diff | 21 + bug-211314-patch-9.diff | 20 + bug-211314_mesa-destroy_buffers.diff | 317 +++++++++++ bug-211314_mesa-framebuffer-counting.diff | 147 +++++ bug-211314_mesa-refcount-memleak-fixes.diff | 316 +++++++++++ disable-sis_dri.diff | 2 +- 21 files changed, 2167 insertions(+), 14 deletions(-) create mode 100644 Mesa-6.5.2-fix_radeon_cliprect.diff create mode 100644 Mesa-6.5.2.tar.bz2 delete mode 100644 MesaDemos-6.5.3rc4.tar.gz delete mode 100644 MesaLib-6.5.3rc4.tar.gz create mode 100644 bug-211314-patch-1.diff create mode 100644 bug-211314-patch-10.diff create mode 100644 bug-211314-patch-11.diff create mode 100644 bug-211314-patch-2.diff create mode 100644 bug-211314-patch-3.diff create mode 100644 bug-211314-patch-4.diff create mode 100644 bug-211314-patch-5.diff create mode 100644 bug-211314-patch-6.diff create mode 100644 bug-211314-patch-7.diff create mode 100644 bug-211314-patch-8.diff create mode 100644 bug-211314-patch-9.diff create mode 100644 bug-211314_mesa-destroy_buffers.diff create mode 100644 bug-211314_mesa-framebuffer-counting.diff create mode 100644 bug-211314_mesa-refcount-memleak-fixes.diff diff --git a/Mesa-6.5.2-fix_radeon_cliprect.diff b/Mesa-6.5.2-fix_radeon_cliprect.diff new file mode 100644 index 0000000..760b093 --- /dev/null +++ b/Mesa-6.5.2-fix_radeon_cliprect.diff @@ -0,0 +1,237 @@ +unchanged: +--- a/src/mesa/drivers/dri/radeon/radeon_context.c ++++ b/src/mesa/drivers/dri/radeon/radeon_context.c +@@ -594,12 +594,14 @@ radeonMakeCurrent( __DRIcontextPrivate * + driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, + &newCtx->vbl_seq ); + } +- +- if ( (newCtx->dri.drawable != driDrawPriv) +- || (newCtx->dri.readable != driReadPriv) ) { ++ ++ newCtx->dri.readable = driReadPriv; ++ ++ if ( (newCtx->dri.drawable != driDrawPriv) || ++ newCtx->lastStamp != driDrawPriv->lastStamp ) { + newCtx->dri.drawable = driDrawPriv; +- newCtx->dri.readable = driReadPriv; + ++ radeonSetCliprects(newCtx); + radeonUpdateWindow( newCtx->glCtx ); + radeonUpdateViewportOffset( newCtx->glCtx ); + } +unchanged: +--- a/src/mesa/drivers/dri/radeon/radeon_lock.c ++++ b/src/mesa/drivers/dri/radeon/radeon_lock.c +@@ -96,7 +96,6 @@ void radeonGetLock( radeonContextPtr rme + radeonSetCliprects( rmesa ); + radeonUpdateViewportOffset( rmesa->glCtx ); + driUpdateFramebufferSize(rmesa->glCtx, drawable); +- rmesa->lastStamp = drawable->lastStamp; + } + + RADEON_STATECHANGE( rmesa, ctx ); +unchanged: +--- a/src/mesa/drivers/dri/radeon/radeon_state.c ++++ b/src/mesa/drivers/dri/radeon/radeon_state.c +@@ -1675,6 +1675,8 @@ void radeonSetCliprects( radeonContextPt + + if (rmesa->state.scissor.enabled) + radeonRecalcScissorRects( rmesa ); ++ ++ rmesa->lastStamp = drawable->lastStamp; + } + + +unchanged: +--- b/src/mesa/drivers/dri/r200/r200_context.c ++++ b/src/mesa/drivers/dri/r200/r200_context.c +@@ -673,11 +673,13 @@ + &newCtx->vbl_seq ); + } + ++ newCtx->dri.readable = driReadPriv; ++ + if ( newCtx->dri.drawable != driDrawPriv || +- newCtx->dri.readable != driReadPriv ) { ++ newCtx->lastStamp != driDrawPriv->lastStamp ) { + newCtx->dri.drawable = driDrawPriv; +- newCtx->dri.readable = driReadPriv; + ++ r200SetCliprects(newCtx); + r200UpdateWindow( newCtx->glCtx ); + r200UpdateViewportOffset( newCtx->glCtx ); + } +unchanged: +--- b/src/mesa/drivers/dri/r200/r200_lock.c ++++ b/src/mesa/drivers/dri/r200/r200_lock.c +@@ -92,13 +92,9 @@ + + if ( rmesa->lastStamp != drawable->lastStamp ) { + r200UpdatePageFlipping( rmesa ); +- if (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) +- r200SetCliprects( rmesa, GL_BACK_LEFT ); +- else +- r200SetCliprects( rmesa, GL_FRONT_LEFT ); ++ r200SetCliprects( rmesa ); + r200UpdateViewportOffset( rmesa->glCtx ); + driUpdateFramebufferSize(rmesa->glCtx, drawable); +- rmesa->lastStamp = drawable->lastStamp; + } + + R200_STATECHANGE( rmesa, ctx ); +unchanged: +--- b/src/mesa/drivers/dri/r200/r200_state.c ++++ b/src/mesa/drivers/dri/r200/r200_state.c +@@ -1691,6 +1691,11 @@ + #define SUBPIXEL_X 0.125 + #define SUBPIXEL_Y 0.125 + ++ ++/** ++ * Called when window size or position changes or viewport or depth range ++ * state is changed. We update the hardware viewport state here. ++ */ + void r200UpdateWindow( GLcontext *ctx ) + { + r200ContextPtr rmesa = R200_CONTEXT(ctx); +@@ -1843,19 +1848,18 @@ + } + + +-void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ) ++/* ++ * Set up the cliprects for either front or back-buffer drawing. ++ */ ++void r200SetCliprects( r200ContextPtr rmesa ) + { + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; + +- switch ( mode ) { +- case GL_FRONT_LEFT: +- rmesa->numClipRects = drawable->numClipRects; +- rmesa->pClipRects = drawable->pClipRects; +- break; +- case GL_BACK_LEFT: ++ if (draw_fb->_ColorDrawBufferMask[0] ++ == BUFFER_BIT_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. + */ + if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) { +@@ -1866,11 +1870,12 @@ + rmesa->numClipRects = drawable->numBackClipRects; + rmesa->pClipRects = drawable->pBackClipRects; + } +- break; +- default: +- fprintf(stderr, "bad mode in r200SetCliprects\n"); +- return; + } ++ else { ++ /* front buffer (or none, or multiple buffers) */ ++ rmesa->numClipRects = drawable->numClipRects; ++ rmesa->pClipRects = drawable->pClipRects; ++ } + + if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { + _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, +@@ -1889,6 +1894,8 @@ + + if (rmesa->state.scissor.enabled) + r200RecalcScissorRects( rmesa ); ++ ++ rmesa->lastStamp = drawable->lastStamp; + } + + +@@ -1908,19 +1915,17 @@ + */ + switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { + case BUFFER_BIT_FRONT_LEFT: +- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); +- r200SetCliprects( rmesa, GL_FRONT_LEFT ); +- break; + case BUFFER_BIT_BACK_LEFT: + FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); +- r200SetCliprects( rmesa, GL_BACK_LEFT ); + break; + default: +- /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ ++ /* 0 (GL_NONE) buffers or multiple color drawing buffers */ + FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + ++ r200SetCliprects( rmesa ); ++ + /* We'll set the drawing engine's offset/pitch parameters later + * when we update other state. + */ +unchanged: +--- a/src/mesa/drivers/dri/r200/r200_state.h ++++ b/src/mesa/drivers/dri/r200/r200_state.h +@@ -44,7 +44,7 @@ extern void r200InitTnlFuncs( GLcontext + + extern void r200UpdateMaterial( GLcontext *ctx ); + +-extern void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ); ++extern void r200SetCliprects( r200ContextPtr rmesa ); + extern void r200RecalcScissorRects( r200ContextPtr rmesa ); + extern void r200UpdateViewportOffset( GLcontext *ctx ); + extern void r200UpdateWindow( GLcontext *ctx ); +only in patch2: +unchanged: +--- b/src/mesa/drivers/dri/r300/radeon_context.c ++++ b/src/mesa/drivers/dri/r300/radeon_context.c +@@ -51,6 +51,7 @@ + #include "radeon_macros.h" + #include "radeon_reg.h" + ++#include "radeon_state.h" + #include "r300_state.h" + + #include "utils.h" +@@ -272,11 +273,13 @@ + &radeon->vbl_seq); + } + ++ radeon->dri.readable = driReadPriv; ++ + if (radeon->dri.drawable != driDrawPriv || +- radeon->dri.readable != driReadPriv) { ++ radeon->lastStamp != driDrawPriv->lastStamp) { + radeon->dri.drawable = driDrawPriv; +- radeon->dri.readable = driReadPriv; + ++ radeonSetCliprects(radeon); + r300UpdateWindow(radeon->glCtx); + r300UpdateViewportOffset(radeon->glCtx); + } +only in patch2: +unchanged: +--- a/src/mesa/drivers/dri/r300/radeon_lock.c ++++ b/src/mesa/drivers/dri/r300/radeon_lock.c +@@ -90,7 +90,6 @@ static void r300RegainedLock(radeonConte + #else + radeonUpdateScissor(radeon->glCtx); + #endif +- radeon->lastStamp = drawable->lastStamp; + } + + if (sarea->ctx_owner != radeon->dri.hwContext) { +only in patch2: +unchanged: +--- a/src/mesa/drivers/dri/r300/radeon_state.c ++++ b/src/mesa/drivers/dri/r300/radeon_state.c +@@ -185,6 +185,8 @@ void radeonSetCliprects(radeonContextPtr + + if (radeon->state.scissor.enabled) + radeonRecalcScissorRects(radeon); ++ ++ radeon->lastStamp = drawable->lastStamp; + } + + diff --git a/Mesa-6.5.2.tar.bz2 b/Mesa-6.5.2.tar.bz2 new file mode 100644 index 0000000..2122008 --- /dev/null +++ b/Mesa-6.5.2.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bd2f940b3461574076fa1b6161430b8ed1d9d451d183411f40edfc6ce4034bd +size 5950038 diff --git a/Mesa.changes b/Mesa.changes index 8d448b0..8cc9390 100644 --- a/Mesa.changes +++ b/Mesa.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Fri Apr 27 16:57:47 CEST 2007 - sndirsch@suse.de + +- back to Mesa 6.5.2 (Bug #269155/269042) + ------------------------------------------------------------------- Wed Apr 25 19:31:11 CEST 2007 - sndirsch@suse.de diff --git a/Mesa.spec b/Mesa.spec index 675a634..960290c 100644 --- a/Mesa.spec +++ b/Mesa.spec @@ -1,5 +1,5 @@ # -# spec file for package Mesa (Version 6.5.3) +# spec file for package Mesa (Version 6.5.2) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -18,11 +18,10 @@ Group: System/Libraries Provides: xorg-x11-Mesa Obsoletes: xorg-x11-Mesa Autoreqprov: on -Version: 6.5.3 -Release: 4 +Version: 6.5.2 +Release: 28 Summary: Mesa is a 3-D graphics library with an API which is very similar to that of OpenGL.* -Source: MesaLib-%{version}rc4.tar.gz -Source1: MesaDemos-%{version}rc4.tar.gz +Source: Mesa-%{version}.tar.bz2 Source3: README.updates Source4: manual-pages.tar.bz2 Source5: via.csh @@ -32,6 +31,21 @@ Patch1: dri_driver_dir.diff Patch2: i915-crossbar.diff Patch4: libIndirectGL.diff Patch5: static.diff +Patch6: bug-211314_mesa-destroy_buffers.diff +Patch7: bug-211314_mesa-framebuffer-counting.diff +Patch8: bug-211314-patch-1.diff +Patch9: bug-211314-patch-2.diff +Patch10: bug-211314-patch-3.diff +Patch11: bug-211314-patch-4.diff +Patch12: bug-211314-patch-5.diff +Patch13: bug-211314-patch-6.diff +Patch14: bug-211314-patch-7.diff +Patch15: bug-211314-patch-8.diff +Patch16: bug-211314-patch-9.diff +Patch17: bug-211314-patch-10.diff +Patch18: bug-211314-patch-11.diff +Patch19: bug-211314_mesa-refcount-memleak-fixes.diff +Patch20: Mesa-6.5.2-fix_radeon_cliprect.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -101,12 +115,12 @@ Authors: Brian Paul %prep -%setup -n %{name}-%{version}rc4 -b1 -b4 +%setup -n %name -b4 # make legal department happy (Bug #204110) test -f src/mesa/drivers/directfb/idirectfbgl_mesa.c && exit 1 test -f progs/ggi/asc-view.c && exit 1 # no need to build GLUT and (GLUT-)Demos -rm -rf src/glut progs/{demos,redbook,samples,xdemos,glsl} +rm -rf src/glut progs/{demos,redbook,samples,xdemos} # we use freeglut rm -f include/GL/{glut.h,uglglutshapes.h,glutf90.h} # extra package for GLw (MesaGLw) @@ -115,6 +129,21 @@ rm -rf src/glw/ %patch1 %patch2 %patch5 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 %build @@ -233,6 +262,8 @@ rm -rf $RPM_BUILD_ROOT /usr/%{_lib}/libMesaGL.a %changelog +* Fri Apr 27 2007 - sndirsch@suse.de +- back to Mesa 6.5.2 (Bug #269155/269042) * Wed Apr 25 2007 - sndirsch@suse.de - 4th RC ready * This fixes some breakage in RC3. diff --git a/MesaDemos-6.5.3rc4.tar.gz b/MesaDemos-6.5.3rc4.tar.gz deleted file mode 100644 index 14ff5ef..0000000 --- a/MesaDemos-6.5.3rc4.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e03b0c6517e408ef1f5942625e05f4e67b150a6614610023e8e456ae84936716 -size 1673468 diff --git a/MesaLib-6.5.3rc4.tar.gz b/MesaLib-6.5.3rc4.tar.gz deleted file mode 100644 index f8180bb..0000000 --- a/MesaLib-6.5.3rc4.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12901ffe8018f87dfb7ac06a0b7b2cf4e5b9b9ff36dc2a91b3ee81470dcf2168 -size 4526210 diff --git a/bug-211314-patch-1.diff b/bug-211314-patch-1.diff new file mode 100644 index 0000000..8afc064 --- /dev/null +++ b/bug-211314-patch-1.diff @@ -0,0 +1,99 @@ +commit f30e8a4bdf8338dc3f8e985a9c91af61a3301990 +Author: Brian +Date: Mon Feb 26 11:37:52 2007 -0700 + + if renderbuffer ptr is null, just return + +diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c +index 27f4736..15dc810 100644 +--- a/src/mesa/swrast/s_readpix.c ++++ b/src/mesa/swrast/s_readpix.c +@@ -1,8 +1,8 @@ + /* + * Mesa 3-D graphics library +- * Version: 6.5.2 ++ * 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"), +@@ -54,7 +54,8 @@ read_index_pixels( GLcontext *ctx, + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + GLint i; + +- ASSERT(rb); ++ if (!rb) ++ return; + + /* width should never be > MAX_WIDTH since we did clipping earlier */ + ASSERT(width <= MAX_WIDTH); +@@ -91,6 +92,9 @@ read_depth_pixels( GLcontext *ctx, + const GLboolean biasOrScale + = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; + ++ if (!rb) ++ return; ++ + /* clipping should have been done already */ + ASSERT(x >= 0); + ASSERT(y >= 0); +@@ -99,8 +103,6 @@ read_depth_pixels( GLcontext *ctx, + /* width should never be > MAX_WIDTH since we did clipping earlier */ + ASSERT(width <= MAX_WIDTH); + +- ASSERT(rb); +- + if (type == GL_UNSIGNED_SHORT && fb->Visual.depthBits == 16 + && !biasOrScale && !packing->SwapBytes) { + /* Special case: directly read 16-bit unsigned depth values. */ +@@ -171,7 +173,8 @@ read_stencil_pixels( GLcontext *ctx, + struct gl_renderbuffer *rb = fb->_StencilBuffer; + GLint j; + +- ASSERT(rb); ++ if (!rb) ++ return; + + /* width should never be > MAX_WIDTH since we did clipping earlier */ + ASSERT(width <= MAX_WIDTH); +@@ -195,6 +198,7 @@ read_stencil_pixels( GLcontext *ctx, + /** + * Optimized glReadPixels for particular pixel formats when pixel + * scaling, biasing, mapping, etc. are disabled. ++ * \return GL_TRUE if success, GL_FALSE if unable to do the readpixels + */ + static GLboolean + fast_read_rgba_pixels( GLcontext *ctx, +@@ -207,6 +211,9 @@ fast_read_rgba_pixels( GLcontext *ctx, + { + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + ++ if (!rb) ++ return GL_FALSE; ++ + ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); + + /* clipping should have already been done */ +@@ -316,7 +323,8 @@ read_rgba_pixels( GLcontext *ctx, + struct gl_framebuffer *fb = ctx->ReadBuffer; + struct gl_renderbuffer *rb = fb->_ColorReadBuffer; + +- ASSERT(rb); ++ if (!rb) ++ return; + + if (type == GL_FLOAT && ((ctx->Color.ClampReadColor == GL_TRUE) || + (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB && +@@ -457,8 +465,8 @@ read_depth_stencil_pixels(GLcontext *ctx + depthRb = ctx->ReadBuffer->_DepthBuffer; + stencilRb = ctx->ReadBuffer->_StencilBuffer; + +- ASSERT(depthRb); +- ASSERT(stencilRb); ++ if (!depthRb || !stencilRb) ++ return; + + depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; diff --git a/bug-211314-patch-10.diff b/bug-211314-patch-10.diff new file mode 100644 index 0000000..ce4b923 --- /dev/null +++ b/bug-211314-patch-10.diff @@ -0,0 +1,19 @@ +commit f04979ae481acc9fdc423da06514c4d557edd7cd +Author: Mathias Hopf +Date: Fri Mar 16 08:28:34 2007 -0600 + + added null xmctx check to XMesaResizeBuffers(), bug 7205 + +diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c +index cbbbd56..ba020fc 100644 +--- a/src/mesa/drivers/x11/xm_api.c ++++ b/src/mesa/drivers/x11/xm_api.c +@@ -2499,6 +2499,8 @@ XMesaResizeBuffers( XMesaBuffer b ) + { + GET_CURRENT_CONTEXT(ctx); + XMesaContext xmctx = XMESA_CONTEXT(ctx); ++ if (!xmctx) ++ return; + xmesa_check_and_update_buffer_size(xmctx, b); + } + diff --git a/bug-211314-patch-11.diff b/bug-211314-patch-11.diff new file mode 100644 index 0000000..d9e31d2 --- /dev/null +++ b/bug-211314-patch-11.diff @@ -0,0 +1,218 @@ +commit e5070bc3ca75dee31034cc543f3d2ee04e5dc032 +Author: Brian +Date: Fri Mar 16 11:00:07 2007 -0600 + + Assorted fixes for dealing with zero-size frame/renderbuffers. + + In xmesa_check_and_update_buffer_size() handle xmctx==NULL correctly: still + call _mesa_resize_framebufer(). If we don't we can wind up in a situation + where the framebuffer size is non-zero but an attached renderbuffer size + is still initialized to zero. This inconsistancy can later cause problems. + Check for zero-size renderbuffers in update_color_draw_buffers() and + update_color_read_buffer(). + See bug 7205. + +diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c +index ba020fc..b513dc8 100644 +--- a/src/mesa/drivers/x11/xm_api.c ++++ b/src/mesa/drivers/x11/xm_api.c +@@ -1842,16 +1842,18 @@ XMesaDestroyBuffer(XMesaBuffer b) + * 1. the first time a buffer is bound to a context. + * 2. from glViewport to poll for window size changes + * 3. from the XMesaResizeBuffers() API function. ++ * Note: it's possible (and legal) for xmctx to be NULL. That can happen ++ * when resizing a buffer when no rendering context is bound. + */ + void + xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) + { + GLuint width, height; +- xmesa_get_window_size(xmctx->display, drawBuffer, &width, &height); ++ xmesa_get_window_size(drawBuffer->display, drawBuffer, &width, &height); + if (drawBuffer->mesa_buffer.Width != width || + drawBuffer->mesa_buffer.Height != height) { +- _mesa_resize_framebuffer(&(xmctx->mesa), +- &(drawBuffer->mesa_buffer), width, height); ++ GLcontext *ctx = xmctx ? &xmctx->mesa : NULL; ++ _mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height); + } + drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */ + } +@@ -2175,7 +2177,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) + } + #endif + if (b->backxrb->ximage) { +- /* Copy Ximage from host's memory to server's window */ ++ /* Copy Ximage (back buf) from client memory to server window */ + #if defined(USE_XSHM) && !defined(XFree86Server) + if (b->shm) { + /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ +@@ -2197,8 +2199,8 @@ void XMesaSwapBuffers( XMesaBuffer b ) + /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ + } + } +- else { +- /* Copy pixmap to window on server */ ++ else if (b->backxrb->pixmap) { ++ /* Copy pixmap (back buf) to window (front buf) on server */ + /*_glthread_LOCK_MUTEX(_xmesa_lock);*/ + XMesaCopyArea( b->xm_visual->display, + b->backxrb->pixmap, /* source drawable */ +diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c +index 73c46b1..c1fa233 100644 +--- a/src/mesa/drivers/x11/xm_buffer.c ++++ b/src/mesa/drivers/x11/xm_buffer.c +@@ -168,9 +168,6 @@ alloc_back_shm_ximage(XMesaBuffer b, GLu + static void + alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height) + { +- if (width == 0 || height == 0) +- return; +- + if (b->db_mode == BACK_XIMAGE) { + /* Deallocate the old backxrb->ximage, if any */ + if (b->backxrb->ximage) { +@@ -186,6 +183,9 @@ alloc_back_buffer(XMesaBuffer b, GLuint + b->backxrb->ximage = NULL; + } + ++ if (width == 0 || height == 0) ++ return; ++ + /* Allocate new back buffer */ + #ifdef XFree86Server + /* Allocate a regular XImage for the back buffer. */ +@@ -218,20 +218,20 @@ alloc_back_buffer(XMesaBuffer b, GLuint + b->backxrb->pixmap = None; + } + else if (b->db_mode == BACK_PIXMAP) { +- if (!width) +- width = 1; +- if (!height) +- height = 1; +- + /* Free the old back pixmap */ + if (b->backxrb->pixmap) { +- XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap); ++ XMesaFreePixmap(b->xm_visual->display, b->backxrb->pixmap); ++ b->backxrb->pixmap = 0; + } +- /* Allocate new back pixmap */ +- b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display, +- b->frontxrb->drawable, +- width, height, +- GET_VISUAL_DEPTH(b->xm_visual)); ++ ++ if (width > 0 && height > 0) { ++ /* Allocate new back pixmap */ ++ b->backxrb->pixmap = XMesaCreatePixmap(b->xm_visual->display, ++ b->frontxrb->drawable, ++ width, height, ++ GET_VISUAL_DEPTH(b->xm_visual)); ++ } ++ + b->backxrb->ximage = NULL; + } + } +@@ -250,6 +250,7 @@ xmesa_delete_renderbuffer(struct gl_rend + + /** + * Reallocate renderbuffer storage for front color buffer. ++ * Called via gl_renderbuffer::AllocStorage() + */ + static GLboolean + xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, +@@ -260,6 +261,7 @@ xmesa_alloc_front_storage(GLcontext *ctx + /* just clear these to be sure we don't accidentally use them */ + xrb->origin1 = NULL; + xrb->origin2 = NULL; ++ xrb->origin3 = NULL; + xrb->origin4 = NULL; + + /* for the FLIP macro: */ +@@ -275,6 +277,7 @@ xmesa_alloc_front_storage(GLcontext *ctx + + /** + * Reallocate renderbuffer storage for back color buffer. ++ * Called via gl_renderbuffer::AllocStorage() + */ + static GLboolean + xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, +@@ -309,8 +312,12 @@ xmesa_alloc_back_storage(GLcontext *ctx, + xrb->origin4 = (GLuint *) xrb->ximage->data + xrb->width4 * (height - 1); + } + else { +- /* this assertion will fail if we happend to run out of memory */ +- /*assert(xrb->pixmap);*/ ++ /* out of memory or buffer size is 0 x 0 */ ++ xrb->width1 = xrb->width2 = xrb->width3 = xrb->width4 = 0; ++ xrb->origin1 = NULL; ++ xrb->origin2 = NULL; ++ xrb->origin3 = NULL; ++ xrb->origin4 = NULL; + } + + return GL_TRUE; +diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c +index 3136a95..cd4f594 100644 +--- a/src/mesa/main/framebuffer.c ++++ b/src/mesa/main/framebuffer.c +@@ -647,7 +647,7 @@ update_color_draw_buffers(GLcontext *ctx + const GLuint bufferBit = 1 << i; + if (bufferBit & bufferMask) { + struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; +- if (rb) { ++ if (rb && rb->Width > 0 && rb->Height > 0) { + fb->_ColorDrawBuffers[output][count] = rb; + count++; + } +@@ -673,7 +673,10 @@ static void + update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb) + { + (void) ctx; +- if (fb->_ColorReadBufferIndex == -1 || fb->DeletePending) { ++ if (fb->_ColorReadBufferIndex == -1 || ++ fb->DeletePending || ++ fb->Width == 0 || ++ fb->Height == 0) { + fb->_ColorReadBuffer = NULL; /* legal! */ + } + else { +diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c +index 1cc95a7..e387c42 100644 +--- a/src/mesa/main/renderbuffer.c ++++ b/src/mesa/main/renderbuffer.c +@@ -1192,18 +1192,22 @@ _mesa_soft_renderbuffer_storage(GLcontex + ASSERT(rb->PutMonoValues); + + /* free old buffer storage */ +- if (rb->Data) ++ if (rb->Data) { + _mesa_free(rb->Data); +- +- /* allocate new buffer storage */ +- rb->Data = _mesa_malloc(width * height * pixelSize); +- if (rb->Data == NULL) { +- rb->Width = 0; +- rb->Height = 0; +- _mesa_error(ctx, GL_OUT_OF_MEMORY, +- "software renderbuffer allocation (%d x %d x %d)", +- width, height, pixelSize); +- return GL_FALSE; ++ rb->Data = NULL; ++ } ++ ++ if (width > 0 && height > 0) { ++ /* allocate new buffer storage */ ++ rb->Data = _mesa_malloc(width * height * pixelSize); ++ if (rb->Data == NULL) { ++ rb->Width = 0; ++ rb->Height = 0; ++ _mesa_error(ctx, GL_OUT_OF_MEMORY, ++ "software renderbuffer allocation (%d x %d x %d)", ++ width, height, pixelSize); ++ return GL_FALSE; ++ } + } + + rb->Width = width; diff --git a/bug-211314-patch-2.diff b/bug-211314-patch-2.diff new file mode 100644 index 0000000..e7aa278 --- /dev/null +++ b/bug-211314-patch-2.diff @@ -0,0 +1,594 @@ +commit a510bc3ee1a696da120c09ee4ec33dc033f671ac +Author: Brian +Date: Tue Mar 6 10:07:59 2007 -0700 + + 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. + +diff --git a/src/mesa/drivers/allegro/amesa.c b/src/mesa/drivers/allegro/amesa.c +index 594668a..518211c 100644 +--- a/src/mesa/drivers/allegro/amesa.c ++++ b/src/mesa/drivers/allegro/amesa.c +@@ -338,7 +338,7 @@ void AMesaDestroyBuffer(AMesaBuffer buff + { + 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 08b52b4..a6d7590 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 *driS + 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 215aaf8..4c5323d 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 *driS + 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 e8922b1..f41682c 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 *d + 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/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c +index 1014b8a..4e9e216 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 * + 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 f024f73..67a6f8b 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 *dri + 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/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c +index 4f1b20a..880dee8 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 *dr + 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 fc5aa11..abb14fa 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 * + 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 c451f74..c66fd6d 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 *dri + 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 ad79b92..f859217 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 * + 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 8f52cfe..89d734b 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 *dri + 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 646f512..1f9ff4e 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 *dr + 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 dbbd1ac..8dc7f0d 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 + 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 28e1f94..90f76be 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 *driS + 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 e535e73..00b9d29 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 fxMes + 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 c4fc882..96b9b5c 100644 +--- a/src/mesa/drivers/osmesa/osmesa.c ++++ b/src/mesa/drivers/osmesa/osmesa.c +@@ -1303,7 +1303,8 @@ OSMesaDestroyContext( OSMesaContext osme + _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 0dd9a14..d138587 100644 +--- a/src/mesa/drivers/svga/svgamesa.c ++++ b/src/mesa/drivers/svga/svgamesa.c +@@ -433,7 +433,6 @@ void SVGAMesaDestroyContext( SVGAMesaCon + 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 2cd7d8a..a42de72 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 1245c10..135c814 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, G + 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, G + + 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 a99ff9d..6608eef 100644 +--- a/src/mesa/main/fbobject.c ++++ b/src/mesa/main/fbobject.c +@@ -602,7 +602,7 @@ _mesa_BindRenderbufferEXT(GLenum target, + + oldRb = ctx->CurrentRenderbuffer; + if (oldRb) { +- _mesa_dereference_renderbuffer(&oldRb); ++ _mesa_unreference_renderbuffer(&oldRb); + } + + ASSERT(newRb != &DummyRenderbuffer); +@@ -639,7 +639,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, + /* 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, + } + _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, + */ + + if (bindReadBuf) { +- 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) { +- 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, c + /* 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 dabc96d..c97d2f0 100644 +--- a/src/mesa/main/framebuffer.c ++++ b/src/mesa/main/framebuffer.c +@@ -78,7 +78,7 @@ set_depth_renderbuffer(struct gl_framebu + 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_frame + struct gl_renderbuffer *rb) + { + if (fb->_StencilBuffer) { +- _mesa_dereference_renderbuffer(&fb->_StencilBuffer); ++ _mesa_unreference_renderbuffer(&fb->_StencilBuffer); + } + fb->_StencilBuffer = rb; + if (rb) { +@@ -223,13 +223,7 @@ _mesa_free_framebuffer_data(struct gl_fr + 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_unreference_renderbuffer(&att->Renderbuffer); + } + if (att->Texture) { + /* render to texture */ +@@ -236,6 +236,5 @@ _mesa_free_framebuffer_data(struct gl_fr + } + } + att->Type = GL_NONE; +- att->Renderbuffer = NULL; + } + +@@ -247,25 +246,44 @@ _mesa_free_framebuffer_data(struct gl_fr + + + /** +- * 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 7f3254f..4d76f3a 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 313c8d4..60f4948 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 *r + /* 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 6b18d60..1cc95a7 100644 +--- a/src/mesa/main/renderbuffer.c ++++ b/src/mesa/main/renderbuffer.c +@@ -2089,32 +2089,33 @@ _mesa_remove_renderbuffer(struct gl_fram + 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 74ca43c..e1a0a55 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); diff --git a/bug-211314-patch-3.diff b/bug-211314-patch-3.diff new file mode 100644 index 0000000..2d94bef --- /dev/null +++ b/bug-211314-patch-3.diff @@ -0,0 +1,29 @@ +commit 955906aa647d0d233b422c979e1ee81dc32abb87 +Author: Brian +Date: Tue Mar 6 16:25:07 2007 -0700 + + fix renderbuffer mem leak + +diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c +index a358ec2..747971a 100644 +--- a/src/mesa/drivers/x11/xm_buffer.c ++++ b/src/mesa/drivers/x11/xm_buffer.c +@@ -418,6 +418,18 @@ xmesa_delete_framebuffer(struct gl_frame + XMesaDestroyImage( b->rowimage ); + } + ++ /* Note that XMesaBuffer renderbuffers normally have a refcount of 2 ++ * (creation + binding) so we need to explicitly delete/unbind them here. ++ */ ++ if (b->frontxrb) { ++ _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb); ++ ASSERT(b->frontxrb == NULL); ++ } ++ if (b->backxrb) { ++ _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb); ++ ASSERT(b->backxrb == NULL); ++ } ++ + _mesa_free_framebuffer_data(fb); + _mesa_free(fb); + } diff --git a/bug-211314-patch-4.diff b/bug-211314-patch-4.diff new file mode 100644 index 0000000..3409320 --- /dev/null +++ b/bug-211314-patch-4.diff @@ -0,0 +1,24 @@ +commit 1a6baf092b4c31d5fd30c934f1a17d69c9689f12 +Author: Brian +Date: Tue Mar 6 16:26:02 2007 -0700 + + unreference old framebuffer, if needed, in _mesa_reference_framebuffer() + +diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c +index c97d2f0..3136a95 100644 +--- a/src/mesa/main/framebuffer.c ++++ b/src/mesa/main/framebuffer.c +@@ -253,6 +253,13 @@ _mesa_reference_framebuffer(struct gl_fr + 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); diff --git a/bug-211314-patch-5.diff b/bug-211314-patch-5.diff new file mode 100644 index 0000000..6a38ae4 --- /dev/null +++ b/bug-211314-patch-5.diff @@ -0,0 +1,26 @@ +commit e69da9d02ecdf47d930276783f8b8df1a3cd99dd +Author: Brian +Date: Tue Mar 6 16:26:22 2007 -0700 + + explicit calls to _mesa_unreference_framebuffer() not always needed now + +diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c +index 6608eef..f7e870b 100644 +--- a/src/mesa/main/fbobject.c ++++ b/src/mesa/main/fbobject.c +@@ -1014,7 +1014,6 @@ _mesa_BindFramebufferEXT(GLenum target, + */ + + if (bindReadBuf) { +- _mesa_unreference_framebuffer(&ctx->ReadBuffer); + _mesa_reference_framebuffer(&ctx->ReadBuffer, newFb); + } + +@@ -1022,7 +1021,6 @@ _mesa_BindFramebufferEXT(GLenum target, + /* 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 */ diff --git a/bug-211314-patch-6.diff b/bug-211314-patch-6.diff new file mode 100644 index 0000000..bcbbd9a --- /dev/null +++ b/bug-211314-patch-6.diff @@ -0,0 +1,30 @@ +commit 47e0b606a85059ff29fe311dc2f1bcafdefe4cdb +Author: Brian +Date: Wed Mar 14 12:42:30 2007 -0600 + + move CLIENT_ID code in xmesa_delete_framebuffer(), see bug 7205 + +diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c +index 747971a..73c46b1 100644 +--- a/src/mesa/drivers/x11/xm_buffer.c ++++ b/src/mesa/drivers/x11/xm_buffer.c +@@ -362,16 +362,13 @@ xmesa_delete_framebuffer(struct gl_frame + { + XMesaBuffer b = XMESA_BUFFER(fb); + +-#ifdef XFree86Server +- int client = 0; +- if (b->frontxrb->drawable) +- client = CLIENT_ID(b->frontxrb->drawable->id); +-#endif +- + if (b->num_alloced > 0) { + /* If no other buffer uses this X colormap then free the colors. */ + if (!xmesa_find_buffer(b->display, b->cmap, b)) { + #ifdef XFree86Server ++ int client = 0; ++ if (b->frontxrb->drawable) ++ client = CLIENT_ID(b->frontxrb->drawable->id); + (void)FreeColors(b->cmap, client, + b->num_alloced, b->alloced_colors, 0); + #else diff --git a/bug-211314-patch-7.diff b/bug-211314-patch-7.diff new file mode 100644 index 0000000..b83696e --- /dev/null +++ b/bug-211314-patch-7.diff @@ -0,0 +1,23 @@ +commit 3049946fa742b654afa9b24f8bc79f387f01aea9 +Author: Brian +Date: Wed Mar 14 12:52:53 2007 -0600 + + clear the b->frontxrb->drawable field in xmesa_free_buffer(), see bug 7205 + +diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c +index 776928d..cbbbd56 100644 +--- a/src/mesa/drivers/x11/xm_api.c ++++ b/src/mesa/drivers/x11/xm_api.c +@@ -483,6 +483,12 @@ xmesa_free_buffer(XMesaBuffer buffer) + + /* mark as delete pending */ + fb->DeletePending = GL_TRUE; ++ ++ /* Since the X window for the XMesaBuffer is going away, we don't ++ * want to dereference this pointer in the future. ++ */ ++ b->frontxrb->drawable = 0; ++ + /* Unreference. If count = zero we'll really delete the buffer */ + _mesa_unreference_framebuffer(&fb); + diff --git a/bug-211314-patch-8.diff b/bug-211314-patch-8.diff new file mode 100644 index 0000000..51c761e --- /dev/null +++ b/bug-211314-patch-8.diff @@ -0,0 +1,21 @@ +commit 038e981cacdc6f32588442666cde8a8fc16cfdfc +Author: Brian +Date: Thu Mar 15 11:11:41 2007 -0600 + + add some rb->Data null ptr checks (bug 7205) + +diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c +index 69e9404..f53e7f5 100644 +--- a/src/mesa/swrast/s_accum.c ++++ b/src/mesa/swrast/s_accum.c +@@ -136,7 +136,9 @@ _swrast_clear_accum_buffer( GLcontext *c + return; + } + +- assert(rb); ++ if (!rb || !rb->Data) ++ return; ++ + assert(rb->_BaseFormat == GL_RGBA); + /* add other types in future? */ + assert(rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT); diff --git a/bug-211314-patch-9.diff b/bug-211314-patch-9.diff new file mode 100644 index 0000000..28d4dc2 --- /dev/null +++ b/bug-211314-patch-9.diff @@ -0,0 +1,20 @@ +commit 4d2eb637a20e4fdf5d5f6c0ea4d4627894594661 +Author: Brian +Date: Thu Mar 15 11:16:41 2007 -0600 + + no-op clear if buffer width or height is zero (bug 7205) + +diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c +index 0e3ed15..11bd173 100644 +--- a/src/mesa/main/buffers.c ++++ b/src/mesa/main/buffers.c +@@ -140,6 +140,9 @@ _mesa_Clear( GLbitfield mask ) + return; + } + ++ if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0) ++ return; ++ + if (ctx->RenderMode == GL_RENDER) { + GLbitfield bufferMask; + diff --git a/bug-211314_mesa-destroy_buffers.diff b/bug-211314_mesa-destroy_buffers.diff new file mode 100644 index 0000000..e1c17b3 --- /dev/null +++ b/bug-211314_mesa-destroy_buffers.diff @@ -0,0 +1,317 @@ +commit 928a70e4354d4884e2918ec67ddc6d8baf942c8a +Author: Brian +Date: Mon Feb 26 11:39:17 2007 -0700 + + Rewrite code related to buffer destruction. + + Do proper reference counting so that we don't wind up with dangling + references to deleted windows/framebuffers. Should help with bug 7205. + +diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c +index b0ef422..2cd7d8a 100644 +--- a/src/mesa/drivers/x11/xm_api.c ++++ b/src/mesa/drivers/x11/xm_api.c +@@ -345,7 +345,7 @@ xmesa_get_window_size(XMesaDisplay *dpy, + /***** Linked list of XMesaBuffers *****/ + /**********************************************************************/ + +-static XMesaBuffer XMesaBufferList = NULL; ++XMesaBuffer XMesaBufferList = NULL; + + + /** +@@ -378,6 +378,7 @@ create_xmesa_buffer(XMesaDrawable d, Buf + b->cmap = cmap; + + _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); ++ b->mesa_buffer.Delete = xmesa_delete_framebuffer; + + /* + * Front renderbuffer +@@ -451,8 +452,8 @@ create_xmesa_buffer(XMesaDrawable d, Buf + * Find an XMesaBuffer by matching X display and colormap but NOT matching + * the notThis buffer. + */ +-static XMesaBuffer +-find_xmesa_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) ++XMesaBuffer ++xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) + { + XMesaBuffer b; + for (b=XMesaBufferList; b; b=b->Next) { +@@ -465,38 +466,27 @@ find_xmesa_buffer(XMesaDisplay *dpy, XMe + + + /** +- * Free an XMesaBuffer, remove from linked list, perhaps free X colormap +- * entries. ++ * Remove buffer from linked list, delete if no longer referenced. + */ + static void +-free_xmesa_buffer(int client, XMesaBuffer buffer) ++xmesa_free_buffer(XMesaBuffer buffer) + { + XMesaBuffer prev = NULL, b; +- (void) client; +- for (b=XMesaBufferList; b; b=b->Next) { +- if (b==buffer) { +- /* unlink bufer from list */ ++ ++ for (b = XMesaBufferList; b; b = b->Next) { ++ if (b == buffer) { ++ struct gl_framebuffer *fb = &buffer->mesa_buffer; ++ ++ /* unlink buffer from list */ + if (prev) + prev->Next = buffer->Next; + else + XMesaBufferList = buffer->Next; +- /* Check to free X colors */ +- if (buffer->num_alloced>0) { +- /* If no other buffer uses this X colormap then free the colors. */ +- if (!find_xmesa_buffer(buffer->display, buffer->cmap, buffer)) { +-#ifdef XFree86Server +- (void)FreeColors(buffer->cmap, client, +- buffer->num_alloced, buffer->alloced_colors, +- 0); +-#else +- XFreeColors(buffer->display, buffer->cmap, +- buffer->alloced_colors, buffer->num_alloced, 0); +-#endif +- } +- } + +- _mesa_free_framebuffer_data(&buffer->mesa_buffer); +- _mesa_free(buffer); ++ /* mark as delete pending */ ++ fb->DeletePending = GL_TRUE; ++ /* Dereference. If count = zero we'll really delete the buffer */ ++ _mesa_dereference_framebuffer(&fb); + + return; + } +@@ -504,7 +494,7 @@ free_xmesa_buffer(int client, XMesaBuffe + prev = b; + } + /* buffer not found in XMesaBufferList */ +- _mesa_problem(NULL,"free_xmesa_buffer() - buffer not found\n"); ++ _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n"); + } + + +@@ -686,7 +676,7 @@ setup_grayscale(int client, XMesaVisual + return GL_FALSE; + } + +- prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); ++ prevBuffer = xmesa_find_buffer(v->display, cmap, buffer); + if (prevBuffer && + (buffer->xm_visual->mesa_visual.rgbMode == + prevBuffer->xm_visual->mesa_visual.rgbMode)) { +@@ -775,7 +765,7 @@ setup_dithered_color(int client, XMesaVi + return GL_FALSE; + } + +- prevBuffer = find_xmesa_buffer(v->display, cmap, buffer); ++ prevBuffer = xmesa_find_buffer(v->display, cmap, buffer); + if (prevBuffer && + (buffer->xm_visual->mesa_visual.rgbMode == + prevBuffer->xm_visual->mesa_visual.rgbMode)) { +@@ -1666,7 +1656,7 @@ XMesaCreateWindowBuffer2(XMesaVisual v, + + if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) w, cmap )) { +- free_xmesa_buffer(client, b); ++ xmesa_free_buffer(b); + return NULL; + } + +@@ -1787,7 +1777,7 @@ XMesaCreatePixmapBuffer(XMesaVisual v, X + + if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { +- free_xmesa_buffer(client, b); ++ xmesa_free_buffer(b); + return NULL; + } + +@@ -1821,7 +1811,7 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaC + + if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + drawable, cmap)) { +- free_xmesa_buffer(client, b); ++ xmesa_free_buffer(b); + return NULL; + } + +@@ -1834,48 +1824,10 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaC + /* + * Deallocate an XMesaBuffer structure and all related info. + */ +-void XMesaDestroyBuffer( XMesaBuffer b ) ++void ++XMesaDestroyBuffer(XMesaBuffer b) + { +- int client = 0; +- +-#ifdef XFree86Server +- if (b->frontxrb->drawable) +- client = CLIENT_ID(b->frontxrb->drawable->id); +-#endif +- +- if (b->gc) XMesaFreeGC( b->xm_visual->display, b->gc ); +- if (b->cleargc) XMesaFreeGC( b->xm_visual->display, b->cleargc ); +- if (b->swapgc) XMesaFreeGC( b->xm_visual->display, b->swapgc ); +- +- if (b->xm_visual->mesa_visual.doubleBufferMode) +- { +- if (b->backxrb->ximage) { +-#if defined(USE_XSHM) && !defined(XFree86Server) +- if (b->shm) { +- XShmDetach( b->xm_visual->display, &b->shminfo ); +- XDestroyImage( b->backxrb->ximage ); +- shmdt( b->shminfo.shmaddr ); +- } +- else +-#endif +- XMesaDestroyImage( b->backxrb->ximage ); +- } +- if (b->backxrb->pixmap) { +- XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); +- if (b->xm_visual->hpcr_clear_flag) { +- XMesaFreePixmap( b->xm_visual->display, +- b->xm_visual->hpcr_clear_pixmap ); +- XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); +- } +- } +- } +- if (b->rowimage) { +- _mesa_free( b->rowimage->data ); +- b->rowimage->data = NULL; +- XMesaDestroyImage( b->rowimage ); +- } +- +- free_xmesa_buffer(client, b); ++ xmesa_free_buffer(b); + } + + +@@ -2436,7 +2388,7 @@ void xmesa_destroy_buffers_on_display(XM + for (b = XMesaBufferList; b; b = next) { + next = b->Next; + if (b->display == dpy) { +- free_xmesa_buffer(0, b); ++ xmesa_free_buffer(b); + } + } + } +diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c +index 490c479..187ae51 100644 +--- a/src/mesa/drivers/x11/xm_buffer.c ++++ b/src/mesa/drivers/x11/xm_buffer.c +@@ -33,6 +33,7 @@ + #include "GL/xmesa.h" + #include "xmesaP.h" + #include "imports.h" ++#include "framebuffer.h" + #include "renderbuffer.h" + + +@@ -352,5 +353,72 @@ xmesa_new_renderbuffer(GLcontext *ctx, G + } + + ++/** ++ * Called via gl_framebuffer::Delete() method when this buffer ++ * is _really_ being ++ * deleted. ++ */ ++void ++xmesa_delete_framebuffer(struct gl_framebuffer *fb) ++{ ++ XMesaBuffer b = XMESA_BUFFER(fb); + ++#ifdef XFree86Server ++ int client = 0; ++ if (b->frontxrb->drawable) ++ client = CLIENT_ID(b->frontxrb->drawable->id); ++#endif + ++ if (b->num_alloced > 0) { ++ /* If no other buffer uses this X colormap then free the colors. */ ++ if (!xmesa_find_buffer(b->display, b->cmap, b)) { ++#ifdef XFree86Server ++ (void)FreeColors(b->cmap, client, ++ b->num_alloced, b->alloced_colors, 0); ++#else ++ XFreeColors(b->display, b->cmap, ++ b->alloced_colors, b->num_alloced, 0); ++#endif ++ } ++ } ++ ++ if (b->gc) ++ XMesaFreeGC(b->xm_visual->display, b->gc); ++ if (b->cleargc) ++ XMesaFreeGC(b->xm_visual->display, b->cleargc); ++ if (b->swapgc) ++ XMesaFreeGC(b->xm_visual->display, b->swapgc); ++ ++ if (b->xm_visual->mesa_visual.doubleBufferMode) { ++ /* free back ximage/pixmap/shmregion */ ++ if (b->backxrb->ximage) { ++#if defined(USE_XSHM) && !defined(XFree86Server) ++ if (b->shm) { ++ XShmDetach( b->xm_visual->display, &b->shminfo ); ++ XDestroyImage( b->backxrb->ximage ); ++ shmdt( b->shminfo.shmaddr ); ++ } ++ else ++#endif ++ XMesaDestroyImage( b->backxrb->ximage ); ++ b->backxrb->ximage = NULL; ++ } ++ if (b->backxrb->pixmap) { ++ XMesaFreePixmap( b->xm_visual->display, b->backxrb->pixmap ); ++ if (b->xm_visual->hpcr_clear_flag) { ++ XMesaFreePixmap( b->xm_visual->display, ++ b->xm_visual->hpcr_clear_pixmap ); ++ XMesaDestroyImage( b->xm_visual->hpcr_clear_ximage ); ++ } ++ } ++ } ++ ++ if (b->rowimage) { ++ _mesa_free( b->rowimage->data ); ++ b->rowimage->data = NULL; ++ XMesaDestroyImage( b->rowimage ); ++ } ++ ++ _mesa_free_framebuffer_data(fb); ++ _mesa_free(fb); ++} +diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h +index e332fb5..5516031 100644 +--- a/src/mesa/drivers/x11/xmesaP.h ++++ b/src/mesa/drivers/x11/xmesaP.h +@@ -42,6 +42,7 @@ + + extern _glthread_Mutex _xmesa_lock; + ++extern XMesaBuffer XMesaBufferList; + + /* for PF_8R8G8B24 pixel format */ + typedef struct { +@@ -489,6 +490,12 @@ extern struct xmesa_renderbuffer * + xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual, + GLboolean backBuffer); + ++extern void ++xmesa_delete_framebuffer(struct gl_framebuffer *fb); ++ ++extern XMesaBuffer ++xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis); ++ + extern unsigned long + xmesa_color_to_pixel( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a, diff --git a/bug-211314_mesa-framebuffer-counting.diff b/bug-211314_mesa-framebuffer-counting.diff new file mode 100644 index 0000000..ef80c39 --- /dev/null +++ b/bug-211314_mesa-framebuffer-counting.diff @@ -0,0 +1,147 @@ +commit e6a9381f78605072cab52447fce35eaa98c1e75c +Author: Brian +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. diff --git a/bug-211314_mesa-refcount-memleak-fixes.diff b/bug-211314_mesa-refcount-memleak-fixes.diff new file mode 100644 index 0000000..1c73430 --- /dev/null +++ b/bug-211314_mesa-refcount-memleak-fixes.diff @@ -0,0 +1,316 @@ +commit 42aaa548a1020be5d40b3dce9448d8004b1ef947 +Author: Brian +Date: Sun Mar 25 10:39:36 2007 -0600 + + Fix some renderbuffer reference counting issues. Also fixes a mem leak. + +diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c +index c1fa233..bb8fe31 100644 +--- a/src/mesa/drivers/x11/xm_buffer.c ++++ b/src/mesa/drivers/x11/xm_buffer.c +@@ -422,18 +422,6 @@ xmesa_delete_framebuffer(struct gl_frame + XMesaDestroyImage( b->rowimage ); + } + +- /* Note that XMesaBuffer renderbuffers normally have a refcount of 2 +- * (creation + binding) so we need to explicitly delete/unbind them here. +- */ +- if (b->frontxrb) { +- _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->frontxrb); +- ASSERT(b->frontxrb == NULL); +- } +- if (b->backxrb) { +- _mesa_unreference_renderbuffer((struct gl_renderbuffer **) &b->backxrb); +- ASSERT(b->backxrb == NULL); +- } +- + _mesa_free_framebuffer_data(fb); + _mesa_free(fb); + } +diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c +index f7e870b..fefa14e 100644 +--- a/src/mesa/main/fbobject.c ++++ b/src/mesa/main/fbobject.c +@@ -559,7 +559,7 @@ _mesa_IsRenderbufferEXT(GLuint renderbuf + void GLAPIENTRY + _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) + { +- struct gl_renderbuffer *newRb, *oldRb; ++ struct gl_renderbuffer *newRb; + GET_CURRENT_CONTEXT(ctx); + + ASSERT_OUTSIDE_BEGIN_END(ctx); +@@ -593,21 +593,16 @@ _mesa_BindRenderbufferEXT(GLenum target, + } + ASSERT(newRb->AllocStorage); + _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb); ++ newRb->RefCount = 1; /* referenced by hash table */ + } +- newRb->RefCount++; + } + else { + newRb = NULL; + } + +- oldRb = ctx->CurrentRenderbuffer; +- if (oldRb) { +- _mesa_unreference_renderbuffer(&oldRb); +- } +- + ASSERT(newRb != &DummyRenderbuffer); + +- ctx->CurrentRenderbuffer = newRb; ++ _mesa_reference_renderbuffer(&ctx->CurrentRenderbuffer, newRb); + } + + +@@ -632,14 +627,15 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, + _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + +- /* remove from hash table immediately, to free the ID */ ++ /* Remove from hash table immediately, to free the ID. ++ * But the object will not be freed until it's no longer ++ * referenced anywhere else. ++ */ + _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); + + if (rb != &DummyRenderbuffer) { +- /* But the object will not be freed until it's no longer +- * bound in any context. +- */ +- _mesa_unreference_renderbuffer(&rb); ++ /* no longer referenced by hash table */ ++ _mesa_reference_renderbuffer(&rb, NULL); + } + } + } +diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c +index cd4f594..1fd31a5 100644 +--- a/src/mesa/main/framebuffer.c ++++ b/src/mesa/main/framebuffer.c +@@ -70,42 +70,6 @@ compute_depth_max(struct gl_framebuffer + + + /** +- * Set the framebuffer's _DepthBuffer field, taking care of +- * reference counts, etc. +- */ +-static void +-set_depth_renderbuffer(struct gl_framebuffer *fb, +- struct gl_renderbuffer *rb) +-{ +- if (fb->_DepthBuffer) { +- _mesa_unreference_renderbuffer(&fb->_DepthBuffer); +- } +- fb->_DepthBuffer = rb; +- if (rb) { +- rb->RefCount++; +- } +-} +- +- +-/** +- * Set the framebuffer's _StencilBuffer field, taking care of +- * reference counts, etc. +- */ +-static void +-set_stencil_renderbuffer(struct gl_framebuffer *fb, +- struct gl_renderbuffer *rb) +-{ +- if (fb->_StencilBuffer) { +- _mesa_unreference_renderbuffer(&fb->_StencilBuffer); +- } +- fb->_StencilBuffer = rb; +- if (rb) { +- rb->RefCount++; +- } +-} +- +- +-/** + * Create and initialize a gl_framebuffer object. + * This is intended for creating _window_system_ framebuffers, not generic + * framebuffer objects ala GL_EXT_framebuffer_object. +@@ -223,7 +187,7 @@ _mesa_free_framebuffer_data(struct gl_fr + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; + if (att->Renderbuffer) { +- _mesa_unreference_renderbuffer(&att->Renderbuffer); ++ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + } + if (att->Texture) { + /* render to texture */ +@@ -239,9 +203,9 @@ _mesa_free_framebuffer_data(struct gl_fr + att->Texture = NULL; + } + +- /* unbind depth/stencil to decr ref counts */ +- set_depth_renderbuffer(fb, NULL); +- set_stencil_renderbuffer(fb, NULL); ++ /* unbind _Depth/_StencilBuffer to decr ref counts */ ++ _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL); ++ _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL); + } + + +@@ -569,13 +533,13 @@ _mesa_update_depth_buffer(GLcontext *ctx + /* need to update wrapper */ + struct gl_renderbuffer *wrapper + = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb); +- set_depth_renderbuffer(fb, wrapper); ++ _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper); + ASSERT(fb->_DepthBuffer->Wrapped == depthRb); + } + } + else { + /* depthRb may be null */ +- set_depth_renderbuffer(fb, depthRb); ++ _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb); + } + } + +@@ -610,13 +574,13 @@ _mesa_update_stencil_buffer(GLcontext *c + /* need to update wrapper */ + struct gl_renderbuffer *wrapper + = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb); +- set_stencil_renderbuffer(fb, wrapper); ++ _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper); + ASSERT(fb->_StencilBuffer->Wrapped == stencilRb); + } + } + else { + /* stencilRb may be null */ +- set_stencil_renderbuffer(fb, stencilRb); ++ _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb); + } + } + +diff --git a/src/mesa/main/rbadaptors.c b/src/mesa/main/rbadaptors.c +index 60f4948..c1ac060 100644 +--- a/src/mesa/main/rbadaptors.c ++++ b/src/mesa/main/rbadaptors.c +@@ -45,7 +45,7 @@ Delete_wrapper(struct gl_renderbuffer *r + /* Decrement reference count on the buffer we're wrapping and delete + * it if refcount hits zero. + */ +- _mesa_unreference_renderbuffer(&rb->Wrapped); ++ _mesa_reference_renderbuffer(&rb->Wrapped, NULL); + + /* delete myself */ + _mesa_delete_renderbuffer(rb); +diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c +index ded0063..49706b5 100644 +--- a/src/mesa/main/renderbuffer.c ++++ b/src/mesa/main/renderbuffer.c +@@ -1473,7 +1473,7 @@ _mesa_init_renderbuffer(struct gl_render + + rb->ClassID = 0; + rb->Name = name; +- rb->RefCount = 1; ++ rb->RefCount = 0; + rb->Delete = _mesa_delete_renderbuffer; + + /* The rest of these should be set later by the caller of this function or +@@ -2105,9 +2105,7 @@ _mesa_add_renderbuffer(struct gl_framebu + + fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; + fb->Attachment[bufferName].Complete = GL_TRUE; +- fb->Attachment[bufferName].Renderbuffer = rb; +- +- rb->RefCount++; ++ _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, rb); + } + + +@@ -2125,38 +2123,55 @@ _mesa_remove_renderbuffer(struct gl_fram + if (!rb) + return; + +- _mesa_unreference_renderbuffer(&rb); ++ _mesa_reference_renderbuffer(&rb, NULL); + + fb->Attachment[bufferName].Renderbuffer = NULL; + } + + + /** +- * Decrement a renderbuffer object's reference count and delete it when +- * the refcount hits zero. +- * Note: we pass the address of a pointer. ++ * Set *ptr to point to rb. If *ptr points to another renderbuffer, ++ * dereference that buffer first. The new renderbuffer's refcount will ++ * be incremented. The old renderbuffer's refcount will be decremented. + */ + void +-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb) ++_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, ++ struct gl_renderbuffer *rb) + { +- assert(rb); +- if (*rb) { ++ assert(ptr); ++ if (*ptr == rb) { ++ /* no change */ ++ return; ++ } ++ ++ if (*ptr) { ++ /* Unreference the old renderbuffer */ + GLboolean deleteFlag = GL_FALSE; ++ struct gl_renderbuffer *oldRb = *ptr; + +- _glthread_LOCK_MUTEX((*rb)->Mutex); +- ASSERT((*rb)->RefCount > 0); +- (*rb)->RefCount--; +- deleteFlag = ((*rb)->RefCount == 0); +- _glthread_UNLOCK_MUTEX((*rb)->Mutex); ++ _glthread_LOCK_MUTEX(oldRb->Mutex); ++ ASSERT(oldRb->RefCount > 0); ++ oldRb->RefCount--; ++ /*printf("RB DECR %p to %d\n", (void*) oldRb, oldRb->RefCount);*/ ++ deleteFlag = (oldRb->RefCount == 0); ++ _glthread_UNLOCK_MUTEX(oldRb->Mutex); + + if (deleteFlag) +- (*rb)->Delete(*rb); ++ oldRb->Delete(oldRb); + +- *rb = NULL; ++ *ptr = NULL; + } +-} +- ++ assert(!*ptr); + ++ if (rb) { ++ /* reference new renderbuffer */ ++ _glthread_LOCK_MUTEX(rb->Mutex); ++ rb->RefCount++; ++ /*printf("RB REF %p to %d\n", (void*)rb, rb->RefCount);*/ ++ _glthread_UNLOCK_MUTEX(rb->Mutex); ++ *ptr = rb; ++ } ++} + + + /** +@@ -2180,4 +2195,3 @@ _mesa_new_depthstencil_renderbuffer(GLco + + return dsrb; + } +- +diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h +index e5f1147..c9bf888 100644 +--- a/src/mesa/main/renderbuffer.h ++++ b/src/mesa/main/renderbuffer.h +@@ -102,7 +102,8 @@ extern void + _mesa_remove_renderbuffer(struct gl_framebuffer *fb, GLuint bufferName); + + extern void +-_mesa_unreference_renderbuffer(struct gl_renderbuffer **rb); ++_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, ++ struct gl_renderbuffer *rb); + + extern struct gl_renderbuffer * + _mesa_new_depthstencil_renderbuffer(GLcontext *ctx, GLuint name); diff --git a/disable-sis_dri.diff b/disable-sis_dri.diff index b9e2488..0c8d870 100644 --- a/disable-sis_dri.diff +++ b/disable-sis_dri.diff @@ -4,5 +4,5 @@ # gamma are missing because they have not been converted to use the new # interface. DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \ -- savage sis tdfx trident unichrome ffb nouveau +- savage sis tdfx trident unichrome ffb + savage tdfx trident unichrome ffb