Mesa (master): glx: Refactor and simplify context creation

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


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

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Fri Jul 23 16:15:31 2010 -0400

glx: Refactor and simplify context creation

This lets us better separate context creation between the different
backends.

---

 src/glx/dri2_glx.c  |   11 +-
 src/glx/dri_glx.c   |   12 ++-
 src/glx/drisw_glx.c |   12 ++-
 src/glx/glxclient.h |   11 ++
 src/glx/glxcmds.c   |  327 +++++++++++++++++++++++---------------------------
 src/glx/glxext.c    |   17 +---
 6 files changed, 185 insertions(+), 205 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 02c0f9f..58f09ed 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -154,9 +154,9 @@ dri2UnbindContext(__GLXcontext *context)
 }
 
 static __GLXcontext *
-dri2CreateContext(__GLXscreenConfigs *base,
-                  const __GLcontextModes * mode,
-                  GLXContext shareList, int renderType)
+dri2_create_context(__GLXscreenConfigs *base,
+		    const __GLcontextModes * mode,
+		    GLXContext shareList, int renderType)
 {
    struct dri2_context *pcp, *pcp_shared;
    struct dri2_screen *psc = (struct dri2_screen *) base;
@@ -718,6 +718,9 @@ dri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions)
    }
 }
 
+static const struct glx_screen_vtable dri2_screen_vtable = {
+   dri2_create_context
+};
 
 static __GLXscreenConfigs *
 dri2CreateScreen(int screen, __GLXdisplayPrivate * priv)
@@ -811,10 +814,10 @@ dri2CreateScreen(int screen, __GLXdisplayPrivate * priv)
 
    psc->driver_configs = driver_configs;
 
+   psc->base.vtable = &dri2_screen_vtable;
    psp = &psc->vtable;
    psc->base.driScreen = psp;
    psp->destroyScreen = dri2DestroyScreen;
-   psp->createContext = dri2CreateContext;
    psp->createDrawable = dri2CreateDrawable;
    psp->swapBuffers = dri2SwapBuffers;
    psp->getDrawableMSC = NULL;
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index ff7ca5e..95cded7 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -550,9 +550,9 @@ static const struct glx_context_vtable dri_context_vtable = {
 };
 
 static __GLXcontext *
-driCreateContext(__GLXscreenConfigs *base,
-                 const __GLcontextModes * mode,
-                 GLXContext shareList, int renderType)
+dri_create_context(__GLXscreenConfigs *base,
+		   const __GLcontextModes *mode,
+		   GLXContext shareList, int renderType)
 {
    struct dri_context *pcp, *pcp_shared;
    struct dri_screen *psc = (struct dri_screen *) base;
@@ -821,6 +821,10 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
    }
 }
 
+static const struct glx_screen_vtable dri_screen_vtable = {
+   dri_create_context
+};
+
 static __GLXscreenConfigs *
 driCreateScreen(int screen, __GLXdisplayPrivate *priv)
 {
@@ -882,13 +886,13 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv)
    extensions = psc->core->getExtensions(psc->driScreen);
    driBindExtensions(psc, extensions);
 
+   psc->base.vtable = &dri_screen_vtable;
    psp = &psc->vtable;
    psc->base.driScreen = psp;
    if (psc->driCopySubBuffer)
       psp->copySubBuffer = driCopySubBuffer;
 
    psp->destroyScreen = driDestroyScreen;
-   psp->createContext = driCreateContext;
    psp->createDrawable = driCreateDrawable;
    psp->swapBuffers = driSwapBuffers;
 
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index c971de2..4265f56 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -289,9 +289,9 @@ static const struct glx_context_vtable drisw_context_vtable = {
 };
 
 static __GLXcontext *
-driCreateContext(__GLXscreenConfigs *base,
-		 const __GLcontextModes *mode,
-		 GLXContext shareList, int renderType)
+drisw_create_context(__GLXscreenConfigs *base,
+		     const __GLcontextModes *mode,
+		     GLXContext shareList, int renderType)
 {
    struct drisw_context *pcp, *pcp_shared;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
@@ -426,6 +426,10 @@ driOpenSwrast(void)
    return driver;
 }
 
