Author: Kristian Høgsberg <krh at redhat.com>

krh at bitplanet.net krh at bitplanet.net
Fri Oct 26 11:02:41 PDT 2007


Hi,

The patch below fixes a problem I introdced with the latest visual
cleanup work.  The problem was that the X root visual no longer got
associated with a GLX visual.  GLX applications rendering to the root
window or the composite overlay window (such as compiz) would fail to
work.

The fix here sets up GLX visuals for the root visuals and other X
visuals so that the root window can be rendered to again.  However,
there's a significant change in there; the extension stacking order is
changed so that GLX now sits on top of COMPOSITE.  This fixes a
problem we had even in the old code: COMPOSITE screen init runs after
GLX screen init and thus, we can't create a GLX visual for the
COMPOSITE ARGB visual.

Reordering the stacking order fixes this problem, since when GLX
screen init runs, COMPOSITE will already have added its special visual
and we can set up the extra GLX visual information nicely.  There is
no other interactions between COMPOSITE and GLX that I can think of,
so I believe it's safe to bubble GLX up, but I though I'd run it by
the list.  Putting GLX above COMPOSITE also puts it above XFIXES,
RENDER, RANDR, RES, DMXEXT, XEVIE, and DAMAGE, but that should be fine
too.  GLX is kinda special in that it doesn't really integrate much
with the tradition rendering paths in the X server, so there are few
dependencies.

cheers,
Kristian

diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 3151400..58a3549 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -396,38 +396,63 @@ initGlxVisual(VisualPtr visual, __GLcontextModes *config)
     visual->offsetBlue = findFirstSet(config->blueMask);
 }
 
-static void
-addMinimalSet(__GLXscreen *pGlxScreen)
+typedef struct {
+    GLboolean doubleBuffer;
+    GLboolean depthBuffer;
+} FBConfigTemplateRec, *FBConfigTemplatePtr;
+
+static __GLcontextModes *
+pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class)
 {
     __GLcontextModes *config;
-    VisualPtr visuals;
-    int depth;
 
     for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
 	if (config->visualRating != GLX_NONE)
 	    continue;
-	if (config->doubleBufferMode && config->depthBits > 0)
-	    break;
+	if (_gl_convert_to_x_visual_type(config->visualType) != class)
+	    continue;
+	if ((config->doubleBufferMode > 0) != template->doubleBuffer)
+	    continue;
+	if ((config->depthBits > 0) != template->depthBuffer)
+	    continue;
+
+	return config;
     }
-    if (config == NULL)
-	config = pGlxScreen->fbconfigs;
 
-    pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *));
+    return NULL;
+}
+
+static void
+addMinimalSet(__GLXscreen *pGlxScreen)
+{
+    __GLcontextModes *config;
+    VisualPtr visuals;
+    int i;
+    FBConfigTemplateRec best = { GL_TRUE, GL_TRUE };
+    FBConfigTemplateRec minimal = { GL_FALSE, GL_FALSE };
+
+    pGlxScreen->visuals = xcalloc(pGlxScreen->pScreen->numVisuals,
+				  sizeof (__GLcontextModes *));
     if (pGlxScreen->visuals == NULL) {
 	ErrorF("Failed to allocate for minimal set of GLX visuals\n");
 	return;
     }
 
-    depth = config->redBits + config->greenBits + config->blueBits;
-    visuals = AddScreenVisuals(pGlxScreen->pScreen, 1, depth);
-    if (visuals == NULL) {
-	xfree(pGlxScreen->visuals);
-	return;
+    pGlxScreen->numVisuals = pGlxScreen->pScreen->numVisuals;
+    visuals = pGlxScreen->pScreen->visuals;
+    for (i = 0; i < pGlxScreen->numVisuals; i++) {
+	if (visuals[i].nplanes == 32)
+	    config = pickFBConfig(pGlxScreen, &minimal, visuals[i].class);
+	else
+	    config = pickFBConfig(pGlxScreen, &best, visuals[i].class);
+	if (config == NULL)
+	    config = pGlxScreen->fbconfigs;
+	pGlxScreen->visuals[i] = config;
+	config->visualID = visuals[i].vid;
+	ErrorF("mapping visual 0x%02lx to fbconfig 0x%02x\n",
+	       visuals[i].vid, config->fbconfigID);
     }
 
-    pGlxScreen->numVisuals = 1;
-    pGlxScreen->visuals[0] = config;
-    initGlxVisual(&visuals[0], config);
 }
 
 static void
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 35b62a2..b8929c3 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1094,7 +1094,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
     }
 
 #ifdef GLXEXT
-    xf86Info.glxVisuals = XF86_GlxVisualsAll;
+    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
     xf86Info.glxVisualsFrom = X_DEFAULT;
     if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
 	if (!xf86NameCmp(s, "minimal")) {
diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c
index 847f0d4..0ff867d 100644
--- a/hw/xfree86/dixmods/glxmodule.c
+++ b/hw/xfree86/dixmods/glxmodule.c
@@ -45,7 +45,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 static MODULESETUPPROTO(glxSetup);
 
-static const char *initdeps[] = { "DOUBLE-BUFFER", NULL };
+static const char *initdeps[] = { "DOUBLE-BUFFER", "COMPOSITE", NULL };
 
 static ExtensionModule GLXExt =
 {
diff --git a/mi/miinitext.c b/mi/miinitext.c
index 556bfc8..b40e8bd 100644
--- a/mi/miinitext.c
+++ b/mi/miinitext.c
@@ -630,16 +630,6 @@ InitExtensions(argc, argv)
     if (!noXFree86DRIExtension) XFree86DRIExtensionInit();
 #endif
 #endif
-
-#ifdef GLXEXT
-#ifdef INXDARWINAPP
-    DarwinGlxPushProvider(__DarwinglXMesaProvider);
-    if (!noGlxExtension) DarwinGlxExtensionInit();
-#else
-    GlxPushProvider(&__glXMesaProvider);
-    if (!noGlxExtension) GlxExtensionInit();
-#endif // INXDARWINAPP
-#endif // GLXEXT
 #ifdef XFIXES
     /* must be before Render to layer DisplayCursor correctly */
     if (!noXFixesExtension) XFixesExtensionInit();
@@ -665,6 +655,16 @@ InitExtensions(argc, argv)
 #ifdef DAMAGE
     if (!noDamageExtension) DamageExtensionInit();
 #endif
+
+#ifdef GLXEXT
+#ifdef INXDARWINAPP
+    DarwinGlxPushProvider(__DarwinglXMesaProvider);
+    if (!noGlxExtension) DarwinGlxExtensionInit();
+#else
+    GlxPushProvider(&__glXMesaProvider);
+    if (!noGlxExtension) GlxExtensionInit();
+#endif
+#endif
 }
 
 void



More information about the xorg mailing list