From c796bb0cc3fde409545bff320540ddf5c029e513 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 22 Jul 2010 23:45:18 -0400 Subject: [PATCH] glx: Move context destroy to context vtable --- src/glx/dri2_glx.c | 11 +++++- src/glx/dri_glx.c | 27 ++++++++----- src/glx/drisw_glx.c | 11 +++++- src/glx/glxclient.h | 10 +++-- src/glx/glxcmds.c | 104 ++++++++++++++++++--------------------------------- src/glx/glxcurrent.c | 23 +----------- src/glx/glxext.c | 2 +- 7 files changed, 83 insertions(+), 105 deletions(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index ae5bf535afb..02c0f9f24ee 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -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, diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 352d833fd7d..ff7ca5ef7d6 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -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; diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 0ad73914575..c971de2f76f 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -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; diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 8112c01e7cc..20c45291315 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -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); diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 8ee9a999e4a..72ac3ecd7d7 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -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 @@ -759,6 +721,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) { glFinish(); @@ -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, diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index 0bf61779c4a..e8649b67655 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -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) { diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 88e74c2a386..97149dff702 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -263,8 +263,8 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes) gc = __glXGetCurrentContext(); if (dpy == gc->currentDpy) { + gc->vtable->destroy(gc); __glXSetCurrentContextNull(); - __glXFreeContext(gc); } FreeScreenConfigs(priv); -- 2.11.0