glx: Move context destroy to context vtable
authorKristian Høgsberg <krh@bitplanet.net>
Fri, 23 Jul 2010 03:45:18 +0000 (23:45 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Sat, 24 Jul 2010 02:05:52 +0000 (22:05 -0400)
src/glx/dri2_glx.c
src/glx/dri_glx.c
src/glx/drisw_glx.c
src/glx/glxclient.h
src/glx/glxcmds.c
src/glx/glxcurrent.c
src/glx/glxext.c

index ae5bf535afb35b50c00e296b4c96c164b2b58ec9..02c0f9f24eec084eda7ac4228d511d141660ecf1 100644 (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,
index 352d833fd7d6b577e1a5180a7ba126ae7f5b434d..ff7ca5ef7d6b9b48a7bb6d02b145983217c66956 100644 (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;
 
index 0ad73914575013801311d47c18985defaaa7fc63..c971de2f76fb52e09c366a9d317f60e4480aebd6 100644 (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;
 
index 8112c01e7cc53dd4214797ec844cad3f19f4f0c0..20c452913152ff9e964ccb7982dd39973cc61f94 100644 (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);
 
index 8ee9a999e4aacbfea4f8642caf85ee9fb810d161..72ac3ecd7d7fc38b30f4020c83f60514c7eb427a 100644 (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,
index 0bf61779c4a1dda7d162a584d2b26c413645bb7e..e8649b67655ff6a91fd6456c371b50233f4be227 100644 (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) {
index 88e74c2a3862aeadc9e9bcd2ad8b4775ae7ec9d5..97149dff7022900c5f21bf18e79ffd0660605026 100644 (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);