Mesa (master): glx: Move context destroy to context vtable

Kristian Høgsberg krh at kemper.freedesktop.org
Sat Jul 24 02:07:11 UTC 2010


Module: Mesa
Branch: master
Commit: c796bb0cc3fde409545bff320540ddf5c029e513
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c796bb0cc3fde409545bff320540ddf5c029e513

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Jul 22 23:45:18 2010 -0400

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 ae5bf53..02c0f9f 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 352d833..ff7ca5e 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 0ad7391..c971de2 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 8112c01..20c4529 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 8ee9a99..72ac3ec 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 0bf6177..e8649b6 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 88e74c2..97149df 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);




More information about the mesa-commit mailing list