From 844147f263809f05941e54f5f799f398834c42c3 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Thu, 11 May 2006 14:37:03 +0000 Subject: [PATCH] Fix GLX drawable destruction --- GL/glx/glxext.c | 3 +++ GL/glx/glxscreens.c | 3 +++ GL/glx/glxutil.c | 5 +---- GL/mesa/X/xf86glx.c | 34 ++++++++++++++++++++++++++++++---- hw/xgl/glxext/xglglxext.c | 8 ++++++-- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c index 8b1a586b1..b55acb4bb 100644 --- a/GL/glx/glxext.c +++ b/GL/glx/glxext.c @@ -181,6 +181,9 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) } } + /* remove the drawable from the drawable list */ + FreeResourceByType(glxPriv->drawId, __glXDrawableRes, FALSE); + __glXUnrefDrawable(glxPriv); return True; diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 2af553d0c..3b5bafa00 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -199,12 +199,15 @@ static Bool PositionWindow(WindowPtr pWin, int x, int y) } /* mark contexts as needing resize */ + __glXFlushContextCache (); for (glxc = glxPriv->drawGlxc; glxc; glxc = glxc->nextDrawPriv) { + (*glxc->loseCurrent)(glxc); glxc->pendingState |= __GLX_PENDING_RESIZE; } for (glxc = glxPriv->readGlxc; glxc; glxc = glxc->nextReadPriv) { + (*glxc->loseCurrent)(glxc); glxc->pendingState |= __GLX_PENDING_RESIZE; } diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c index f1f9c06c5..fe206be7c 100644 --- a/GL/glx/glxutil.c +++ b/GL/glx/glxutil.c @@ -131,11 +131,8 @@ void __glXUnrefDrawable(__GLXdrawable *glxPriv) { glxPriv->refCount--; - if (glxPriv->refCount == 0) { - /* remove the drawable from the drawable list */ - FreeResourceByType(glxPriv->drawId, __glXDrawableRes, FALSE); + if (glxPriv->refCount == 0) glxPriv->destroy(glxPriv); - } } GLboolean diff --git a/GL/mesa/X/xf86glx.c b/GL/mesa/X/xf86glx.c index e16137df7..09cebc4da 100644 --- a/GL/mesa/X/xf86glx.c +++ b/GL/mesa/X/xf86glx.c @@ -86,6 +86,9 @@ struct __GLXMESAscreen { struct __GLXMESAcontext { __GLXcontext base; XMesaContext xmesa; + + __GLXMESAdrawable *drawPriv; + __GLXMESAdrawable *readPriv; }; struct __GLXMESAdrawable { @@ -102,7 +105,10 @@ __glXMesaDrawableDestroy(__GLXdrawable *base) __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base; if (glxPriv->xm_buf) + { + glxPriv->xm_buf->frontxrb->drawable = 0; XMesaDestroyBuffer(glxPriv->xm_buf); + } xfree(glxPriv); } @@ -111,7 +117,8 @@ __glXMesaDrawableResize(__GLXdrawable *base) { __GLXMESAdrawable *glxPriv = (__GLXMESAdrawable *) base; - XMesaResizeBuffers(glxPriv->xm_buf); + if (XMesaGetCurrentBuffer () == glxPriv->xm_buf) + XMesaResizeBuffers(glxPriv->xm_buf); return GL_TRUE; } @@ -214,6 +221,11 @@ __glXMesaContextDestroy(__GLXcontext *baseContext) { __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext; + if (context->drawPriv) + __glXUnrefDrawable (&context->drawPriv->base); + if (context->readPriv) + __glXUnrefDrawable (&context->readPriv->base); + XMesaDestroyContext(context->xmesa); __glXContextDestroy(context); xfree(context); @@ -226,10 +238,24 @@ __glXMesaContextMakeCurrent(__GLXcontext *baseContext) __GLXMESAcontext *context = (__GLXMESAcontext *) baseContext; __GLXMESAdrawable *drawPriv = (__GLXMESAdrawable *) context->base.drawPriv; __GLXMESAdrawable *readPriv = (__GLXMESAdrawable *) context->base.readPriv; + int status; - return XMesaMakeCurrent2(context->xmesa, - drawPriv->xm_buf, - readPriv->xm_buf); + __glXRefDrawable (&drawPriv->base); + __glXRefDrawable (&readPriv->base); + + status = XMesaMakeCurrent2(context->xmesa, + drawPriv->xm_buf, + readPriv->xm_buf); + + if (context->drawPriv) + __glXUnrefDrawable (&context->drawPriv->base); + if (context->readPriv) + __glXUnrefDrawable (&context->readPriv->base); + + context->drawPriv = drawPriv; + context->readPriv = readPriv; + + return status; } static int diff --git a/hw/xgl/glxext/xglglxext.c b/hw/xgl/glxext/xglglxext.c index 99150120a..89f060257 100644 --- a/hw/xgl/glxext/xglglxext.c +++ b/hw/xgl/glxext/xglglxext.c @@ -5583,7 +5583,11 @@ xglDestroyDrawable (__GLXdrawable *drawable) __GLXdrawable *mesaDrawable = pBufferPriv->mesaDrawable; if (mesaDrawable) - (*mesaDrawable->destroy) (mesaDrawable); + { + mesaDrawable->refCount--; + if (!mesaDrawable->refCount) + (*mesaDrawable->destroy) (mesaDrawable); + } if (pBufferPriv->pGC) FreeGC (pBufferPriv->pGC, (GContext) 0); @@ -6351,7 +6355,7 @@ xglScreenDestroy (__GLXscreen *screen) __GLXscreen *mesaScreen = pScreen->mesaScreen; if (mesaScreen) - GlxScreenDestroy (mesaScreen); + (*mesaScreen->destroy) (mesaScreen); if (pScreen->GLXextensions) xfree (pScreen->GLXextensions);