Bug 596544 - These WebGL samples are slow on Firefox, fast on Chrome - r=vladimir, a=joe
authorBenoit Jacob <bjacob@mozilla.com>
Mon, 20 Sep 2010 13:19:30 -0400
changeset 54359 f9728160d6e41da28e4312748bf7d146bb38edb0
parent 54358 0dcf8c885e0710c69c470f1c316051c8b7eb7927
child 54360 901fd772c4da647b68670b28aed1510c1bc76dc2
push id15866
push userbjacob@mozilla.com
push dateMon, 20 Sep 2010 17:26:44 +0000
treeherdermozilla-central@901fd772c4da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladimir, joe
bugs596544
milestone2.0b7pre
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
Bug 596544 - These WebGL samples are slow on Firefox, fast on Chrome - r=vladimir, a=joe
gfx/thebes/GLContextProviderGLX.cpp
gfx/thebes/GLXLibrary.h
--- a/gfx/thebes/GLContextProviderGLX.cpp
+++ b/gfx/thebes/GLContextProviderGLX.cpp
@@ -93,16 +93,17 @@ GLXLibrary::EnsureInitialized()
         { (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
         { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } },
         { (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
         { (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } },
         { (PRFuncPtr*) &xCreatePixmap, { "glXCreatePixmap", NULL } },
         { (PRFuncPtr*) &xDestroyPixmap, { "glXDestroyPixmap", NULL } },
         { (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } },
         { (PRFuncPtr*) &xCreateContext, { "glXCreateContext", NULL } },
+        { (PRFuncPtr*) &xGetCurrentContext, { "glXGetCurrentContext", NULL } },
         { NULL, { NULL } }
     };
 
     if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return PR_FALSE;
     }
 
@@ -249,18 +250,29 @@ TRY_AGAIN_NO_SHARING:
             return PR_FALSE;
         }
 
         return IsExtensionSupported("GL_EXT_framebuffer_object");
     }
 
     PRBool MakeCurrent(PRBool aForce = PR_FALSE)
     {
-        Bool succeeded = sGLXLibrary.xMakeCurrent(mDisplay, mDrawable, mContext);
-        NS_ASSERTION(succeeded, "Failed to make GL context current!");
+        PRBool succeeded = PR_TRUE;
+
+        // With the ATI FGLRX driver, glxMakeCurrent is very slow even when the context doesn't change.
+        // (This is not the case with other drivers such as NVIDIA).
+        // So avoid calling it more than necessary. Since GLX documentation says that:
+        //     "glXGetCurrentContext returns client-side information.
+        //      It does not make a round trip to the server."
+        // I assume that it's not worth using our own TLS slot here.
+        if (aForce || sGLXLibrary.xGetCurrentContext() != mContext) {
+            succeeded = sGLXLibrary.xMakeCurrent(mDisplay, mDrawable, mContext);
+            NS_ASSERTION(succeeded, "Failed to make GL context current!");
+        }
+
         return succeeded;
     }
 
     PRBool SetupLookupFunction()
     {
         mLookupFunc = (PlatformLookupFunction)sGLXLibrary.xGetProcAddress;
         return PR_TRUE;
     }
--- a/gfx/thebes/GLXLibrary.h
+++ b/gfx/thebes/GLXLibrary.h
@@ -49,16 +49,18 @@ public:
 
     typedef void (GLAPIENTRY * PFNGLXDELETECONTEXTPROC) (Display*,
                                                          GLXContext);
     PFNGLXDELETECONTEXTPROC xDeleteContext;
     typedef Bool (GLAPIENTRY * PFNGLXMAKECURRENTPROC) (Display*,
                                                        GLXDrawable,
                                                        GLXContext);
     PFNGLXMAKECURRENTPROC xMakeCurrent;
+    typedef GLXContext (GLAPIENTRY * PFNGLXGETCURRENTCONTEXT) ();
+    PFNGLXGETCURRENTCONTEXT xGetCurrentContext;
     typedef void* (GLAPIENTRY * PFNGLXGETPROCADDRESSPROC) (const char *);
     PFNGLXGETPROCADDRESSPROC xGetProcAddress;
     typedef XVisualInfo* (GLAPIENTRY * PFNGLXCHOOSEVISUALPROC) (Display*,
                                                                 int,
                                                                 int *);
     PFNGLXCHOOSEVISUALPROC xChooseVisual;
     typedef GLXFBConfig* (GLAPIENTRY * PFNGLXCHOOSEFBCONFIG) (Display *,
                                                               int,