aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/glx
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/glx')
-rw-r--r--xorg-server/glx/glxcmds.c39
-rw-r--r--xorg-server/glx/glxdri2.c5
-rw-r--r--xorg-server/glx/glxext.c13
-rw-r--r--xorg-server/glx/glxscreens.c28
-rw-r--r--xorg-server/glx/glxscreens.h1
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);
};