diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2011-12-07 13:31:27 -0800 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2011-12-19 14:55:31 -0800 |
commit | 4dbd13cb3f5aeff6ddc85fd091b4677369c19778 (patch) | |
tree | 6386f735fdd356d300ae5bde2a6971e587e32a82 /src | |
parent | 3b9b42250ca9f0da6e979afc047d1c8524466076 (diff) |
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 <ian.d.romanick@intel.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/glx/dri2_glx.c | 3 | ||||
-rw-r--r-- | src/glx/dri_glx.c | 3 | ||||
-rw-r--r-- | src/glx/drisw_glx.c | 3 | ||||
-rw-r--r-- | src/glx/glxclient.h | 3 | ||||
-rw-r--r-- | src/glx/glxcmds.c | 42 | ||||
-rw-r--r-- | 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 f929fddcf6..a9bcebf9b5 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 9365224a69..3c14ef05ff 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 801ac7d470..204879efec 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 f915426610..109206f6ba 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 f2c1884b8a..4f99023172 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 7b542dd159..17689d45f2 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) |