From 3750ebd540510324ef5ada769537ae05309adadb Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Mon, 19 Jul 2010 09:37:07 -0400 Subject: glx: Fix drawable lookup in DRI2 event handler DRI2 events are sent to the X drawable ID used to create the DRI2 drawable, not the GLX drawable ID. So when an event comes in, we need to look up the __GLXDRIdrawable by its X drawable ID, which needs a new hash table. --- src/glx/dri2.c | 3 ++- src/glx/dri2_glx.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/glx/glxclient.h | 2 ++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/glx/dri2.c b/src/glx/dri2.c index dbf3420892..ab530baf0f 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -99,9 +99,10 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, awire->drawable, NULL); + __GLXDRIdrawable *pdraw; /* Ignore swap events if we're not looking for them */ + pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable); if (!(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) return False; diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index d4747388e3..04d900c2e5 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -74,6 +74,8 @@ struct __GLXDRIdisplayPrivateRec int swapAvailable; int invalidateAvailable; + __glxHashTable *dri2Hash; + const __DRIextension *loader_extensions[4]; }; @@ -166,10 +168,16 @@ dri2CreateContext(__GLXscreenConfigs * psc, } static void -dri2DestroyDrawable(__GLXDRIdrawable * pdraw) +dri2DestroyDrawable(__GLXDRIdrawable *pdraw) { const __DRIcoreExtension *core = pdraw->psc->core; + __GLXdisplayPrivate *dpyPriv; + __GLXDRIdisplayPrivate *pdp; + dpyPriv = __glXInitialize(pdraw->psc->dpy); + pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; + + __glxHashDelete(pdp->dri2Hash, pdraw->xDrawable); (*core->destroyDrawable) (pdraw->driDrawable); DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable); Xfree(pdraw); @@ -228,6 +236,14 @@ dri2CreateDrawable(__GLXscreenConfigs * psc, return NULL; } + if (__glxHashInsert(pdp->dri2Hash, xDrawable, pdraw)) { + (*psc->core->destroyDrawable) (pdraw->base.driDrawable); + DRI2DestroyDrawable(psc->dpy, xDrawable); + Xfree(pdraw); + return None; + } + + #ifdef X_DRI2SwapInterval /* * Make sure server has the same swap interval we do for the new @@ -555,7 +571,8 @@ static const __DRIuseInvalidateExtension dri2UseInvalidate = { _X_HIDDEN void dri2InvalidateBuffers(Display *dpy, XID drawable) { - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + __GLXDRIdrawable *pdraw = + dri2GetGlxDrawableFromXDrawableId(dpy, drawable); #if __DRI2_FLUSH_VERSION >= 3 if (pdraw && pdraw->psc->f) @@ -751,6 +768,19 @@ dri2DestroyDisplay(__GLXDRIdisplay * dpy) Xfree(dpy); } +_X_HIDDEN __GLXDRIdrawable * +dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id) +{ + __GLXdisplayPrivate *d = __glXInitialize(dpy); + __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *) d->dri2Display; + __GLXDRIdrawable *pdraw; + + if (__glxHashLookup(pdp->dri2Hash, id, (void *) &pdraw) == 0) + return pdraw; + + return NULL; +} + /* * Allocate, initialize and return a __DRIdisplayPrivate object. * This is called from __glXInitialize() when we are given a new @@ -794,6 +824,12 @@ dri2CreateDisplay(Display * dpy) #endif pdp->loader_extensions[i++] = NULL; + pdp->dri2Hash = __glxHashCreate(); + if (pdp->dri2Hash == NULL) { + Xfree(pdp); + return NULL; + } + return &pdp->base; } diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 49f31a16fe..ef46a39928 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -650,6 +650,8 @@ struct __GLXdisplayPrivateRec #endif }; +extern __GLXDRIdrawable * +dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id); extern GLubyte *__glXFlushRenderBuffer(__GLXcontext *, GLubyte *); -- cgit v1.2.3