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>
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user