Fix GLX version check so it won't break when the version hits 1.10. (Bug 605992) r=bjacob a2.0=joedrew
authorL. David Baron <dbaron@dbaron.org>
Wed, 10 Nov 2010 07:49:52 -0800
changeset 57247 f989d1ef7cb8182c62400434d4a6c9a36f3f8df0
parent 57246 8b83d833cc950398c586183b23253ea9f4e3c59e
child 57248 3c75b7bea31ac5e0b8f89b71464ce343c8de5dc5
push id16847
push userdbaron@mozilla.com
push dateWed, 10 Nov 2010 15:50:38 +0000
treeherdermozilla-central@e250978a21be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs605992
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Fix GLX version check so it won't break when the version hits 1.10. (Bug 605992) r=bjacob a2.0=joedrew
gfx/thebes/GLContextProviderGLX.cpp
gfx/thebes/GLXLibrary.h
--- a/gfx/thebes/GLContextProviderGLX.cpp
+++ b/gfx/thebes/GLContextProviderGLX.cpp
@@ -59,17 +59,25 @@
 #include "gfxPlatform.h"
 #include "GLContext.h"
 
 namespace mozilla {
 namespace gl {
 
 static PRBool gIsATI = PR_FALSE;
 static PRBool gIsChromium = PR_FALSE;
-static int gGLXVersion = 0;
+static int gGLXMajorVersion = 0, gGLXMinorVersion = 0;
+
+// Check that we have at least version aMajor.aMinor .
+static inline bool
+GLXVersionCheck(int aMajor, int aMinor)
+{
+    return aMajor < gGLXMajorVersion ||
+           (aMajor == gGLXMajorVersion && aMinor <= gGLXMinorVersion);
+}
 
 static inline bool
 HasExtension(const char* aExtensions, const char* aRequiredExtension)
 {
     return GLContext::ListHasExtension(
         reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
 }
 
@@ -94,21 +102,21 @@ GLXLibrary::EnsureInitialized()
         }
     }
 
     LibrarySymbolLoader::SymLoadStruct symbols[] = {
         /* functions that were in GLX 1.0 */
         { (PRFuncPtr*) &xDestroyContext, { "glXDestroyContext", NULL } },
         { (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } },
         { (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
+        { (PRFuncPtr*) &xQueryVersion, { "glXQueryVersion", NULL } },
         { (PRFuncPtr*) &xGetCurrentContext, { "glXGetCurrentContext", NULL } },
         /* functions introduced in GLX 1.1 */
         { (PRFuncPtr*) &xQueryExtensionsString, { "glXQueryExtensionsString", NULL } },
         { (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } },
-        { (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } },
         { NULL, { NULL } }
     };
 
     LibrarySymbolLoader::SymLoadStruct symbols13[] = {
         /* functions introduced in GLX 1.3 */
         { (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } },
         { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } },
         // WARNING: xGetFBConfigs not set in symbols13_ext
@@ -150,78 +158,66 @@ GLXLibrary::EnsureInitialized()
 
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
     Display *display = DefaultXDisplay();
     int screen = DefaultScreen(display);
+    if (!xQueryVersion(display, &gGLXMajorVersion, &gGLXMinorVersion)) {
+        gGLXMajorVersion = 0;
+        gGLXMinorVersion = 0;
+        return PR_FALSE;
+    }
+
     const char *vendor = xQueryServerString(display, screen, GLX_VENDOR);
     const char *serverVersionStr = xQueryServerString(display, screen, GLX_VERSION);
-    const char *clientVersionStr = xGetClientString(display, GLX_VERSION);
 
-    int serverVersion = 0, clientVersion = 0;
-    if (serverVersionStr &&
-        strlen(serverVersionStr) >= 3 &&
-        serverVersionStr[1] == '.')
-    {
-        serverVersion = (serverVersionStr[0] - '0') << 8 | (serverVersionStr[2] - '0');
-    }
-
-    if (clientVersionStr &&
-        strlen(clientVersionStr) >= 3 &&
-        clientVersionStr[1] == '.')
-    {
-        clientVersion = (clientVersionStr[0] - '0') << 8 | (clientVersionStr[2] - '0');
-    }
-
-    gGLXVersion = PR_MIN(clientVersion, serverVersion);
-
-    if (gGLXVersion < 0x0101)
+    if (!GLXVersionCheck(1, 1))
         // Not possible to query for extensions.
         return PR_FALSE;
 
     const char *extensionsStr = xQueryExtensionsString(display, screen);
 
     LibrarySymbolLoader::SymLoadStruct *sym13;
-    if (gGLXVersion < 0x0103) {
+    if (!GLXVersionCheck(1, 3)) {
         // Even if we don't have 1.3, we might have equivalent extensions
         // (as on the Intel X server).
         if (!HasExtension(extensionsStr, "GLX_SGIX_fbconfig")) {
             return PR_FALSE;
         }
         sym13 = symbols13_ext;
     } else {
         sym13 = symbols13;
     }
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym13)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
     LibrarySymbolLoader::SymLoadStruct *sym14;
-    if (gGLXVersion < 0x0104) {
+    if (!GLXVersionCheck(1, 4)) {
         // Even if we don't have 1.4, we might have equivalent extensions
         // (as on the Intel X server).
         if (!HasExtension(extensionsStr, "GLX_ARB_get_proc_address")) {
             return PR_FALSE;
         }
         sym14 = symbols14_ext;
     } else {
         sym14 = symbols14;
     }
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym14)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
     gIsATI = vendor && DoesVendorStringMatch(vendor, "ATI");
     gIsChromium = (vendor && DoesVendorStringMatch(vendor, "Chromium")) ||
-        (serverVersion && DoesVendorStringMatch(serverVersionStr, "Chromium"));
+        (serverVersionStr && DoesVendorStringMatch(serverVersionStr, "Chromium"));
 
     mInitialized = PR_TRUE;
     return PR_TRUE;
 }
 
 GLXLibrary sGLXLibrary;
 
 static bool ctxErrorOccurred = false;
@@ -508,17 +504,17 @@ GLContextProviderGLX::CreateForWindow(ns
     // is a relatively safe intermediate step.
 
     Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY); 
     int xscreen = DefaultScreen(display);
     Window window = GET_NATIVE_WINDOW(aWidget);
 
     int numConfigs;
     ScopedXFree<GLXFBConfig> cfgs;
-    if (gIsATI || gGLXVersion < 0x0103) {
+    if (gIsATI || !GLXVersionCheck(1, 3)) {
         const int attribs[] = {
             GLX_DOUBLEBUFFER, False,
             0
         };
         cfgs = sGLXLibrary.xChooseFBConfig(display,
                                            xscreen,
                                            attribs,
                                            &numConfigs);
@@ -672,17 +668,17 @@ CreateOffscreenPixmapContext(const gfxIn
         return nsnull;
     }
 
 
     GLXPixmap glxpixmap;
     // Handle slightly different signature between glXCreatePixmap and
     // its pre-GLX-1.3 extension equivalent (though given the ABI, we
     // might not need to).
-    if (gGLXVersion >= 0x0103) {
+    if (GLXVersionCheck(1, 3)) {
         glxpixmap = sGLXLibrary.xCreatePixmap(display,
                                               cfgs[chosenIndex],
                                               xsurface->XDrawable(),
                                               NULL);
     } else {
         glxpixmap = sGLXLibrary.xCreateGLXPixmapWithConfig(display,
                                                            cfgs[chosenIndex],
                                                            xsurface->
--- a/gfx/thebes/GLXLibrary.h
+++ b/gfx/thebes/GLXLibrary.h
@@ -102,24 +102,25 @@ public:
     typedef GLXPixmap (GLAPIENTRY * PFNGLXCREATEGLXPIXMAPWITHCONFIG)
                                                         (Display *,
                                                          GLXFBConfig,
                                                          Pixmap);
     PFNGLXCREATEGLXPIXMAPWITHCONFIG xCreateGLXPixmapWithConfig;
     typedef void (GLAPIENTRY * PFNGLXDESTROYPIXMAP) (Display *,
                                                      GLXPixmap);
     PFNGLXDESTROYPIXMAP xDestroyPixmap;
-    typedef const char * (GLAPIENTRY * PFNGLXGETCLIENTSTRING) (Display *,
-                                                               int);
-    PFNGLXGETCLIENTSTRING xGetClientString;
     typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXT) (Display *,
                                                            XVisualInfo *,
                                                            GLXContext,
                                                            Bool);
     PFNGLXCREATECONTEXT xCreateContext;
+    typedef Bool (GLAPIENTRY * PFNGLXQUERYVERSION) (Display *,
+                                                    int *,
+                                                    int *);
+    PFNGLXQUERYVERSION xQueryVersion;
 
     PRBool EnsureInitialized();
 
 private:
     PRBool mInitialized;
     PRBool mTriedInitializing;
     PRLibrary *mOGLLibrary;
 };