| diff -paur mesa-7.10.2/src/glx/dri2_glx.c mesa-7.10.2.work/src/glx/dri2_glx.c |
| --- mesa-7.10.2/src/glx/dri2_glx.c 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/dri2_glx.c 2011-06-16 20:54:42.294798000 -0700 |
| @@ -143,6 +143,8 @@ dri2_bind_context(struct glx_context *co |
| pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw); |
| pread = (struct dri2_drawable *) driFetchDrawable(context, read); |
| |
| + driReleaseDrawables(&pcp->base); |
| + |
| if (pdraw == NULL || pread == NULL) |
| return GLXBadDrawable; |
| |
| @@ -170,9 +172,6 @@ dri2_unbind_context(struct glx_context * |
| struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; |
| |
| (*psc->core->unbindContext) (pcp->driContext); |
| - |
| - if (context == new) |
| - driReleaseDrawables(&pcp->base); |
| } |
| |
| static struct glx_context * |
| diff -paur mesa-7.10.2/src/glx/dri_common.c mesa-7.10.2.work/src/glx/dri_common.c |
| --- mesa-7.10.2/src/glx/dri_common.c 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/dri_common.c 2011-06-16 20:54:42.302797000 -0700 |
| @@ -367,8 +367,10 @@ driFetchDrawable(struct glx_context *gc, |
| if (priv->drawHash == NULL) |
| return NULL; |
| |
| - if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) |
| + if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) { |
| + pdraw->refcount ++; |
| return pdraw; |
| + } |
| |
| pdraw = psc->driScreen->createDrawable(psc, glxDrawable, |
| glxDrawable, gc->config); |
| @@ -376,6 +378,7 @@ driFetchDrawable(struct glx_context *gc, |
| (*pdraw->destroyDrawable) (pdraw); |
| return NULL; |
| } |
| + pdraw->refcount = 1; |
| |
| return pdraw; |
| } |
| @@ -392,19 +395,28 @@ driReleaseDrawables(struct glx_context * |
| if (__glxHashLookup(priv->drawHash, |
| gc->currentDrawable, (void *) &pdraw) == 0) { |
| if (pdraw->drawable == pdraw->xDrawable) { |
| - (*pdraw->destroyDrawable)(pdraw); |
| - __glxHashDelete(priv->drawHash, gc->currentDrawable); |
| + pdraw->refcount --; |
| + if (pdraw->refcount == 0) { |
| + (*pdraw->destroyDrawable)(pdraw); |
| + __glxHashDelete(priv->drawHash, gc->currentDrawable); |
| + } |
| } |
| } |
| |
| - if (gc->currentDrawable != gc->currentReadable && |
| - __glxHashLookup(priv->drawHash, |
| + if (__glxHashLookup(priv->drawHash, |
| gc->currentReadable, (void *) &pdraw) == 0) { |
| if (pdraw->drawable == pdraw->xDrawable) { |
| - (*pdraw->destroyDrawable)(pdraw); |
| - __glxHashDelete(priv->drawHash, gc->currentReadable); |
| + pdraw->refcount --; |
| + if (pdraw->refcount == 0) { |
| + (*pdraw->destroyDrawable)(pdraw); |
| + __glxHashDelete(priv->drawHash, gc->currentReadable); |
| + } |
| } |
| } |
| + |
| + gc->currentDrawable = None; |
| + gc->currentReadable = None; |
| + |
| } |
| |
| #endif /* GLX_DIRECT_RENDERING */ |
| diff -paur mesa-7.10.2/src/glx/dri_glx.c mesa-7.10.2.work/src/glx/dri_glx.c |
| --- mesa-7.10.2/src/glx/dri_glx.c 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/dri_glx.c 2011-06-16 20:54:42.305804000 -0700 |
| @@ -503,6 +503,8 @@ dri_destroy_context(struct glx_context * |
| struct dri_context *pcp = (struct dri_context *) context; |
| struct dri_screen *psc = (struct dri_screen *) context->psc; |
| |
| + driReleaseDrawables(&pcp->base); |
| + |
| if (context->xid) |
| glx_send_destroy_context(psc->base.dpy, context->xid); |
| |
| @@ -526,6 +528,8 @@ dri_bind_context(struct glx_context *con |
| pdraw = (struct dri_drawable *) driFetchDrawable(context, draw); |
| pread = (struct dri_drawable *) driFetchDrawable(context, read); |
| |
| + driReleaseDrawables(&pcp->base); |
| + |
| if (pdraw == NULL || pread == NULL) |
| return GLXBadDrawable; |
| |
| @@ -543,8 +547,6 @@ dri_unbind_context(struct glx_context *c |
| struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; |
| |
| (*psc->core->unbindContext) (pcp->driContext); |
| - |
| - driReleaseDrawables(&pcp->base); |
| } |
| |
| static const struct glx_context_vtable dri_context_vtable = { |
| diff -paur mesa-7.10.2/src/glx/drisw_glx.c mesa-7.10.2.work/src/glx/drisw_glx.c |
| --- mesa-7.10.2/src/glx/drisw_glx.c 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/drisw_glx.c 2011-06-16 20:54:42.312797000 -0700 |
| @@ -244,6 +244,8 @@ drisw_destroy_context(struct glx_context |
| struct drisw_context *pcp = (struct drisw_context *) context; |
| struct drisw_screen *psc = (struct drisw_screen *) context->psc; |
| |
| + driReleaseDrawables(&pcp->base); |
| + |
| if (context->xid) |
| glx_send_destroy_context(psc->base.dpy, context->xid); |
| |
| @@ -266,6 +268,8 @@ drisw_bind_context(struct glx_context *c |
| pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw); |
| pread = (struct drisw_drawable *) driFetchDrawable(context, read); |
| |
| + driReleaseDrawables(&pcp->base); |
| + |
| if (pdraw == NULL || pread == NULL) |
| return GLXBadDrawable; |
| |
| @@ -283,8 +287,6 @@ drisw_unbind_context(struct glx_context |
| struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc; |
| |
| (*psc->core->unbindContext) (pcp->driContext); |
| - |
| - driReleaseDrawables(&pcp->base); |
| } |
| |
| static const struct glx_context_vtable drisw_context_vtable = { |
| diff -paur mesa-7.10.2/src/glx/glxclient.h mesa-7.10.2.work/src/glx/glxclient.h |
| --- mesa-7.10.2/src/glx/glxclient.h 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/glxclient.h 2011-06-16 20:54:42.316797000 -0700 |
| @@ -138,6 +138,7 @@ struct __GLXDRIdrawableRec |
| GLenum textureTarget; |
| GLenum textureFormat; /* EXT_texture_from_pixmap support */ |
| unsigned long eventMask; |
| + int refcount; |
| }; |
| |
| /* |
| diff -paur mesa-7.10.2/src/glx/glxcurrent.c mesa-7.10.2.work/src/glx/glxcurrent.c |
| --- mesa-7.10.2/src/glx/glxcurrent.c 2011-04-06 13:41:43.000000000 -0700 |
| +++ mesa-7.10.2.work/src/glx/glxcurrent.c 2011-06-16 20:57:36.183701000 -0700 |
| @@ -249,18 +249,16 @@ MakeContextCurrent(Display * dpy, GLXDra |
| if (oldGC != &dummyContext) { |
| oldGC->vtable->unbind(oldGC, gc); |
| oldGC->currentDpy = 0; |
| - oldGC->currentDrawable = None; |
| - oldGC->currentReadable = None; |
| oldGC->thread_id = 0; |
| } |
| |
| if (gc) { |
| gc->currentDpy = dpy; |
| - gc->currentDrawable = draw; |
| - gc->currentReadable = read; |
| gc->thread_id = _glthread_GetID(); |
| __glXSetCurrentContext(gc); |
| ret = gc->vtable->bind(gc, oldGC, draw, read); |
| + gc->currentDrawable = draw; |
| + gc->currentReadable = read; |
| } else { |
| __glXSetCurrentContextNull(); |
| } |