+static const struct glx_screen_vtable drisw_screen_vtable = {
+   drisw_create_context
+};
+
 static __GLXscreenConfigs *
 driCreateScreen(int screen, __GLXdisplayPrivate *priv)
 {
@@ -482,10 +486,10 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv)
 
    psc->driver_configs = driver_configs;
 
+   psc->base.vtable = &drisw_screen_vtable;
    psp = &psc->vtable;
    psc->base.driScreen = psp;
    psp->destroyScreen = driDestroyScreen;
-   psp->createContext = driCreateContext;
    psp->createDrawable = driCreateDrawable;
    psp->swapBuffers = driSwapBuffers;
 
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 20c4529..48b5501 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -504,8 +504,16 @@ extern void __glFreeAttributeState(__GLXcontext *);
  * One of these records exists per screen of the display.  It contains
  * a pointer to the config data for that screen (if the screen supports GL).
  */
+struct glx_screen_vtable {
+   __GLXcontext *(*create_context)(__GLXscreenConfigs *psc,
+				   const __GLcontextModes *mode,
+				   GLXContext shareList, int renderType);
+};
+
 struct __GLXscreenConfigsRec
 {
+   const struct glx_screen_vtable *vtable;
+
     /**
      * GLX extension string reported by the X-server.
      */
@@ -799,4 +807,7 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable);
 
 #endif
 
+extern __GLXscreenConfigs *
+indirect_create_screen(int screen, __GLXdisplayPrivate * priv);
+
 #endif /* !__GLX_client_h__ */
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 72ac3ec..1ded624 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -234,6 +234,55 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
    return NULL;
 }
 
+#ifdef GLX_USE_APPLEGL
+
+static const struct glx_context_vtable applegl_context_vtable;
+
+static __GLcontext *
+applegl_create_context(__GLXscreenConfigs *psc,
+			const __GLcontextModes *mode,
+			GLXContext shareList, int renderType)
+{
+   __GLXcontext *gc;
+   int errorcode;
+   bool x11error;
+
+   /* TODO: Integrate this with apple_glx_create_context and make
+    * struct apple_glx_context inherit from __GLXcontext. */
+
+   gc = Xmalloc(sizeof *gc);
+   if (pcp == NULL)
+      return NULL;
+
+   memset(gc, 0, sizeof *gc);
+   if (!glx_context_init(&gc->base, &psc->base, mode)) {
+      Xfree(gc);
+      return NULL;
+   }
+
+   gc->vtable = &applegl_context_vtable;
+   gc->driContext = NULL;
+   gc->do_destroy = False;
+
+   /* TODO: darwin: Integrate with above to do indirect */
+   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
+			       shareList ? shareList->driContext : NULL,
+			       &errorcode, &x11error)) {
+      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
+      gc->vtable->destroy(gc);
+      return NULL;
+   }
+
+   gc->currentContextTag = -1;
+   gc->mode = fbconfig;
+   gc->isDirect = allowDirect;
+   gc->xid = 1; /* Just something not None, so we know when to destroy
+		 * it in MakeContextCurrent. */
+
+   return gc;
+}
+#endif
+
 
 /**
  * \todo It should be possible to move the allocate of \c client_state_private
@@ -246,17 +295,16 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
  * does all the initialization (including the pixel pack / unpack).
  */
 static GLXContext
-AllocateGLXContext(Display * dpy)
+indirect_create_context(__GLXscreenConfigs *psc,
+			const __GLcontextModes *mode,
+			GLXContext shareList, int renderType)
 {
    GLXContext gc;
    int bufSize;
    CARD8 opcode;
    __GLXattribute *state;
 
-   if (!dpy)
-      return NULL;
-
-   opcode = __glXSetupForCommand(dpy);
+   opcode = __glXSetupForCommand(psc->dpy);
    if (!opcode) {
       return NULL;
    }
@@ -269,6 +317,8 @@ AllocateGLXContext(Display * dpy)
    }
    memset(gc, 0, sizeof(struct __GLXcontextRec));
 
