1
0
OBS User unknown 2007-03-20 00:22:56 +00:00 committed by Git OBS Bridge
parent 1839f722aa
commit 25e9371fc9
18 changed files with 1633 additions and 189 deletions

99
bug-211314-patch-1.diff Normal file
View File

@ -0,0 +1,99 @@
commit f30e8a4bdf8338dc3f8e985a9c91af61a3301990
Author: Brian <brian@yutani.localnet.net>
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;

19
bug-211314-patch-10.diff Normal file
View File

@ -0,0 +1,19 @@
commit f04979ae481acc9fdc423da06514c4d557edd7cd
Author: Mathias Hopf <mhopf@suse.de>
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);
}

218
bug-211314-patch-11.diff Normal file
View File

@ -0,0 +1,218 @@
commit e5070bc3ca75dee31034cc543f3d2ee04e5dc032
Author: Brian <brian@yutani.localnet.net>
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;

594
bug-211314-patch-2.diff Normal file
View File

@ -0,0 +1,594 @@
commit a510bc3ee1a696da120c09ee4ec33dc033f671ac
Author: Brian <brian@yutani.localnet.net>
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);

29
bug-211314-patch-3.diff Normal file
View File

@ -0,0 +1,29 @@
commit 955906aa647d0d233b422c979e1ee81dc32abb87
Author: Brian <brian@yutani.localnet.net>
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);
}

24
bug-211314-patch-4.diff Normal file
View File

@ -0,0 +1,24 @@
commit 1a6baf092b4c31d5fd30c934f1a17d69c9689f12
Author: Brian <brian@yutani.localnet.net>
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);

26
bug-211314-patch-5.diff Normal file
View File

@ -0,0 +1,26 @@
commit e69da9d02ecdf47d930276783f8b8df1a3cd99dd
Author: Brian <brian@yutani.localnet.net>
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 */

30
bug-211314-patch-6.diff Normal file
View File

@ -0,0 +1,30 @@
commit 47e0b606a85059ff29fe311dc2f1bcafdefe4cdb
Author: Brian <brian@yutani.localnet.net>
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

23
bug-211314-patch-7.diff Normal file
View File

@ -0,0 +1,23 @@
commit 3049946fa742b654afa9b24f8bc79f387f01aea9
Author: Brian <brian@yutani.localnet.net>
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);

47
bug-211314-patch-8.diff Normal file
View File

