summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-07-19 09:37:07 -0400
committerKristian Høgsberg <krh@bitplanet.net>2010-07-19 09:37:38 -0400
commit3750ebd540510324ef5ada769537ae05309adadb (patch)
tree7c132086ed4e029a9f552ad100db6248f51e089b
parent4eaf591d1504f61e131f77f01711d27a75d02e90 (diff)
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.
-rw-r--r--src/glx/dri2.c3
-rw-r--r--src/glx/dri2_glx.c40
-rw-r--r--src/glx/glxclient.h2
3 files changed, 42 insertions, 3 deletions
diff --git a/src/glx/dri2.c b/src/glx/dri2.c
index dbf3420892b..ab530baf0f6 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 d4747388e30..04d900c2e55 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 49f31a16fec..ef46a399281 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 *);