+   glx_context_init(gc, psc, mode);
+   gc->isDirect = GL_FALSE;
    gc->vtable = &indirect_context_vtable;
    state = Xmalloc(sizeof(struct __GLXattributeRec));
    if (state == NULL) {
@@ -287,7 +337,7 @@ AllocateGLXContext(Display * dpy)
     ** packet for the GLXRenderReq header.
     */
 
-   bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
+   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
    gc->buf = (GLubyte *) Xmalloc(bufSize);
    if (!gc->buf) {
       Xfree(gc->client_state_private);
@@ -339,14 +389,31 @@ AllocateGLXContext(Display * dpy)
    }
    gc->maxSmallRenderCommandSize = bufSize;
    
-#ifdef GLX_USE_APPLEGL
-   gc->driContext = NULL;
-   gc->do_destroy = False;   
-#endif
 
    return gc;
 }
 
+struct glx_screen_vtable indirect_screen_vtable = {
+   indirect_create_context
+};
+
+_X_HIDDEN __GLXscreenConfigs *
+indirect_create_screen(int screen, __GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+
+   psc = Xmalloc(sizeof *psc);
+   if (psc == NULL)
+      return NULL;
+
+   memset(psc, 0, sizeof *psc);
+   glx_screen_init(psc, screen, priv);
+   psc->vtable = &indirect_screen_vtable;
+
+   return psc;
+}
+
+
 _X_HIDDEN Bool
 glx_context_init(__GLXcontext *gc,
 		 __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig)
@@ -382,27 +449,19 @@ CreateContext(Display * dpy, int generic_id,
 {
    GLXContext gc = NULL;
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL)
-   int errorcode;
-   bool x11error;
-#endif
-    
+
    if (dpy == NULL)
       return NULL;
 
    if (generic_id == None)
       return NULL;
 
-#ifndef GLX_USE_APPLEGL  /* TODO: darwin indirect */
-#ifdef GLX_DIRECT_RENDERING
-   if (allowDirect && psc->driScreen) {
-      gc = psc->driScreen->createContext(psc, fbconfig,
-					 shareList, renderType);
-   }
-#endif
-
+   gc = NULL;
+   if (allowDirect && psc->vtable->create_context)
+      gc = psc->vtable->create_context(psc, fbconfig,
+				      shareList, renderType);
    if (!gc)
-      gc = AllocateGLXContext(dpy);
+      gc = indirect_create_context(psc, fbconfig, shareList, renderType);
    if (!gc)
       return NULL;
 
@@ -469,26 +528,10 @@ CreateContext(Display * dpy, int generic_id,
 
    UnlockDisplay(dpy);
    SyncHandle();
-#endif
 
    gc->imported = GL_FALSE;
    gc->renderType = renderType;
 
-   /* TODO: darwin: Integrate with above to do indirect */
-#ifdef GLX_USE_APPLEGL
-   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
-                               shareList ? shareList->driContext : NULL,
-                               &errorcode, &x11error)) {
-      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
-      gc->vtable->destroy(gc);
-      return NULL;
-   }
-   
-   gc->currentContextTag = -1;
-   gc->mode = fbconfig;
-   gc->isDirect = allowDirect;
-#endif
-
    return gc;
 }
 
@@ -1633,122 +1676,103 @@ GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
           glXGetCurrentDisplay)
 
 #ifndef GLX_USE_APPLEGL
