From 928a70e4354d4884e2918ec67ddc6d8baf942c8a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 26 Feb 2007 11:39:17 -0700 Subject: 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. --- src/mesa/drivers/x11/xm_buffer.c | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'src/mesa/drivers/x11/xm_buffer.c') diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index 490c479676..187ae516cf 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, GLuint name, const GLvisual *visual, } +/** + * 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); +} -- cgit v1.2.3 From 59e56ee3e5c8f9aa9ec74e1817065a7ae14012ea Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 27 Feb 2007 11:09:48 -0700 Subject: fix comment --- src/mesa/drivers/x11/xm_buffer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/drivers/x11/xm_buffer.c') diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index 187ae516cf..a358ec25ae 100644 --- a/src/mesa/drivers/x11/xm_buffer.c +++ b/src/mesa/drivers/x11/xm_buffer.c @@ -355,8 +355,7 @@ xmesa_new_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual, /** * Called via gl_framebuffer::Delete() method when this buffer - * is _really_ being - * deleted. + * is _really_ being deleted. */ void xmesa_delete_framebuffer(struct gl_framebuffer *fb) -- cgit v1.2.3 From 955906aa647d0d233b422c979e1ee81dc32abb87 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Mar 2007 16:25:07 -0700 Subject: fix renderbuffer mem leak --- src/mesa/drivers/x11/xm_buffer.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/mesa/drivers/x11/xm_buffer.c') diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c index a358ec25ae..747971a6c3 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_framebuffer *fb) 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); } -- cgit v1.2.3