glx: Move context destroy to context vtable

This commit is contained in:
Kristian Høgsberg 2010-07-22 23:45:18 -04:00
parent 80b331c7f6
commit c796bb0cc3
7 changed files with 83 additions and 105 deletions

View file

@ -114,11 +114,18 @@ struct dri2_drawable
static const struct glx_context_vtable dri2_context_vtable;
static void
dri2DestroyContext(__GLXcontext *context)
dri2_destroy_context(__GLXcontext *context)
{
struct dri2_context *pcp = (struct dri2_context *) context;
struct dri2_screen *psc = (struct dri2_screen *) context->psc;
glx_send_destroy_context(psc->base.dpy, context->xid);
if (context->extensions)
XFree((char *) context->extensions);
GarbageCollectDRIDrawables(context->psc);
(*psc->core->destroyContext) (pcp->driContext);
Xfree(pcp);
@ -182,7 +189,6 @@ dri2CreateContext(__GLXscreenConfigs *base,
pcp->base.vtable = &dri2_context_vtable;
pcp->base.driContext = &pcp->dri_vtable;
pcp->dri_vtable.destroyContext = dri2DestroyContext;
pcp->dri_vtable.bindContext = dri2BindContext;
pcp->dri_vtable.unbindContext = dri2UnbindContext;
@ -675,6 +681,7 @@ dri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
}
static const struct glx_context_vtable dri2_context_vtable = {
dri2_destroy_context,
dri2_wait_gl,
dri2_wait_x,
DRI_glXUseXFont,

View file

@ -92,13 +92,7 @@ struct dri_drawable
__DRIdrawable *driDrawable;
};
static const struct glx_context_vtable dri_context_vtable = {
NULL,
NULL,
DRI_glXUseXFont,
NULL,
NULL,
};
static const struct glx_context_vtable dri_context_vtable;
/*
* Given a display pointer and screen number, determine the name of
@ -506,11 +500,18 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
}
static void
driDestroyContext(__GLXcontext * context)
dri_destroy_context(__GLXcontext * context)
{
struct dri_context *pcp = (struct dri_context *) context;
struct dri_screen *psc = (struct dri_screen *) context->psc;
glx_send_destroy_context(psc->base.dpy, context->xid);
if (context->extensions)
XFree((char *) context->extensions);
GarbageCollectDRIDrawables(context->psc);
(*psc->core->destroyContext) (pcp->driContext);
XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
@ -539,6 +540,15 @@ driUnbindContext(__GLXcontext * context)
(*psc->core->unbindContext) (pcp->driContext);
}
static const struct glx_context_vtable dri_context_vtable = {
dri_destroy_context,
NULL,
NULL,
DRI_glXUseXFont,
NULL,
NULL,
};
static __GLXcontext *
driCreateContext(__GLXscreenConfigs *base,
const __GLcontextModes * mode,
@ -587,7 +597,6 @@ driCreateContext(__GLXscreenConfigs *base,
pcp->base.vtable = &dri_context_vtable;
pcp->base.driContext = &pcp->dri_vtable;
pcp->dri_vtable.destroyContext = driDestroyContext;
pcp->dri_vtable.bindContext = driBindContext;
pcp->dri_vtable.unbindContext = driUnbindContext;

View file

@ -240,11 +240,18 @@ static const __DRIextension *loader_extensions[] = {
*/
static void
driDestroyContext(__GLXcontext *context)
drisw_destroy_context(__GLXcontext *context)
{
struct drisw_context *pcp = (struct drisw_context *) context;
struct drisw_screen *psc = (struct drisw_screen *) context->psc;
glx_send_destroy_context(psc->base.dpy, context->xid);
if (context->extensions)
XFree((char *) context->extensions);
GarbageCollectDRIDrawables(context->psc);
(*psc->core->destroyContext) (pcp->driContext);
Xfree(pcp);
@ -273,6 +280,7 @@ driUnbindContext(__GLXcontext * context)
}
static const struct glx_context_vtable drisw_context_vtable = {
drisw_destroy_context,
NULL,
NULL,
DRI_glXUseXFont,
@ -318,7 +326,6 @@ driCreateContext(__GLXscreenConfigs *base,
pcp->base.vtable = &drisw_context_vtable;
pcp->base.driContext = &pcp->dri_vtable;
pcp->dri_vtable.destroyContext = driDestroyContext;
pcp->dri_vtable.bindContext = driBindContext;
pcp->dri_vtable.unbindContext = driUnbindContext;

View file

@ -153,7 +153,6 @@ struct __GLXDRIscreenRec {
struct __GLXDRIcontextRec
{
void (*destroyContext) (__GLXcontext *context);
Bool(*bindContext) (__GLXcontext *context, __GLXDRIdrawable *pdraw,
__GLXDRIdrawable *pread);
void (*unbindContext) (__GLXcontext *context);
@ -241,6 +240,7 @@ typedef struct __GLXattributeMachineRec
} __GLXattributeMachine;
struct glx_context_vtable {
void (*destroy)(__GLXcontext *ctx);
void (*wait_gl)(__GLXcontext *ctx);
void (*wait_x)(__GLXcontext *ctx);
void (*use_x_font)(__GLXcontext *ctx,
@ -252,6 +252,9 @@ struct glx_context_vtable {
};
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.
@ -660,8 +663,6 @@ extern __GLXcontext *__glXcurrentContext;
extern void __glXSetCurrentContextNull(void);
extern void __glXFreeContext(__GLXcontext *);
/*
** Global lock for all threads in this address space using the GLX
@ -790,6 +791,9 @@ __glxGetMscRate(__GLXDRIdrawable *glxDraw,
* glx_info->codes->first_event */
XExtDisplayInfo *__glXFindDisplay (Display *dpy);
extern void
GarbageCollectDRIDrawables(__GLXscreenConfigs *psc);
extern __GLXDRIdrawable *
GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable);

View file

@ -85,7 +85,7 @@ windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr)
* \param dpy Display to destroy drawables for
* \param screen Screen number to destroy drawables for
*/
static void
_X_HIDDEN void
GarbageCollectDRIDrawables(__GLXscreenConfigs * sc)
{
XID draw;
@ -480,7 +480,7 @@ CreateContext(Display * dpy, int generic_id,
shareList ? shareList->driContext : NULL,
&errorcode, &x11error)) {
__glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
__glXFreeContext(gc);
gc->vtable->destroy(gc);
return NULL;
}
@ -524,8 +524,28 @@ glXCreateContext(Display * dpy, XVisualInfo * vis,
}
_X_HIDDEN void
__glXFreeContext(__GLXcontext * gc)
glx_send_destroy_context(Display *dpy, XID xid)
{
CARD8 opcode = __glXSetupForCommand(dpy);
xGLXDestroyContextReq *req;
LockDisplay(dpy);
GetReq(GLXDestroyContext, req);
req->reqType = opcode;
req->glxCode = X_GLXDestroyContext;
req->context = xid;
UnlockDisplay(dpy);
SyncHandle();
}
static void
indirect_destroy_context(__GLXcontext *gc)
{
if (!gc->imported)
glx_send_destroy_context(gc->psc->dpy, gc->xid);
__glXFreeVertexArrayState(gc);
if (gc->vendor)
XFree((char *) gc->vendor);
if (gc->renderer)
@ -538,7 +558,6 @@ __glXFreeContext(__GLXcontext * gc)
XFree((char *) gc->buf);
Xfree((char *) gc->client_state_private);
XFree((char *) gc);
}
/*
@ -547,81 +566,24 @@ __glXFreeContext(__GLXcontext * gc)
static void
DestroyContext(Display * dpy, GLXContext gc)
{
#ifndef GLX_USE_APPLEGL /* TODO: darwin: indirect */
xGLXDestroyContextReq *req;
GLXContextID xid;
CARD8 opcode;
GLboolean imported;
opcode = __glXSetupForCommand(dpy);
if (!opcode || !gc) {
if (!gc)
return;
}
__glXLock();
xid = gc->xid;
imported = gc->imported;
gc->xid = None;
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.
*/
gc->xid = None;
__glXUnlock();
return;
}
__glXUnlock();
#if defined(GLX_DIRECT_RENDERING)
/* Destroy the direct rendering context */
if (gc->driContext) {
GarbageCollectDRIDrawables(gc->psc);
if (gc->extensions)
XFree((char *) gc->extensions);
(*gc->driContext->destroyContext) (gc);
}
else
#endif
{
__glXFreeVertexArrayState(gc);
__glXFreeContext(gc);
}
if (!imported) {
/*
** This dpy also created the server side part of the context.
** Send the glXDestroyContext request.
*/
LockDisplay(dpy);
GetReq(GLXDestroyContext, req);
req->reqType = opcode;
req->glxCode = X_GLXDestroyContext;
req->context = xid;
UnlockDisplay(dpy);
SyncHandle();
}
#else
__glXLock();
if (gc->currentDpy) {
/*
* Set the Bool that indicates that we should destroy this GLX context
* when the context is no longer current.
*/
gc->do_destroy = True;
/* Have to free later cuz it's in use now */
__glXUnlock();
}
else {
/* Destroy the handle if not current to anybody */
__glXUnlock();
if(gc->driContext)
apple_glx_destroy_context(&gc->driContext, dpy);
__glXFreeContext(gc);
}
#endif
if (gc->vtable->destroy)
gc->vtable->destroy(gc);
}
PUBLIC void
@ -758,6 +720,12 @@ indirect_use_x_font(__GLXcontext *gc,
#ifdef GLX_USE_APPLEGL
static void
applegl_destroy_context(__GLXcontext *gc)
{
apple_glx_destroy_context(&gc->driContext, gc->currentDpy);
}
static void
applegl_wait_gl(__GLXcontext *gc)
{
@ -771,6 +739,7 @@ applegl_wait_x(__GLXcontext *gc)
}
static const struct glx_context_vtable applegl_context_vtable = {
applegl_destroy_context,
applegl_wait_gl,
applegl_wait_x,
DRI_glXUseXFont,
@ -1857,7 +1826,7 @@ glXImportContextEXT(Display * dpy, GLXContextID contextID)
ctx->imported = GL_TRUE;
if (Success != __glXQueryContextInfo(dpy, ctx)) {
__glXFreeContext(ctx);
ctx->vtable->destroy(ctx);
ctx = NULL;
}
}
@ -2773,6 +2742,7 @@ indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
}
static const struct glx_context_vtable indirect_context_vtable = {
indirect_destroy_context,
indirect_wait_gl,
indirect_wait_x,
indirect_use_x_font,

View file

@ -468,32 +468,13 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
oldGC->currentReadable = None;
oldGC->currentContextTag = 0;
oldGC->thread_id = 0;
#ifdef GLX_USE_APPLEGL
/*
* At this point we should check if the context has been
* through glXDestroyContext, and redestroy it if so.
*/
if(oldGC->do_destroy) {
__glXUnlock();
/* glXDestroyContext uses the same global lock. */
glXDestroyContext(dpy, oldGC);
__glXLock();
#else
if (oldGC->xid == None) {
/* We are switching away from a context that was
* previously destroyed, so we need to free the memory
* for the old handle.
*/
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
/* Destroy the old direct rendering context */
if (oldGC->driContext) {
oldGC->driContext->destroyContext(oldGC);
oldGC->driContext = NULL;
}
#endif
__glXFreeContext(oldGC);
#endif /* GLX_USE_APPLEGL */
oldGC->vtable->destroy(oldGC);
}
}
if (gc) {

View file

@ -263,8 +263,8 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes)
gc = __glXGetCurrentContext();
if (dpy == gc->currentDpy) {
gc->vtable->destroy(gc);
__glXSetCurrentContextNull();
__glXFreeContext(gc);
}
FreeScreenConfigs(priv);