@ -0,0 +1,47 @@
commit 038e981cacdc6f32588442666cde8a8fc16cfdfc
Author: Brian <brian@yutani.localnet.net>
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/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index 408174c..dde2b1d 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -1350,7 +1350,7 @@ _swrast_clear_depth_buffer( GLcontext *c
GLuint clearValue;
GLint x, y, width, height;
- if (!rb || !ctx->Depth.Mask) {
+ if (!rb || !ctx->Depth.Mask || !rb->Data) {
/* no depth buffer, or writing to it is disabled */
return;
}
diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c
index a8aa1d4..43475c0 100644
--- a/src/mesa/swrast/s_stencil.c
+++ b/src/mesa/swrast/s_stencil.c
@@ -1154,7 +1154,7 @@ _swrast_clear_stencil_buffer( GLcontext
const GLuint stencilMax = (1 << stencilBits) - 1;
GLint x, y, width, height;
- if (!rb || mask == 0)
+ if (!rb || mask == 0 || !rb->Data)
return;
ASSERT(rb->DataType == GL_UNSIGNED_BYTE ||

20
bug-211314-patch-9.diff Normal file
View File

@ -0,0 +1,20 @@
commit 4d2eb637a20e4fdf5d5f6c0ea4d4627894594661
Author: Brian <brian@yutani.localnet.net>
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;

View File

@ -1,27 +0,0 @@
--- src/mesa/drivers/x11/xm_api.c.orig 2006-11-30 20:45:42.000000000 +0100
+++ src/mesa/drivers/x11/xm_api.c 2006-11-30 20:47:12.000000000 +0100
@@ -2101,7 +2101,11 @@ static void FXgetImage( XMesaBuffer b )
static unsigned short pixbuf[MAX_WIDTH];
GLuint x, y;
GLuint width, height;
- XMesaContext xmesa = XMESA_CONTEXT(ctx);
+ XMesaContext xmesa;
+
+ if (! ctx)
+ return;
+ xmesa = XMESA_CONTEXT(ctx);
#ifdef XFree86Server
x = b->frontxrb->pixmap->x;
@@ -2535,7 +2539,9 @@ void
XMesaResizeBuffers( XMesaBuffer b )
{
GET_CURRENT_CONTEXT(ctx);
- XMesaContext xmctx = XMESA_CONTEXT(ctx);
- xmesa_check_and_update_buffer_size(xmctx, b);
+ if (ctx) {
+ XMesaContext xmctx = XMESA_CONTEXT(ctx);
+ xmesa_check_and_update_buffer_size(xmctx, b);
+ }
}

View File

@ -0,0 +1,317 @@
commit 928a70e4354d4884e2918ec67ddc6d8baf942c8a
Author: Brian <brian@yutani.localnet.net>
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,

View File

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

View File

@ -1,143 +0,0 @@
Novell Bugzilla #211314 and others
Maybe Xorg Bugzilla #7205 and probably others
Programs apparently crash if a context is reused for a window that changed in
the meantime. Crashes apparently only occure for software rendering.
The basic problem is that a buffer is freed, when the according window is
closed, but the old context (which is no longer referenced in _glapi_Context
or in the according glxPriv structures) still has a reference to this buffer,
and is reactivated later. As the buffer points to a freed memory location, it
is no longer recognized as an old buffer (because buffer->Name - by accident -
contains 0x00cccccc) and not replaced.
About this patch:
The correct way to remove the reference would be to nuke it when a context is
disassociated from a drawable - because after that only the Xserver itself
(and not the Mesa subsystem) knows about the context which still has the stray
buffer and glxPriv pointers.
Unfortunately, if you do that, the server crashes in glxSwapBuffers() - I
don't known enough about that code to decide, whether this is a broken
implementation, a bug in glxSwapBuffers() (there might be other calls), broken
by design, or deliberately chosen this way and actually correct.
So the only way is to scan all contexts known for this client for references
to this buffer (and the according private structure) when the buffer is
actually destroyed. This is done in __glXMesaDrawableDestroy(), which has
access to all needed data - all but one.
Scanning all contexts only needs the client id (which is known), but the API
call FindClientResourcesByType() actually needs a ClientPtr - just to extract
the client id! The ClientPtr is only known in glxext.c in a static array
__glXClients. I don't know of a different API to get the ClientPtr from, so I
exported it. One other possibility would be to add a ClientPtr fetch call to
glxext.c, another one to create a new FindClientIDResourcesByType(), another
one to create a Client structure with just the id included (ugh!) just for
this API call. Making the array extern was the simplest thing to do, but is
not necessarily the right solution.
There is probably has a better / right possibility to remove all pointers to
the buffer (MakeCurrent2?) - but I don't have a better idea ATM.
As I consider this a workaround / saveguard for some deeply involved buffer
handling bug, I added a lot of ErrorF()s that indicate these failures. If
removing these references at this point is the only valid solution, I'd gladly
remove these. As the scanning is only invoked on buffer destroys and doesn't
do a lot of scanning, performance is not an issue here.
Matthias Hopf <mhopf@suse.de>
--- GL/glx/glxext.c.orig 2007-01-23 16:00:19.000000000 +0100
+++ GL/glx/glxext.c 2007-01-23 16:00:23.000000000 +0100
@@ -59,7 +59,7 @@ xGLXSingleReply __glXReply;
** A set of state for each client. The 0th one is unused because client
** indices start at 1, not 0.
*/
-static __GLXclientState *__glXClients[MAXCLIENTS + 1];
+__GLXclientState *__glXClients[MAXCLIENTS + 1];
/*
** Forward declarations.
--- GL/mesa/X/xf86glx.c.orig 2007-01-23 12:48:28.000000000 +0100
+++ GL/mesa/X/xf86glx.c 2007-01-25 16:50:19.000000000 +0100
@@ -95,12 +95,74 @@ static XMesaVisual find_mesa_visual(__GL
static void
+__glXMesaDrawableDestoryCB(pointer baseCtx, XID id, pointer basePriv)
+{
+ __GLXMESAcontext *context = (__GLXMESAcontext *) baseCtx;
+ __GLXdrawable *glxPriv = (__GLXdrawable *) basePriv;
+ void *buffer =((__GLXMESAdrawable *) glxPriv) ->xm_buf;
+ __GLXMESAdrawable *drawPriv, *readPriv;
+
+ if (context->base.drawPriv == glxPriv ||
+ context->base.readPriv == glxPriv) {
+ ErrorF ("Cleaning up stray priv pointers to %p in context %p\n",
+ glxPriv, context);
+ if (context->base.drawPriv == glxPriv)
+ context->base.drawPriv = NULL;
+ if (context->base.readPriv == glxPriv)
+ context->base.readPriv = NULL;
+ }
+ drawPriv = (__GLXMESAdrawable *) context->base.drawPriv;
+ readPriv = (__GLXMESAdrawable *) context->base.readPriv;
+ if ((drawPriv && drawPriv->xm_buf == buffer) ||
+ (readPriv && readPriv->xm_buf == buffer)) {
+ /* This should not happen, but the alternative is a sure server crash */
+ ErrorF ("ERROR: Draw priv in context %p is not freed yet, "
+ "but has stray buffer pointer %p\n", context, buffer);
+ if (drawPriv && drawPriv->xm_buf == buffer)
+ drawPriv->xm_buf = NULL;
+ if (readPriv && readPriv->xm_buf == buffer)
+ readPriv->xm_buf = NULL;
+ }
+ if (context->xmesa &&
+ (context->xmesa->mesa.DrawBuffer == buffer ||
+ context->xmesa->mesa.ReadBuffer == buffer ||
+ context->xmesa->mesa.WinSysDrawBuffer == buffer ||
+ context->xmesa->mesa.WinSysReadBuffer == buffer ||
+ context->xmesa->xm_buffer == buffer)) {
+ ErrorF ("Cleaning up stray xmesa pointers to buffer %p in context %p\n",
+ buffer, context);
+ if (context->xmesa->mesa.DrawBuffer == buffer)
+ context->xmesa->mesa.DrawBuffer = NULL;
+ if (context->xmesa->mesa.ReadBuffer == buffer)
+ context->xmesa->mesa.ReadBuffer = NULL;
+ if (context->xmesa->mesa.WinSysDrawBuffer == buffer)
+ context->xmesa->mesa.WinSysDrawBuffer = NULL;
+ if (context->xmesa->mesa.WinSysReadBuffer == buffer)
+ context->xmesa->mesa.WinSysReadBuffer = NULL;
+ if (context->xmesa->xm_buffer == buffer)
+ context->xmesa->xm_buffer = NULL;
+ }
+}
+
+extern __GLXclientState *__glXClients[];
+static void
__glXMesaDrawableDestroy(__GLXdrawable *base)
{
__GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base;
- if (glxPriv->xm_buf != NULL)
+ if (glxPriv->xm_buf != NULL) {
+ /* There may still be stray pointers in contexts that are no longer
+ * visible to Mesa. Scan all contexts for this client and nuke those
+ * pointers */
+ int clientId = CLIENT_ID(base->drawId);
+ if (clientId >=0 && clientId < MAXCLIENTS+1 && __glXClients[clientId]) {
+ ClientPtr client = __glXClients[clientId]->client;
+ if (client)
+ FindClientResourcesByType(client, __glXContextRes,
+ __glXMesaDrawableDestoryCB, glxPriv);
+ }
XMesaDestroyBuffer(glxPriv->xm_buf);
+ }
xfree(glxPriv);
}

View File

@ -1,12 +0,0 @@
--- hw/xfree86/int10/Makefile.am.orig 2007-03-14 15:36:06.000000000 +0100
+++ hw/xfree86/int10/Makefile.am 2007-03-14 15:37:59.669455872 +0100
@@ -29,6 +29,9 @@
if INT10_X86EMU
AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_X86EMU -DNO_SYS_HEADERS \
$(XORG_CFLAGS) $(EXTRA_CFLAGS)
+if LINUX_IA64
+AM_CFLAGS += -DNO_LONG_LONG
+endif
INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu
libint10_la_SOURCES = \
$(COMMON_SOURCES) \

View File

@ -1,3 +1,10 @@
-------------------------------------------------------------------
Mon Mar 19 22:22:43 CET 2007 - sndirsch@suse.de
- no longer apply bug-211314_mesa-context.diff,
bug-211314_p_drawable_privclean.diff (Bug #211314, comment #114)
- added different Mesa patches (Bug #211314, comments #114/#115)
-------------------------------------------------------------------
Thu Mar 15 13:29:53 CET 2007 - schwab@suse.de

View File

@ -21,7 +21,7 @@ BuildRequires: libjpeg-devel
URL: http://xorg.freedesktop.org/
%define EXPERIMENTAL 0
Version: 7.2
Release: 61
Release: 62
License: X11/MIT
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Group: System/X11/Servers/XF86_4
@ -79,10 +79,21 @@ Patch40: 0018-vnc-support.txt.diff
%endif
Patch41: loadmod-bug197195.diff
Patch42: bug227111-ddc_screensize.diff
Patch43: bug-211314_mesa-context.diff
Patch44: bug-211314_p_drawable_privclean.diff
Patch45: bug-197858_dpms.diff
Patch46: x86emu.diff
Patch47: bug-211314_mesa-destroy_buffers.diff
Patch48: bug-211314_mesa-framebuffer-counting.diff
Patch49: bug-211314-patch-1.diff
Patch50: bug-211314-patch-2.diff
Patch51: bug-211314-patch-3.diff
Patch52: bug-211314-patch-4.diff
Patch53: bug-211314-patch-5.diff
Patch54: bug-211314-patch-6.diff
Patch55: bug-211314-patch-7.diff
Patch56: bug-211314-patch-8.diff
Patch57: bug-211314-patch-9.diff
Patch58: bug-211314-patch-10.diff
Patch59: bug-211314-patch-11.diff
Patch334: p_pci-domain.diff
Patch357: p_pci-ce-x.diff
@ -173,12 +184,23 @@ popd
%endif
%patch41 -p1
%patch42 -p1
pushd ../Mesa
%patch43 -p0
popd
%patch44 -p0
%patch45 -p0
%patch46 -p0
pushd ../Mesa
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
popd
%build
autoreconf -fi
@ -509,6 +531,10 @@ exit 0
%endif
%changelog
* Mon Mar 19 2007 - sndirsch@suse.de
- no longer apply bug-211314_mesa-context.diff,
bug-211314_p_drawable_privclean.diff (Bug #211314, comment #114)
- added different Mesa patches (Bug #211314, comments #114/#115)
* Thu Mar 15 2007 - schwab@suse.de
- Remove bug197190-ia64.diff, fix x86emu instead.
* Wed Mar 14 2007 - sndirsch@suse.de