From 4dbd13cb3f5aeff6ddc85fd091b4677369c19778 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 7 Dec 2011 13:31:27 -0800 Subject: [PATCH] glx: Send DestroyContext protocol at the correct times Send the DestroyContext protocol immediately when glXDestroyContext is called, and never call it when glXFreeContextEXT is called. In both cases, either destroy the client-side structures or, if the context is current, set xid to None so that the client-side structures will be destroyed later. I believe this restores the behavior of the original SGI code. See src/glx/x11 around commit 5df82c8. The spec doesn't say anything about glXDestroyContext not really destroying imported contexts (it acts like glXFreeContextEXT instead), but that's what the original code did. Note that glXFreeContextEXT on a non-imported context does not destroy it either. Fixes the piglit test glx-free-context. NOTE: This is a candidate for the 7.11 branch. Signed-off-by: Ian Romanick Reviewed-by: Adam Jackson Reviewed-by: Eric Anholt --- src/glx/dri2_glx.c | 3 --- src/glx/dri_glx.c | 3 --- src/glx/drisw_glx.c | 3 --- src/glx/glxclient.h | 3 --- src/glx/glxcmds.c | 42 +++++++++++++++++++++++++++++++----------- src/glx/indirect_glx.c | 3 --- 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index f929fddcf65..a9bcebf9b5d 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -120,9 +120,6 @@ dri2_destroy_context(struct glx_context *context) driReleaseDrawables(&pcp->base); - if (context->xid) - glx_send_destroy_context(psc->base.dpy, context->xid); - if (context->extensions) XFree((char *) context->extensions); diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 9365224a696..3c14ef05fff 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -516,9 +516,6 @@ dri_destroy_context(struct glx_context * context) driReleaseDrawables(&pcp->base); - if (context->xid) - glx_send_destroy_context(psc->base.dpy, context->xid); - if (context->extensions) XFree((char *) context->extensions); diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 801ac7d470b..204879efeca 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -253,9 +253,6 @@ drisw_destroy_context(struct glx_context *context) driReleaseDrawables(&pcp->base); - if (context->xid) - glx_send_destroy_context(psc->base.dpy, context->xid); - if (context->extensions) XFree((char *) context->extensions); diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index f9154266101..109206f6ba0 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -227,9 +227,6 @@ struct glx_context_vtable { void * (*get_proc_address)(const char *symbol); }; -extern void -glx_send_destroy_context(Display *dpy, XID xid); - /** * GLX state that needs to be kept on the client. One of these records * exist for each context that has been made current by this client. diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index f2c1884b8a5..4f99023172d 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -381,7 +381,7 @@ glXCreateContext(Display * dpy, XVisualInfo * vis, X_GLXCreateContext, renderType, vis->screen); } -_X_HIDDEN void +static void glx_send_destroy_context(Display *dpy, XID xid) { CARD8 opcode = __glXSetupForCommand(dpy); @@ -405,25 +405,24 @@ glXDestroyContext(Display * dpy, GLXContext ctx) { struct glx_context *gc = (struct glx_context *) ctx; - if (!gc) + if (gc == NULL || gc->xid == None) return; __glXLock(); + if (!gc->imported) + glx_send_destroy_context(dpy, gc->xid); + if (gc->currentDpy) { /* This context is bound to some thread. According to the man page, * we should not actually delete the context until it's unbound. * Note that we set gc->xid = None above. In MakeContextCurrent() * we check for that and delete the context there. */ - if (!gc->imported) - glx_send_destroy_context(dpy, gc->xid); gc->xid = None; - __glXUnlock(); - return; + } else { + gc->vtable->destroy(gc); } __glXUnlock(); - - gc->vtable->destroy(gc); } /* @@ -1566,9 +1565,30 @@ _X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user) return (ctx == NULL) ? None : ctx->xid; } -_X_EXPORT -GLX_ALIAS_VOID(glXFreeContextEXT, (Display *dpy, GLXContext ctx), (dpy, ctx), - glXDestroyContext); +_X_EXPORT void +glXFreeContextEXT(Display *dpy, GLXContext ctx) +{ + struct glx_context *gc = (struct glx_context *) ctx; + + if (gc == NULL || gc->xid == None) + return; + + /* The GLX_EXT_import_context spec says: + * + * "glXFreeContext does not free the server-side context information or + * the XID associated with the server-side context." + * + * Don't send any protocol. Just destroy the client-side tracking of the + * context. Also, only release the context structure if it's not current. + */ + __glXLock(); + if (gc->currentDpy) { + gc->xid = None; + } else { + gc->vtable->destroy(gc); + } + __glXUnlock(); +} _X_EXPORT GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c index 7b542dd159c..17689d45f23 100644 --- a/src/glx/indirect_glx.c +++ b/src/glx/indirect_glx.c @@ -43,9 +43,6 @@ static struct _glapi_table *IndirectAPI = NULL; static void indirect_destroy_context(struct glx_context *gc) { - if (!gc->imported && gc->xid) - glx_send_destroy_context(gc->psc->dpy, gc->xid); - __glXFreeVertexArrayState(gc); if (gc->vendor) -- 2.30.2