[PATCH xserver 2/3] glx: Prepare __glXGetDrawable for no-config contexts

Adam Jackson ajax at redhat.com
Tue Nov 14 20:15:02 UTC 2017


Any proper (GLX 1.3) drawable will already have a bound config, but if
we're doing the GLX 1.2 thing of making a Window current, we need to
infer the config from the window's Visual.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 glx/glxcmds.c | 46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 8681ef13f..2f011889c 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -474,6 +474,18 @@ StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
     glxc->currentClient = cl->client;
 }
 
+static __GLXconfig *
+inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
+{
+    int i, vid = wVisual(pWin);
+
+    for (i = 0; i < pGlxScreen->numVisuals; i++)
+        if (pGlxScreen->visuals[i]->visualID == vid)
+            return pGlxScreen->visuals[i];
+
+    return NULL;
+}
+
 /**
  * This is a helper function to handle the legacy (pre GLX 1.3) cases
  * where passing an X window to glXMakeCurrent is valid.  Given a
@@ -486,11 +498,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
 {
     DrawablePtr pDraw;
     __GLXdrawable *pGlxDraw;
+    __GLXconfig *config;
+    __GLXscreen *pGlxScreen;
     int rc;
 
     if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
                          DixWriteAccess, &pGlxDraw, &rc)) {
-        if (glxc != NULL && pGlxDraw->config != glxc->config) {
+        if (glxc != NULL &&
+            glxc->config != NULL &&
+            glxc->config != pGlxDraw->config) {
             client->errorValue = drawId;
             *error = BadMatch;
             return NULL;
@@ -518,19 +534,35 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
         return NULL;
     }
 
-    if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
+    pGlxScreen = glxc->pGlxScreen;
+    if (pDraw->pScreen != pGlxScreen->pScreen) {
         client->errorValue = pDraw->pScreen->myNum;
         *error = BadMatch;
         return NULL;
     }
 
-    if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
+    config = glxc->config;
+    if (!config)
+        config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
+    if (!config) {
+        /*
+         * If we get here, we've tried to bind a no-config context to a
+         * window without a corresponding fbconfig, presumably because
+         * we don't support GL on it (PseudoColor perhaps). From GLX Section
+         * 3.3.7 "Rendering Contexts":
+         *
+         * "If draw or read are not compatible with ctx a BadMatch error
+         * is generated."
+         */
+        *error = BadMatch;
         return NULL;
+    }
 
-    pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
-                                                pDraw, drawId,
-                                                GLX_DRAWABLE_WINDOW,
-                                                drawId, glxc->config);
+    if (!validGlxFBConfigForWindow(client, config, pDraw, error))
+        return NULL;
+
+    pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
+                                          GLX_DRAWABLE_WINDOW, drawId, config);
     if (!pGlxDraw) {
 	*error = BadAlloc;
 	return NULL;
-- 
2.14.3



More information about the xorg-devel mailing list