-/**
- * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
- * to the X-server.
- *
- * \param dpy  Display where \c ctx was created.
- * \param ctx  Context to query.
- * \returns  \c Success on success.  \c GLX_BAD_CONTEXT if \c ctx is invalid,
- *           or zero if the request failed due to internal problems (i.e.,
- *           unable to allocate temporary memory, etc.)
- *
- * \note
- * This function dynamically determines whether to use the EXT_import_context
- * version of the protocol or the GLX 1.3 version of the protocol.
- */
-static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
+PUBLIC GLXContext
+glXImportContextEXT(Display *dpy, GLXContextID contextID)
 {
    __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+   __GLXscreenConfigs *psc;
    xGLXQueryContextReply reply;
    CARD8 opcode;
-   GLuint numValues;
-   int retval;
+   GLXContext ctx;
+   int propList[__GLX_MAX_CONTEXT_PROPS * 2], *pProp, nPropListBytes;
+   int i, renderType;
+   XID share;
+   __GLcontextModes *mode;
+
+   if (contextID == None || __glXIsDirect(dpy, contextID))
+      return NULL;
 
-   if (ctx == NULL) {
-      return GLX_BAD_CONTEXT;
-   }
    opcode = __glXSetupForCommand(dpy);
-   if (!opcode) {
+   if (!opcode)
       return 0;
-   }
 
    /* Send the glXQueryContextInfoEXT request */
    LockDisplay(dpy);
 
-   if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+   if (priv->majorVersion > 1 || priv->minorVersion >= 3) {
       xGLXQueryContextReq *req;
 
       GetReq(GLXQueryContext, req);
 
       req->reqType = opcode;
       req->glxCode = X_GLXQueryContext;
-      req->context = (unsigned int) (ctx->xid);
+      req->context = contextID;
    }
    else {
       xGLXVendorPrivateReq *vpreq;
       xGLXQueryContextInfoEXTReq *req;
 
       GetReqExtra(GLXVendorPrivate,
-                  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
-                  vpreq);
+		  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
+		  vpreq);
       req = (xGLXQueryContextInfoEXTReq *) vpreq;
       req->reqType = opcode;
       req->glxCode = X_GLXVendorPrivateWithReply;
       req->vendorCode = X_GLXvop_QueryContextInfoEXT;
-      req->context = (unsigned int) (ctx->xid);
+      req->context = contextID;
    }
 
    _XReply(dpy, (xReply *) & reply, 0, False);
 
-   numValues = reply.n;
-   if (numValues == 0)
-      retval = Success;
-   else if (numValues > __GLX_MAX_CONTEXT_PROPS)
-      retval = 0;
-   else {
-      int *propList, *pProp;
-      int nPropListBytes;
-
-      nPropListBytes = numValues << 3;
-      propList = (int *) Xmalloc(nPropListBytes);
-      if (NULL == propList) {
-         retval = 0;
-      }
-      else {
-	 unsigned i;
-
-         _XRead(dpy, (char *) propList, nPropListBytes);
-
-	 /* Look up screen first so we can look up visuals/fbconfigs later */
-         pProp = propList;
-         for (i = 0; i < numValues; i++, pProp += 2)
-	     if (pProp[0] == GLX_SCREEN) {
-		 ctx->screen = pProp[1];
-		 ctx->psc = GetGLXScreenConfigs(dpy, ctx->screen);
-	     }
-
-         pProp = propList;
-         for (i = 0; i < numValues; i++) {
-            switch (*pProp++) {
-            case GLX_SHARE_CONTEXT_EXT:
-               ctx->share_xid = *pProp++;
-               break;
-            case GLX_VISUAL_ID_EXT:
-               ctx->mode =
-                  _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
-               break;
-            case GLX_FBCONFIG_ID:
-               ctx->mode =
-                  _gl_context_modes_find_fbconfig(ctx->psc->configs,
-                                                  *pProp++);
-               break;
-            case GLX_RENDER_TYPE:
-               ctx->renderType = *pProp++;
-               break;
-            case GLX_SCREEN:
-            default:
-               pProp++;
-               continue;
-            }
-         }
-         Xfree((char *) propList);
-         retval = Success;
-      }
-   }
+   if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
+      nPropListBytes = reply.n * 2 * sizeof propList[0];
+   else
+      nPropListBytes = 0;
+   _XRead(dpy, (char *) propList, nPropListBytes);
    UnlockDisplay(dpy);
    SyncHandle();
-   return retval;
+
+   /* Look up screen first so we can look up visuals/fbconfigs later */
+   psc = NULL;
+   for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
+      if (pProp[0] == GLX_SCREEN)
+	 psc = GetGLXScreenConfigs(dpy, pProp[1]);
+   if (psc == NULL)
+      return NULL;
+
+   share = None;
+   mode = NULL;
+   renderType = 0;
+   pProp = propList;
+
+   for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
+      switch (pProp[0]) {
+      case GLX_SHARE_CONTEXT_EXT:
+	 share = pProp[1];
+	 break;
+      case GLX_VISUAL_ID_EXT:
+	 mode = _gl_context_modes_find_visual(psc->visuals, pProp[1]);
+	 break;
+      case GLX_FBCONFIG_ID:
+	 mode = _gl_context_modes_find_fbconfig(psc->configs, pProp[1]);
+	 break;
+      case GLX_RENDER_TYPE:
+	 renderType = pProp[1];
+	 break;
+      }
+
+   if (mode == NULL)
+      return NULL;
+
+   ctx = indirect_create_context(psc, mode, NULL, renderType);
+   if (ctx == NULL)
+      return NULL;
+
+   ctx->xid = contextID;
+   ctx->imported = GL_TRUE;
+   ctx->share_xid = share;
+
+   return ctx;
 }
 
 #endif
