glx: Allocate the __GLXcontext in the DRI drivers
authorKristian Høgsberg <krh@bitplanet.net>
Fri, 23 Jul 2010 01:24:14 +0000 (21:24 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 23 Jul 2010 02:16:32 +0000 (22:16 -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

index 6ce5ae6fc9c3adedf9fa0643630e930300578d12..778607dd1c318992a01f9853fcb844f9304a5fe6 100644 (file)
@@ -94,9 +94,9 @@ struct dri2_screen {
 
 struct dri2_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
-   __GLXscreenConfigs *psc;
 };
 
 struct dri2_drawable
@@ -111,12 +111,13 @@ struct dri2_drawable
    int swap_interval;
 };
 
+static const struct glx_context_vtable dri2_context_vtable;
+
 static void
-dri2DestroyContext(__GLXDRIcontext *context,
-                  __GLXscreenConfigs *base, Display *dpy)
+dri2DestroyContext(__GLXcontext *context)
 {
    struct dri2_context *pcp = (struct dri2_context *) context;
-   struct dri2_screen *psc = (struct dri2_screen *) base;
+   struct dri2_screen *psc = (struct dri2_screen *) context->psc;
 
    (*psc->core->destroyContext) (pcp->driContext);
 
@@ -124,11 +125,11 @@ dri2DestroyContext(__GLXDRIcontext *context,
 }
 
 static Bool
-dri2BindContext(__GLXDRIcontext *context,
+dri2BindContext(__GLXcontext *context,
                __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
 {
    struct dri2_context *pcp = (struct dri2_context *) context;
-   struct dri2_screen *psc = (struct dri2_screen *) pcp->psc;
+   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
    struct dri2_drawable *pdr = (struct dri2_drawable *) draw;
    struct dri2_drawable *prd = (struct dri2_drawable *) read;
 
@@ -137,18 +138,18 @@ dri2BindContext(__GLXDRIcontext *context,
 }
 
 static void
-dri2UnbindContext(__GLXDRIcontext *context)
+dri2UnbindContext(__GLXcontext *context)
 {
    struct dri2_context *pcp = (struct dri2_context *) context;
-   struct dri2_screen *psc = (struct dri2_screen *) pcp->psc;
+   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
 
    (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
+static __GLXcontext *
 dri2CreateContext(__GLXscreenConfigs *base,
                   const __GLcontextModes * mode,
-                  GLXContext gc, GLXContext shareList, int renderType)
+                  GLXContext shareList, int renderType)
 {
    struct dri2_context *pcp, *pcp_shared;
    struct dri2_screen *psc = (struct dri2_screen *) base;
@@ -164,7 +165,12 @@ dri2CreateContext(__GLXscreenConfigs *base,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = &psc->base;
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
    pcp->driContext =
       (*psc->dri2->createNewContext) (psc->driScreen,
                                       config->driConfig, shared, pcp);
@@ -174,9 +180,11 @@ dri2CreateContext(__GLXscreenConfigs *base,
       return NULL;
    }
 
-   pcp->base.destroyContext = dri2DestroyContext;
-   pcp->base.bindContext = dri2BindContext;
-   pcp->base.unbindContext = dri2UnbindContext;
+   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;
 
    return &pcp->base;
 }
@@ -826,8 +834,6 @@ dri2CreateScreen(int screen, __GLXdisplayPrivate * priv)
    psp->copySubBuffer = dri2CopySubBuffer;
    __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
 
-   psc->base.direct_context_vtable = &dri2_context_vtable;
-
    Xfree(driverName);
    Xfree(deviceName);
 
index 369d07a27fe2894c5415edbbb3ef400e97ee6a22..959fc7425a408214fb1d2d59d833ab02316a9b38 100644 (file)
@@ -78,7 +78,8 @@ struct dri_screen
 
 struct dri_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
    XID hwContextID;
    __GLXscreenConfigs *psc;
@@ -91,6 +92,11 @@ struct dri_drawable
    __DRIdrawable *driDrawable;
 };
 
+static const struct glx_context_vtable dri_context_vtable = {
+   NULL,
+   NULL,
+};
+
 /*
  * Given a display pointer and screen number, determine the name of
  * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
@@ -497,11 +503,10 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
 }
 
 static void
-driDestroyContext(__GLXDRIcontext * context,
-                  __GLXscreenConfigs *base, Display * dpy)
+driDestroyContext(__GLXcontext * context)
 {
    struct dri_context *pcp = (struct dri_context *) context;
-   struct dri_screen *psc = (struct dri_screen *) base;
+   struct dri_screen *psc = (struct dri_screen *) context->psc;
 
    (*psc->core->destroyContext) (pcp->driContext);
 
@@ -510,7 +515,7 @@ driDestroyContext(__GLXDRIcontext * context,
 }
 
 static Bool
-driBindContext(__GLXDRIcontext *context,
+driBindContext(__GLXcontext *context,
               __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
 {
    struct dri_context *pcp = (struct dri_context *) context;
@@ -523,7 +528,7 @@ driBindContext(__GLXDRIcontext *context,
 }
 
 static void
-driUnbindContext(__GLXDRIcontext * context)
+driUnbindContext(__GLXcontext * context)
 {
    struct dri_context *pcp = (struct dri_context *) context;
    struct dri_screen *psc = (struct dri_screen *) pcp->psc;
@@ -531,10 +536,10 @@ driUnbindContext(__GLXDRIcontext * context)
    (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
+static __GLXcontext *
 driCreateContext(__GLXscreenConfigs *base,
                  const __GLcontextModes * mode,
-                 GLXContext gc, GLXContext shareList, int renderType)
+                 GLXContext shareList, int renderType)
 {
    struct dri_context *pcp, *pcp_shared;
    struct dri_screen *psc = (struct dri_screen *) base;
@@ -554,7 +559,12 @@ driCreateContext(__GLXscreenConfigs *base,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = &psc->base;
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
    if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
                                        mode->visualID,
                                        &pcp->hwContextID, &hwContext)) {
@@ -572,9 +582,11 @@ driCreateContext(__GLXscreenConfigs *base,
       return NULL;
    }
 
-   pcp->base.destroyContext = driDestroyContext;
-   pcp->base.bindContext = driBindContext;
-   pcp->base.unbindContext = driUnbindContext;
+   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;
 
    return &pcp->base;
 }
@@ -673,11 +685,6 @@ driDestroyScreen(__GLXscreenConfigs *base)
       dlclose(psc->driver);
 }
 
-static const struct glx_context_vtable dri_context_vtable = {
-   NULL,
-   NULL,
-};
-
 #ifdef __DRI_SWAP_BUFFER_COUNTER
 
 static int
@@ -884,8 +891,6 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv)
    psp->setSwapInterval = driSetSwapInterval;
    psp->getSwapInterval = driGetSwapInterval;
 
-   psc->base.direct_context_vtable = &dri_context_vtable;
-
    return &psc->base;
 }
 
index 441606106ec6b2f79deb3e8814207de0339167c7..367aa6a6f2e8e76a1c3544334235331f87148d3b 100644 (file)
@@ -35,7 +35,8 @@ struct drisw_display
 
 struct drisw_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
    __GLXscreenConfigs *psc;
 };
@@ -239,11 +240,10 @@ static const __DRIextension *loader_extensions[] = {
  */
 
 static void
-driDestroyContext(__GLXDRIcontext *context,
-                 __GLXscreenConfigs *base, Display *dpy)
+driDestroyContext(__GLXcontext *context)
 {
    struct drisw_context *pcp = (struct drisw_context *) context;
-   struct drisw_screen *psc = (struct drisw_screen *) base;
+   struct drisw_screen *psc = (struct drisw_screen *) context->psc;
 
    (*psc->core->destroyContext) (pcp->driContext);
 
@@ -251,7 +251,7 @@ driDestroyContext(__GLXDRIcontext *context,
 }
 
 static Bool
-driBindContext(__GLXDRIcontext * context,
+driBindContext(__GLXcontext * context,
               __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
 {
    struct drisw_context *pcp = (struct drisw_context *) context;
@@ -264,7 +264,7 @@ driBindContext(__GLXDRIcontext * context,
 }
 
 static void
-driUnbindContext(__GLXDRIcontext * context)
+driUnbindContext(__GLXcontext * context)
 {
    struct drisw_context *pcp = (struct drisw_context *) context;
    struct drisw_screen *psc = (struct drisw_screen *) pcp->psc;
@@ -272,10 +272,10 @@ driUnbindContext(__GLXDRIcontext * context)
    (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
+static __GLXcontext *
 driCreateContext(__GLXscreenConfigs *base,
                 const __GLcontextModes *mode,
-                GLXContext gc, GLXContext shareList, int renderType)
+                GLXContext shareList, int renderType)
 {
    struct drisw_context *pcp, *pcp_shared;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
@@ -294,7 +294,12 @@ driCreateContext(__GLXscreenConfigs *base,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = &psc->base;
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
    pcp->driContext =
       (*psc->core->createNewContext) (psc->driScreen,
                                      config->driConfig, shared, pcp);
@@ -303,9 +308,10 @@ driCreateContext(__GLXscreenConfigs *base,
       return NULL;
    }
 
-   pcp->base.destroyContext = driDestroyContext;
-   pcp->base.bindContext = driBindContext;
-   pcp->base.unbindContext = driUnbindContext;
+   pcp->base.driContext = &pcp->dri_vtable;
+   pcp->dri_vtable.destroyContext = driDestroyContext;
+   pcp->dri_vtable.bindContext = driBindContext;
+   pcp->dri_vtable.unbindContext = driUnbindContext;
 
    return &pcp->base;
 }
index 4f833057ffc304fa3caf4e4490e05abcc1f09c02..dcb75d4959f08cf32627dafe6d8d424d10b6f0f4 100644 (file)
@@ -126,10 +126,9 @@ struct __GLXDRIscreenRec {
 
    void (*destroyScreen)(__GLXscreenConfigs *psc);
 
-   __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
-                                    const __GLcontextModes *mode,
-                                    GLXContext gc,
-                                    GLXContext shareList, int renderType);
+   __GLXcontext *(*createContext)(__GLXscreenConfigs *psc,
+                                 const __GLcontextModes *mode,
+                                 GLXContext shareList, int renderType);
 
    __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
                                       XID drawable,
@@ -155,12 +154,10 @@ struct __GLXDRIscreenRec {
 
 struct __GLXDRIcontextRec
 {
-   void (*destroyContext) (__GLXDRIcontext * context,
-                           __GLXscreenConfigs * psc, Display * dpy);
-     Bool(*bindContext) (__GLXDRIcontext * context, __GLXDRIdrawable * pdraw,
-                         __GLXDRIdrawable * pread);
-
-   void (*unbindContext) (__GLXDRIcontext * context);
+   void (*destroyContext) (__GLXcontext *context);
+   Bool(*bindContext) (__GLXcontext *context, __GLXDRIdrawable *pdraw,
+                      __GLXDRIdrawable *pread);
+   void (*unbindContext) (__GLXcontext *context);
 };
 
 struct __GLXDRIdrawableRec
@@ -388,11 +385,6 @@ struct __GLXcontextRec
    GLubyte *extensions;
    /*@} */
 
-    /**
-     * Record the dpy this context was created on for later freeing
-     */
-   Display *createDpy;
-
     /**
      * Maximum small render command size.  This is the smaller of 64k and
      * the size of the above buffer.
@@ -463,6 +455,10 @@ struct __GLXcontextRec
    const struct glx_context_vtable *vtable;
 };
 
+extern Bool
+glx_context_init(__GLXcontext *gc,
+                __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig);
+
 #define __glXSetError(gc,code)  \
    if (!(gc)->error) {          \
       (gc)->error = code;       \
@@ -515,11 +511,6 @@ struct __GLXscreenConfigsRec
      */
    char *effectiveGLXexts;
 
-   /**
-    * Context vtable to use for direct contexts on this screen
-    */
-   const struct glx_context_vtable *direct_context_vtable;
-
    __GLXdisplayPrivate *display;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
index a9f6b173386b0b31b6a269df96f3cefe22564fa8..5eae5a914df71b90575470aeca6aa02c7a8143d4 100644 (file)
@@ -62,7 +62,7 @@
 
 static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
 static const char __glXGLXClientVersion[] = "1.4";
-static const struct glx_context_vtable glx_indirect_context_vtable;
+static const struct glx_context_vtable indirect_context_vtable;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 
@@ -272,6 +272,7 @@ AllocateGLXContext(Display * dpy)
    }
    memset(gc, 0, sizeof(struct __GLXcontextRec));
 
+   gc->vtable = &indirect_context_vtable;
    state = Xmalloc(sizeof(struct __GLXattributeRec));
    if (state == NULL) {
       /* Out of memory */
@@ -325,7 +326,6 @@ AllocateGLXContext(Display * dpy)
    else {
       gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
    }
-   gc->createDpy = dpy;
    gc->majorOpcode = opcode;
 
    /*
@@ -350,6 +350,22 @@ AllocateGLXContext(Display * dpy)
    return gc;
 }
 
+_X_HIDDEN Bool
+glx_context_init(__GLXcontext *gc,
+                __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig)
+{
+   gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
+   if (!gc->majorOpcode)
+      return GL_FALSE;
+
+   gc->screen = psc->scr;
+   gc->psc = psc;
+   gc->mode = fbconfig;
+   gc->isDirect = GL_TRUE;
+
+   return GL_TRUE;
+}
+
 
 /**
  * Create a new context.  Exactly one of \c vis and \c fbconfig should be
@@ -367,7 +383,7 @@ CreateContext(Display * dpy, int generic_id,
               Bool allowDirect,
              unsigned code, int renderType, int screen)
 {
-   GLXContext gc;
+   GLXContext gc = NULL;
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 #if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL)
    int errorcode;
@@ -380,28 +396,18 @@ CreateContext(Display * dpy, int generic_id,
    if (generic_id == None)
       return NULL;
 
-   gc = AllocateGLXContext(dpy);
-   if (!gc)
-      return NULL;
-
 #ifndef GLX_USE_APPLEGL  /* TODO: darwin indirect */
 #ifdef GLX_DIRECT_RENDERING
    if (allowDirect && psc->driScreen) {
-      gc->driContext = psc->driScreen->createContext(psc, fbconfig, gc,
-                                                    shareList, renderType);
-      if (gc->driContext != NULL) {
-        gc->screen = screen;
-        gc->psc = psc;
-        gc->mode = fbconfig;
-        gc->isDirect = GL_TRUE;
-      }
+      gc = psc->driScreen->createContext(psc, fbconfig,
+                                        shareList, renderType);
    }
 #endif
 
-   if (gc->driContext != NULL)
-      gc->vtable = psc->direct_context_vtable;
-   else
-      gc->vtable = &glx_indirect_context_vtable;
+   if (!gc)
+      gc = AllocateGLXContext(dpy);
+   if (!gc)
+      return NULL;
 
    LockDisplay(dpy);
    switch (code) {
@@ -570,54 +576,54 @@ DestroyContext(Display * dpy, GLXContext gc)
       return;
    }
 
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+#if defined(GLX_DIRECT_RENDERING)
    /* Destroy the direct rendering context */
    if (gc->driContext) {
-      (*gc->driContext->destroyContext) (gc->driContext, gc->psc, dpy);
-      gc->driContext = NULL;
       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();
+   }
 
-   __glXFreeVertexArrayState(gc);
 #else
-   __glXLock();
-#endif /* GLX_USE_APPLEGL */   
 
+   __glXLock();
    if (gc->currentDpy) {
-#ifdef GLX_USE_APPLEGL
       /* 
        * Set the Bool that indicates that we should destroy this GLX context
        * when the context is no longer current.
        */
       gc->do_destroy = True;
-#endif
       /* Have to free later cuz it's in use now */
       __glXUnlock();
    }
    else {
       /* Destroy the handle if not current to anybody */
       __glXUnlock();
-#ifdef GLX_USE_APPLEGL
       if(gc->driContext)
-         apple_glx_destroy_context(&gc->driContext, dpy);
-#endif
+        apple_glx_destroy_context(&gc->driContext, dpy);
       __glXFreeContext(gc);
    }
-#ifndef GLX_USE_APPLEGL
-   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();
-   }
 #endif
 }
 
@@ -2711,9 +2717,9 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
  * GLX_EXT_texture_from_pixmap
  */
 static void
-glx_indirect_bind_tex_image(Display * dpy,
-                           GLXDrawable drawable,
-                           int buffer, const int *attrib_list)
+indirect_bind_tex_image(Display * dpy,
+                       GLXDrawable drawable,
+                       int buffer, const int *attrib_list)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
@@ -2764,7 +2770,7 @@ glx_indirect_bind_tex_image(Display * dpy,
 }
 
 static void
-glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
@@ -2793,9 +2799,9 @@ glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
    SyncHandle();
 }
 
-static const struct glx_context_vtable glx_indirect_context_vtable = {
-   glx_indirect_bind_tex_image,
-   glx_indirect_release_tex_image,
+static const struct glx_context_vtable indirect_context_vtable = {
+   indirect_bind_tex_image,
+   indirect_release_tex_image,
 };
 
 /*@{*/
index 43469c371cff14de60eeda88af0ca539d46add80..0bf61779c4a1dda7d162a584d2b26c413645bb7e 100644 (file)
@@ -399,7 +399,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
       }
 
       bindReturnValue =
-         (gc->driContext->bindContext) (gc->driContext, pdraw, pread);
+         (gc->driContext->bindContext) (gc, pdraw, pread);
    }
    else if (!gc && oldGC && oldGC->driContext) {
       bindReturnValue = True;
@@ -441,7 +441,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
    }
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    else if (oldGC->driContext && oldGC != gc) {
-      oldGC->driContext->unbindContext(oldGC->driContext);
+      oldGC->driContext->unbindContext(oldGC);
    }
 #endif
 
@@ -488,9 +488,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
             /* Destroy the old direct rendering context */
             if (oldGC->driContext) {
-               oldGC->driContext->destroyContext(oldGC->driContext,
-                                                 oldGC->psc,
-                                                 oldGC->createDpy);
+               oldGC->driContext->destroyContext(oldGC);
                oldGC->driContext = NULL;
             }
 #endif