From 86ca6baee221fc691c7828b078008314ac989864 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 16 Apr 2010 05:55:32 -0400 Subject: glx: Track GLX 1.3 style GLX drawables under their X drawable ID as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Michel Dänzer Signed-off-by: Keith Packard (cherry picked from commit f0006aa58f6cf7552a239e169ff6e7e4fda532f4) --- glx/glxcmds.c | 12 ++++++++++++ glx/glxext.c | 11 +++++++++++ 2 files changed, 23 insertions(+) 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; -- cgit v1.2.3