@@ -1756,38 +1780,21 @@ static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
 PUBLIC int
 glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value)
 {
-#ifndef GLX_USE_APPLEGL
-   int retVal;
-
-   /* get the information from the server if we don't have it already */
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   if (!ctx->driContext && (ctx->mode == NULL)) {
-#else
-   if (ctx->mode == NULL) {
-#endif
-      retVal = __glXQueryContextInfo(dpy, ctx);
-      if (Success != retVal)
-         return retVal;
-   }
-#endif
-
    switch (attribute) {
-#ifndef GLX_USE_APPLEGL
       case GLX_SHARE_CONTEXT_EXT:
-      *value = (int) (ctx->share_xid);
+      *value = ctx->share_xid;
       break;
    case GLX_VISUAL_ID_EXT:
       *value = ctx->mode ? ctx->mode->visualID : None;
       break;
-#endif
    case GLX_SCREEN:
-      *value = (int) (ctx->screen);
+      *value = ctx->screen;
       break;
    case GLX_FBCONFIG_ID:
       *value = ctx->mode ? ctx->mode->fbconfigID : None;
       break;
    case GLX_RENDER_TYPE:
-      *value = (int) (ctx->renderType);
+      *value = ctx->renderType;
       break;
    default:
       return GLX_BAD_ATTRIBUTE;
@@ -1805,35 +1812,6 @@ PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
    return ctx->xid;
 }
 
-PUBLIC GLXContext
-glXImportContextEXT(Display * dpy, GLXContextID contextID)
-{
-#ifdef GLX_USE_APPLEGL
-   return NULL;
-#else
-   GLXContext ctx;
-
-   if (contextID == None) {
-      return NULL;
-   }
-   if (__glXIsDirect(dpy, contextID)) {
-      return NULL;
-   }
-
-   ctx = AllocateGLXContext(dpy);
-   if (NULL != ctx) {
-      ctx->xid = contextID;
-      ctx->imported = GL_TRUE;
-
-      if (Success != __glXQueryContextInfo(dpy, ctx)) {
-	 ctx->vtable->destroy(ctx);
-	 ctx = NULL;
-      }
-   }
-   return ctx;
-#endif
-}
-
 PUBLIC void
 glXFreeContextEXT(Display * dpy, GLXContext ctx)
 {
@@ -1841,11 +1819,6 @@ glXFreeContextEXT(Display * dpy, GLXContext ctx)
 }
 
 
-
-/*
- * GLX 1.3 functions - these are just stubs for now!
- */
-
 PUBLIC GLXFBConfig *
 glXChooseFBConfig(Display * dpy, int screen,
                   const int *attribList, int *nitems)
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index 324230f..f9a5f7c 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -738,21 +738,6 @@ glx_screen_init(__GLXscreenConfigs *psc,
    return GL_TRUE;
 }
 
-static __GLXscreenConfigs *
-createIndirectScreen(int screen, __GLXdisplayPrivate * priv)
-{
-   __GLXscreenConfigs *psc;
-
-   psc = Xmalloc(sizeof *psc);
-   if (psc == NULL)
-      return NULL;
-
-   memset(psc, 0, sizeof *psc);
-   glx_screen_init(psc, screen, priv);
-
-   return psc;
-}
-
 /*
 ** Allocate the memory for the per screen configs for each screen.
 ** If that works then fetch the per screen configs data.
@@ -789,7 +774,7 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
 	 psc = (*priv->driswDisplay->createScreen) (i, priv);
 #endif
       if (psc == NULL)
-	 psc = createIndirectScreen (i, priv);
+	 psc = indirect_create_screen(i, priv);
       priv->screenConfigs[i] = psc;
    }
    SyncHandle();




More information about the mesa-commit mailing list