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>
This commit is contained in:
parent
e424d58123
commit
f0006aa58f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
11
glx/glxext.c
11
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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user