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 | 13 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.c | 28 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.h | 1 |
5 files changed, 38 insertions, 48 deletions
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index fe1e38cb0..e9350e380 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -165,7 +165,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) {
@@ -1101,14 +1105,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
@@ -1117,8 +1113,6 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *conf {
__GLXdrawable *pGlxDraw;
- LEGAL_NEW_RESOURCE(glxDrawableId, client);
-
if (pGlxScreen->pScreen != pDraw->pScreen)
return BadMatch;
@@ -1132,6 +1126,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;
}
@@ -1142,6 +1145,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;
@@ -1155,9 +1160,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;
}
@@ -1298,6 +1300,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))
@@ -1308,6 +1312,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);
}
@@ -1415,6 +1426,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 c1fedf3b9..53838077a 100644 --- a/xorg-server/glx/glxext.c +++ b/xorg-server/glx/glxext.c @@ -131,8 +131,19 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) __GLXcontext *c; __GLXcontext *cnext; + /* 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 = cnext) { - cnext=c->next; /* Safe because c is going to be freed */ + cnext=c->next; /* Save because c is going to be freed */ 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 5f9b072b7..1462a0ad5 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -219,7 +219,6 @@ glxCloseScreen (int index, ScreenPtr pScreen) __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
pScreen->CloseScreen = pGlxScreen->CloseScreen;
- pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
pGlxScreen->destroy(pGlxScreen);
@@ -351,31 +350,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;
@@ -398,8 +372,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); }; |