Bug 1382185 - Clear MakeCurrent when MakeCurrent fails. - r=nical draft
authorJeff Gilbert <jgilbert@mozilla.com>
Fri, 21 Jul 2017 17:41:05 -0700
changeset 613465 19b66dcfa7f6a12252252a4ef410e91f881c9805
parent 613463 4ec17b7d52f37489dba4b7e8686c492e94a2651f
child 613468 2a209842fb03d05af4b9781f714884ab64f5872d
push id69809
push userbmo:jgilbert@mozilla.com
push dateSat, 22 Jul 2017 00:50:18 +0000
reviewersnical
bugs1382185
milestone56.0a1
Bug 1382185 - Clear MakeCurrent when MakeCurrent fails. - r=nical MozReview-Commit-ID: GVvkNUbg3dZ
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextCGL.h
gfx/gl/GLContextEAGL.h
gfx/gl/GLContextEGL.h
gfx/gl/GLContextGLX.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEAGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/gl/GLContextWGL.h
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -59,17 +59,17 @@ namespace gl {
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 
 #ifdef MOZ_GL_DEBUG
 unsigned GLContext::sCurrentGLContextTLS = -1;
 #endif
 
-MOZ_THREAD_LOCAL(GLContext*) GLContext::sCurrentContext;
+MOZ_THREAD_LOCAL(const GLContext*) GLContext::sCurrentContext;
 
 // If adding defines, don't forget to undefine symbols. See #undef block below.
 #define CORE_SYMBOL(x) { (PRFuncPtr*) &mSymbols.f##x, { #x, nullptr } }
 #define CORE_EXT_SYMBOL2(x,y,z) { (PRFuncPtr*) &mSymbols.f##x, { #x, #x #y, #x #z, nullptr } }
 #define EXT_SYMBOL2(x,y,z) { (PRFuncPtr*) &mSymbols.f##x, { #x #y, #x #z, nullptr } }
 #define EXT_SYMBOL3(x,y,z,w) { (PRFuncPtr*) &mSymbols.f##x, { #x #y, #x #z, #x #w, nullptr } }
 #define END_SYMBOLS { nullptr, { nullptr } }
 
@@ -2908,48 +2908,58 @@ GetBytesPerTexel(GLenum format, GLenum t
     {
         return 2;
     }
 
     gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
     return 0;
 }
 
-bool GLContext::MakeCurrent(bool aForce)
+bool
+GLContext::MakeCurrent(bool aForce)
 {
-    if (IsDestroyed())
-        return false;
+    const auto fnMakeCurrent = [&]() {
+        if (IsDestroyed())
+            return false;
+
+        if (mUseTLSIsCurrent && !aForce && sCurrentContext.get() == this) {
+            MOZ_ASSERT(IsCurrent());
+            return true;
+        }
+
+        return MakeCurrentImpl(aForce);
+    };
+
+    const GLContext* currentContext;
+    if (fnMakeCurrent()) {
+        currentContext = this;
+    } else {
+        ClearMakeCurrent();
+        currentContext = nullptr;
+    }
 
 #ifdef MOZ_GL_DEBUG
-    PR_SetThreadPrivate(sCurrentGLContextTLS, this);
+    PR_SetThreadPrivate(sCurrentGLContextTLS, (void*)currentContext);
 
     // XXX this assertion is disabled because it's triggering on Mac;
     // we need to figure out why and reenable it.
 #if 0
     // IsOwningThreadCurrent is a bit of a misnomer;
     // the "owning thread" is the creation thread,
     // and the only thread that can own this.  We don't
     // support contexts used on multiple threads.
     NS_ASSERTION(IsOwningThreadCurrent(),
                  "MakeCurrent() called on different thread than this context was created on!");
 #endif
 #endif
-    if (mUseTLSIsCurrent && !aForce && sCurrentContext.get() == this) {
-        MOZ_ASSERT(IsCurrent());
-        return true;
-    }
-
-    if (!MakeCurrentImpl(aForce))
-        return false;
 
     if (mUseTLSIsCurrent) {
-        sCurrentContext.set(this);
+        sCurrentContext.set(currentContext);
     }
-
-    return true;
+    return bool(currentContext);
 }
 
 void
 GLContext::ResetSyncCallCount(const char* resetReason) const
 {
     if (ShouldSpew()) {
         printf_stderr("On %s, mSyncGLCallCount = %" PRIu64 "\n",
                        resetReason, mSyncGLCallCount);
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -192,17 +192,17 @@ enum class GLRenderer {
 
 class GLContext
     : public GLLibraryLoader
     , public GenericAtomicRefCounted
     , public SupportsWeakPtr<GLContext>
 {
 public:
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLContext)
-    static MOZ_THREAD_LOCAL(GLContext*) sCurrentContext;
+    static MOZ_THREAD_LOCAL(const GLContext*) sCurrentContext;
 
 // -----------------------------------------------------------------------------
 // basic getters
 public:
 
     /**
      * Returns true if the context is using ANGLE. This should only be overridden
      * for an ANGLE implementation.
@@ -3267,16 +3267,17 @@ public:
     void MarkDestroyed();
 
 // -----------------------------------------------------------------------------
 // Everything that isn't standard GL APIs
 protected:
     typedef gfx::SurfaceFormat SurfaceFormat;
 
     virtual bool MakeCurrentImpl(bool aForce) = 0;
+    virtual void ClearMakeCurrent() const = 0;
 
 public:
 #ifdef MOZ_GL_DEBUG
     static void StaticInit() {
         PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
     }
 #endif
 
--- a/gfx/gl/GLContextCGL.h
+++ b/gfx/gl/GLContextCGL.h
@@ -41,16 +41,17 @@ public:
     }
 
     bool Init() override;
 
     NSOpenGLContext* GetNSOpenGLContext() const { return mContext; }
     CGLContextObj GetCGLContext() const;
 
     virtual bool MakeCurrentImpl(bool aForce) override;
+    virtual void ClearMakeCurrent() const override;
 
     virtual bool IsCurrent() override;
 
     virtual GLenum GetPreferredARGB32Format() const override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
--- a/gfx/gl/GLContextEAGL.h
+++ b/gfx/gl/GLContextEAGL.h
@@ -39,16 +39,17 @@ public:
 
     bool Init() override;
 
     bool AttachToWindow(nsIWidget* aWidget);
 
     EAGLContext* GetEAGLContext() const { return mContext; }
 
     virtual bool MakeCurrentImpl(bool aForce) override;
+    virtual void ClearMakeCurrent() const override;
 
     virtual bool IsCurrent() override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
 
     virtual bool SwapBuffers() override;
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -69,16 +69,17 @@ public:
     virtual bool ReleaseTexImage() override;
 
     void SetEGLSurfaceOverride(EGLSurface surf);
     EGLSurface GetEGLSurfaceOverride() {
         return mSurfaceOverride;
     }
 
     virtual bool MakeCurrentImpl(bool aForce) override;
+    virtual void ClearMakeCurrent() const override;
 
     virtual bool IsCurrent() override;
 
     virtual bool RenewSurface(widget::CompositorWidget* aWidget) override;
 
     virtual void ReleaseSurface() override;
 
     virtual bool SetupLookupFunction() override;
--- a/gfx/gl/GLContextGLX.h
+++ b/gfx/gl/GLContextGLX.h
@@ -42,16 +42,17 @@ public:
     static GLContextGLX* Cast(GLContext* gl) {
         MOZ_ASSERT(gl->GetContextType() == GLContextType::GLX);
         return static_cast<GLContextGLX*>(gl);
     }
 
     bool Init() override;
 
     virtual bool MakeCurrentImpl(bool aForce) override;
+    virtual void ClearMakeCurrent() const override;
 
     virtual bool IsCurrent() override;
 
     virtual bool SetupLookupFunction() override;
 
     virtual bool IsDoubleBuffered() const override;
 
     virtual bool SwapBuffers() override;
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -126,16 +126,23 @@ GLContextCGL::MakeCurrentImpl(bool aForc
         // When we're iterating as fast as possible, however, we want a non-blocking
         // glSwapBuffers, which will happen when swapInt==0.
         GLint swapInt = gfxPrefs::LayoutFrameRate() == 0 ? 0 : 1;
         [mContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
     }
     return true;
 }
 
+void
+GLContextCGL::ClearMakeCurrent() const
+{
+    [mContext clearCurrentContext];
+    MOZ_ASSERT(![NSOpenGLContext currentContext]);
+}
+
 bool
 GLContextCGL::IsCurrent() {
     return [NSOpenGLContext currentContext] == mContext;
 }
 
 GLenum
 GLContextCGL::GetPreferredARGB32Format() const
 {
--- a/gfx/gl/GLContextProviderEAGL.mm
+++ b/gfx/gl/GLContextProviderEAGL.mm
@@ -122,16 +122,22 @@ GLContextEAGL::MakeCurrentImpl(bool aFor
     if (mContext) {
         if(![EAGLContext setCurrentContext:mContext]) {
             return false;
         }
     }
     return true;
 }
 
+void
+GLContextEAGL::ClearMakeCurrent() const
+{
+    MOZ_ALWAYS_TRUE( [EAGLContext setCurrentContext:nullptr] );
+}
+
 bool
 GLContextEAGL::IsCurrent() {
     return [EAGLContext currentContext] == mContext;
 }
 
 bool
 GLContextEAGL::SetupLookupFunction()
 {
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -383,16 +383,23 @@ GLContextEGL::MakeCurrentImpl(bool aForc
         }
     } else {
         MOZ_ASSERT(sEGLLibrary.CachedCurrentContextMatches());
     }
 
     return succeeded;
 }
 
+void
+GLContextEGL::ClearMakeCurrent() const
+{
+    MOZ_ALWAYS_TRUE( sEGLLibrary.fMakeCurrent(sEGLLibrary.Display(), nullptr, nullptr,
+                                              nullptr) );
+}
+
 bool
 GLContextEGL::IsCurrent() {
     return sEGLLibrary.fGetCurrentContext() == mContext;
 }
 
 bool
 GLContextEGL::RenewSurface(CompositorWidget* aWidget) {
     if (!mOwnsContext) {
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -633,16 +633,22 @@ GLContextGLX::MakeCurrentImpl(bool aForc
             const bool isASAP = (gfxPrefs::LayoutFrameRate() == 0);
             mGLX->fSwapInterval(mDisplay, mDrawable, isASAP ? 0 : 1);
         }
     }
 
     return succeeded;
 }
 
+void
+GLContextGLX::ClearMakeCurrent() const
+{
+    MOZ_ALWAYS_TRUE( mGLX->fMakeCurrent(mDisplay, nullptr, nullptr) );
+}
+
 bool
 GLContextGLX::IsCurrent() {
     return mGLX->fGetCurrentContext() == mContext;
 }
 
 bool
 GLContextGLX::SetupLookupFunction()
 {
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -334,16 +334,22 @@ GLContextWGL::MakeCurrentImpl(bool aForc
     if (aForce || sWGLLib.mSymbols.fGetCurrentContext() != mContext) {
         succeeded = sWGLLib.mSymbols.fMakeCurrent(mDC, mContext);
         NS_ASSERTION(succeeded, "Failed to make GL context current!");
     }
 
     return succeeded;
 }
 
+void
+GLContextWGL::ClearMakeCurrent() const
+{
+    MOZ_ALWAYS_TRUE( sWGLLib.mSymbols.fMakeCurrent(mDC, 0) );
+}
+
 bool
 GLContextWGL::IsCurrent()
 {
     return sWGLLib.mSymbols.fGetCurrentContext() == mContext;
 }
 
 void
 GLContextWGL::SetIsDoubleBuffered(bool aIsDB)
--- a/gfx/gl/GLContextWGL.h
+++ b/gfx/gl/GLContextWGL.h
@@ -41,16 +41,17 @@ public:
     static GLContextWGL* Cast(GLContext* gl) {
         MOZ_ASSERT(gl->GetContextType() == GLContextType::WGL);
         return static_cast<GLContextWGL*>(gl);
     }
 
     bool Init() override;
 
     virtual bool MakeCurrentImpl(bool aForce) override;
+    virtual void ClearMakeCurrent() const override;
 
     virtual bool IsCurrent() override;
 
     void SetIsDoubleBuffered(bool aIsDB);
 
     virtual bool IsDoubleBuffered() const override;
 
     virtual bool SwapBuffers() override;