diff options
Diffstat (limited to 'xorg-server/glx')
-rw-r--r-- | xorg-server/glx/glxcmds.c | 39 | ||||
-rw-r--r-- | xorg-server/glx/glxdri2.c | 5 | ||||
-rw-r--r-- | xorg-server/glx/glxext.c | 11 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.c | 28 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.h | 1 |
5 files changed, 37 insertions, 47 deletions
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index 77afbf4b1..087d52ec2 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/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) { @@ -1097,14 +1101,6 @@ __glXDrawableInit(__GLXdrawable *drawable, void __glXDrawableRelease(__GLXdrawable *drawable) { - ScreenPtr pScreen = drawable->pDraw->pScreen; - - switch (drawable->type) { - case GLX_DRAWABLE_PIXMAP: - case GLX_DRAWABLE_PBUFFER: - (*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw); - break; - } } static int @@ -1113,8 +1109,6 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf { __GLXdrawable *pGlxDraw; - LEGAL_NEW_RESOURCE(glxDrawableId, client); - if (pGlxScreen->pScreen != pDraw->pScreen) return BadMatch; @@ -1128,6 +1122,15 @@ 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 (pDraw->id != glxDrawableId && + !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) { + pGlxDraw->destroy (pGlxDraw); + return BadAlloc; + } + return Success; } @@ -1138,6 +1141,8 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config DrawablePtr pDraw; int err; + LEGAL_NEW_RESOURCE(glxDrawableId, client); + err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); if (err != Success) { client->errorValue = drawableId; @@ -1151,9 +1156,6 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, glxDrawableId, GLX_DRAWABLE_PIXMAP); - if (err == Success) - ((PixmapPtr) pDraw)->refcnt++; - return err; } @@ -1294,6 +1296,8 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, PixmapPtr pPixmap; int err; + LEGAL_NEW_RESOURCE(glxDrawableId, client); + if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) @@ -1304,6 +1308,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, width, height, config->rgbBits, 0); __glXleaveServer(GL_FALSE); + /* Assign the pixmap the same id as the pbuffer and add it as a + * resource so it and the DRI2 drawable will be reclaimed when the + * pbuffer is destroyed. */ + pPixmap->drawable.id = glxDrawableId; + if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap)) + return BadAlloc; + return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, glxDrawableId, GLX_DRAWABLE_PBUFFER); } @@ -1411,6 +1422,8 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) DrawablePtr pDraw; int err; + LEGAL_NEW_RESOURCE(req->glxwindow, client); + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) return err; if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c index 4c9f381c6..74d6ebc5d 100644 --- a/xorg-server/glx/glxdri2.c +++ b/xorg-server/glx/glxdri2.c @@ -105,11 +105,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable) (*core->destroyDrawable)(private->driDrawable); - /* If the X window was destroyed, the dri DestroyWindow hook will - * aready have taken care of this, so only call if pDraw isn't NULL. */ - if (drawable->pDraw != NULL) - DRI2DestroyDrawable(drawable->pDraw); - __glXDrawableRelease(drawable); xfree(private); diff --git a/xorg-server/glx/glxext.c b/xorg-server/glx/glxext.c index 59bcfbed2..89e58b0b0 100644 --- a/xorg-server/glx/glxext.c +++ b/xorg-server/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; diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c index a9b1b7955..3d3c23feb 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -215,7 +215,6 @@ glxCloseScreen (int index, ScreenPtr pScreen) __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
pScreen->CloseScreen = pGlxScreen->CloseScreen;
- pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
pGlxScreen->destroy(pGlxScreen);
@@ -347,31 +346,6 @@ pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual) return best;
}
-static Bool
-glxDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
- Bool retval = TRUE;
-
- FreeResource(pWin->drawable.id, FALSE);
-
- /* call lower wrapped functions */
- if (pGlxScreen->DestroyWindow) {
- /* unwrap */
- pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
-
- /* call lower layers */
- retval = (*pScreen->DestroyWindow)(pWin);
-
- /* rewrap */
- pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = glxDestroyWindow;
- }
-
- return retval;
-}
-
void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
{
__GLXconfig *m;
@@ -394,8 +368,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) pGlxScreen->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = glxCloseScreen;
- pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = glxDestroyWindow;
i = 0;
for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
diff --git a/xorg-server/glx/glxscreens.h b/xorg-server/glx/glxscreens.h index bff436307..d52099fc2 100644 --- a/xorg-server/glx/glxscreens.h +++ b/xorg-server/glx/glxscreens.h @@ -173,7 +173,6 @@ struct __GLXscreen { /*@}*/ Bool (*CloseScreen)(int index, ScreenPtr pScreen); - Bool (*DestroyWindow)(WindowPtr pWindow); }; |