Bug 730079 - Move sCurrentGLContext to TLS to support off main thread GLDebug. r=ajuma
☠☠ backed out by 1fc5f5de538e ☠ ☠
authorBenoit Girard <b56girard@gmail.com>
Thu, 23 Feb 2012 17:51:57 -0500
changeset 89243 f8b7cca3297f14821f045e1f95bbb11b38cfd86d
parent 89242 f068e96a77a5d0cbdfa4b0d15f5f58d1f3bc5fb2
child 89244 1fc5f5de538e32771931bcae7866c6f48f633604
push id22242
push userkgupta@mozilla.com
push dateWed, 14 Mar 2012 15:19:09 +0000
treeherdermozilla-central@936ef50fa498 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajuma
bugs730079
milestone13.0a1
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 730079 - Move sCurrentGLContext to TLS to support off main thread GLDebug. r=ajuma
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -58,18 +58,18 @@
 #include "mozilla/Util.h" // for DebugOnly
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
 #ifdef DEBUG
-// see comment near declaration in GLContext.h. Should be thread-local.
-GLContext* GLContext::sCurrentGLContext = nsnull;
+Monitor GLContext::sCurrentGLContextMonitor("sCurrentGLContext_monitor");
+PRUintn GLContext::sCurrentGLContextTLS = -1;
 #endif
 
 PRUint32 GLContext::sDebugMode = 0;
 
 // define this here since it's global to GLContextProvider, not any
 // specific implementation
 const ContextFormat ContextFormat::BasicRGBA32Format(ContextFormat::BasicRGBA32);
 
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -47,16 +47,20 @@
 #endif
 #include <string.h>
 #include <ctype.h>
 
 #ifdef WIN32
 #include <windows.h>
 #endif
 
+#ifdef DEBUG
+#include "mozilla/Monitor.h"
+#endif
+
 #include "GLDefs.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxRect.h"
 #include "nsISupportsImpl.h"
 #include "prlink.h"
 
@@ -599,17 +603,22 @@ public:
     };
 
     virtual GLContextType GetContextType() { return ContextTypeUnknown; }
 
     virtual bool MakeCurrentImpl(bool aForce = false) = 0;
 
     bool MakeCurrent(bool aForce = false) {
 #ifdef DEBUG
-        sCurrentGLContext = this;
+        MonitorAutoLock lock(sCurrentGLContextMonitor);
+
+        if (sCurrentGLContextTLS == (PRUintn)-1)
+            PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, NULL);
+
+        PR_SetThreadPrivate(sCurrentGLContextTLS, this);
 #endif
         return MakeCurrentImpl(aForce);
     }
 
     bool IsContextLost() { return mContextLost; }
 
     virtual bool SetupLookupFunction() = 0;
 
@@ -1504,20 +1513,18 @@ public:
 protected:
 
     ContextFormat mCreationFormat;
     nsRefPtr<GLContext> mSharedContext;
 
     GLContextSymbols mSymbols;
 
 #ifdef DEBUG
-    // this should be thread-local, but that is slightly annoying to implement because on Mac
-    // we don't have any __thread-like keyword. So for now, MOZ_GL_DEBUG assumes (and asserts)
-    // that only the main thread is doing OpenGL calls.
-    static THEBES_API GLContext* sCurrentGLContext;
+    static Monitor sCurrentGLContextMonitor;
+    static PRUintn sCurrentGLContextTLS;
 #endif
 
     void UpdateActualFormat();
     ContextFormat mActualFormat;
 
     gfxIntSize mOffscreenSize;
     gfxIntSize mOffscreenActualSize;
     GLuint mOffscreenTexture;
@@ -1631,31 +1638,28 @@ public:
 
 protected:
     GLenum mGLError;
 
 public:
 
     void BeforeGLCall(const char* glFunction) {
         if (DebugMode()) {
-            // since the static member variable sCurrentGLContext is not thread-local as it should,
-            // we have to assert that we're in the main thread. Note that sCurrentGLContext is only used
-            // for the OpenGL debug mode.
-            if (!NS_IsMainThread()) {
-                NS_ERROR("OpenGL call from non-main thread. While this is fine in itself, "
-                         "the OpenGL debug mode, which is currently enabled, doesn't support this. "
-                         "It needs to be patched by making GLContext::sCurrentGLContext be thread-local.\n");
-                NS_ABORT();
-            }
+            MonitorAutoLock lock(sCurrentGLContextMonitor);
+            GLContext *currentGLContext = NULL;
+
+            if (sCurrentGLContextTLS != (PRUintn)-1)
+                currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
+
             if (DebugMode() & DebugTrace)
                 printf_stderr("[gl:%p] > %s\n", this, glFunction);
-            if (this != sCurrentGLContext) {
+            if (this != currentGLContext) {
                 printf_stderr("Fatal: %s called on non-current context %p. "
                               "The current context for this thread is %p.\n",
-                               glFunction, this, sCurrentGLContext);
+                               glFunction, this, currentGLContext);
                 NS_ABORT();
             }
         }
     }
 
     void AfterGLCall(const char* glFunction) {
         if (DebugMode()) {
             // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -262,25 +262,16 @@ is_power_of_two(int v)
 
 #define AFTER_GL_CALL do {           \
     AfterGLCall(MOZ_FUNCTION_NAME);  \
 } while (0)
 
 static void BeforeGLCall(const char* glFunction)
 {
     if (GLContext::DebugMode()) {
-        // since the static member variable sCurrentGLContext is not thread-local as it should,
-        // we have to assert that we're in the main thread. Note that sCurrentGLContext is only used
-        // for the OpenGL debug mode.
-        if (!NS_IsMainThread()) {
-            NS_ERROR("OpenGL call from non-main thread. While this is fine in itself, "
-                     "the OpenGL debug mode, which is currently enabled, doesn't support this. "
-                     "It needs to be patched by making GLContext::sCurrentGLContext be thread-local.\n");
-            NS_ABORT();
-        }
         if (GLContext::DebugMode() & GLContext::DebugTrace)
             printf_stderr("[egl] > %s\n", glFunction);
     }
 }
 
 static void AfterGLCall(const char* glFunction)
 {
     if (GLContext::DebugMode() & GLContext::DebugTrace) {