summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2010-04-16 05:55:32 -0400
committerKeith Packard <keithp@keithp.com>2010-04-16 14:53:17 -0700
commitf0006aa58f6cf7552a239e169ff6e7e4fda532f4 (patch)
treeb92379ee09aacae2aa7146e46049a4b69b1bb01c
parente424d5812300e82de375d83dc0b490a76d865016 (diff)
glx: Track GLX 1.3 style GLX drawables under their X drawable ID as well
This ensures that the DrawableGone callback gets called as necessary when the X drawable goes away. Otherwise, using a GLX drawable (say, glXSwapBuffers) in indirect mode after the X drawable has been destroyed will crash the server. Signed-off-by: Kristian Høgsberg <krh@bitplanet.net> Reviewed-by: Michel Dänzer <michel@daenzer.net> Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--glx/glxcmds.c12
-rw-r--r--glx/glxext.c11
2 files changed, 23 insertions, 0 deletions
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 77afbf4b1..04c6d40df 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -161,7 +161,11 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
return FALSE;
}
+ /* If the ID of the glx drawable we looked up doesn't match the id
+ * we looked for, it's because we looked it up under the X
+ * drawable ID (see DoCreateGLXDrawable). */
if (rc == BadValue ||
+ (*drawable)->drawId != id ||
(type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
client->errorValue = id;
switch (type) {
@@ -1128,6 +1132,14 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf
return BadAlloc;
}
+ /* Add the glx drawable under the XID of the underlying X drawable
+ * too. That way we'll get a callback in DrawableGone and can
+ * clean up properly when the drawable is destroyed. */
+ if (!AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) {
+ pGlxDraw->destroy (pGlxDraw);
+ return BadAlloc;
+ }
+
return Success;
}
diff --git a/glx/glxext.c b/glx/glxext.c
index 59bcfbed2..89e58b0b0 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -126,6 +126,17 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
{
__GLXcontext *c;
+ /* If this drawable was created using glx 1.3 drawable
+ * constructors, we added it as a glx drawable resource under both
+ * its glx drawable ID and it X drawable ID. Remove the other
+ * resource now so we don't a callback for freed memory. */
+ if (glxPriv->drawId != glxPriv->pDraw->id) {
+ if (xid == glxPriv->drawId)
+ FreeResourceByType(glxPriv->pDraw->id, __glXDrawableRes, TRUE);
+ else
+ FreeResourceByType(glxPriv->drawId, __glXDrawableRes, TRUE);
+ }
+
for (c = glxAllContexts; c; c = c->next) {
if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
int i;