summaryrefslogtreecommitdiff
path: root/glx/glxcmds.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-04-09 13:16:37 -0400
committerKristian Høgsberg <krh@redhat.com>2009-04-13 13:17:53 -0400
commit7b6400a1b8d2f228fcbedf17c30a7e3924e4dd2a (patch)
tree81755c27fb2cc6997c9ba3997ca1e42d3cd133e4 /glx/glxcmds.c
parent140463a197fb93d0a4bfad924efc35b860e8cc54 (diff)
glx: Fix drawable private leak on destroy
When a drawable goes away, we don't destroy the GLX drawable in full, since it may be current for a context. This means that when the drawable is destroyed in full later, the backend doesn't get a chance to destroy resources associated with the drawable (the DRI2Drawable). With this patch, we destroy the GLX drawable in full when it goes away and then track down all contexts that reference it and NULL their pointers.
Diffstat (limited to 'glx/glxcmds.c')
-rw-r--r--glx/glxcmds.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index e21f0f098..86e8dd8a5 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -193,18 +193,9 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
void
__glXContextDestroy(__GLXcontext *context)
{
- if (!context->isDirect) {
- if (context->drawPriv)
- __glXUnrefDrawable(context->drawPriv);
- if (context->readPriv)
- __glXUnrefDrawable(context->readPriv);
- context->drawPriv = NULL;
- context->readPriv = NULL;
- }
__glXFlushContextCache();
}
-
static void __glXdirectContextDestroy(__GLXcontext *context)
{
__glXContextDestroy(context);
@@ -320,6 +311,8 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
glxc->isDirect = isDirect;
glxc->renderMode = GL_RENDER;
+ __glXAddToContextList(glxc);
+
return Success;
}
@@ -639,10 +632,6 @@ DoMakeCurrent(__GLXclientState *cl,
}
__glXFlushContextCache();
if (!prevglxc->isDirect) {
- if (prevglxc->drawPriv)
- __glXUnrefDrawable(prevglxc->drawPriv);
- if (prevglxc->readPriv)
- __glXUnrefDrawable(prevglxc->readPriv);
prevglxc->drawPriv = NULL;
prevglxc->readPriv = NULL;
}
@@ -662,8 +651,6 @@ DoMakeCurrent(__GLXclientState *cl,
}
glxc->isCurrent = GL_TRUE;
- __glXRefDrawable(glxc->drawPriv);
- __glXRefDrawable(glxc->readPriv);
}
if (prevglxc) {
@@ -1090,6 +1077,33 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
return DoGetFBConfigs(cl, req->screen);
}
+GLboolean
+__glXDrawableInit(__GLXdrawable *drawable,
+ __GLXscreen *screen, DrawablePtr pDraw, int type,
+ XID drawId, __GLXconfig *config)
+{
+ drawable->pDraw = pDraw;
+ drawable->type = type;
+ drawable->drawId = drawId;
+ drawable->config = config;
+ drawable->eventMask = 0;
+
+ return GL_TRUE;
+}
+
+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
DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
DrawablePtr pDraw, XID glxDrawableId, int type)