diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index e7cfc10150ec..883f4e4b6e33 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -2401,6 +2401,12 @@ uint32_t GetBytesPerTexel(GLenum format, GLenum type) { return 0; } +void GLContext::ResetTLSCurrentContext() { + if (sCurrentContext.init()) { + sCurrentContext.set(nullptr); + } +} + bool GLContext::MakeCurrent(bool aForce) const { if (MOZ_UNLIKELY(IsContextLost())) return false; diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 113371bc4282..2e895f226ea3 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -187,6 +187,8 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { bool mImplicitMakeCurrent = false; bool mUseTLSIsCurrent; + static void ResetTLSCurrentContext(); + class TlsScope final { const WeakPtr mGL; const bool mWasTlsOk; diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm index 1608ebb9e5d0..2e205c1434fe 100644 --- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -86,6 +86,8 @@ CGLContextObj GLContextCGL::GetCGLContext() const { bool GLContextCGL::MakeCurrentImpl() const { if (mContext) { + GLContext::ResetTLSCurrentContext(); + [mContext makeCurrentContext]; MOZ_ASSERT(IsCurrentImpl()); // Use non-blocking swap in "ASAP mode". diff --git a/gfx/gl/GLContextProviderEAGL.mm b/gfx/gl/GLContextProviderEAGL.mm index a314bd672dcf..6e2749802846 100644 --- a/gfx/gl/GLContextProviderEAGL.mm +++ b/gfx/gl/GLContextProviderEAGL.mm @@ -92,6 +92,8 @@ bool GLContextEAGL::RecreateRB() { bool GLContextEAGL::MakeCurrentImpl() const { if (mContext) { + GLContext::ResetTLSCurrentContext(); + if (![EAGLContext setCurrentContext:mContext]) { return false; } diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index f1c9aaab4b79..cb47e285a50c 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -1219,7 +1219,6 @@ RefPtr GLContextEGL::CreateWithoutSurface( /*static*/ void GLContextEGL::DestroySurface(EglDisplay& aEgl, const EGLSurface aSurface) { if (aSurface != EGL_NO_SURFACE) { - // TODO: This breaks TLS MakeCurrent caching. if (!aEgl.fMakeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { const EGLint err = aEgl.mLib->fGetError(); gfxCriticalNote << "Error in eglMakeCurrent: " << gfx::hexa(err); diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index 5868426becd2..9786e31307b3 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -163,12 +163,16 @@ bool WGLLibrary::EnsureInitialized() { const auto curCtx = mSymbols.fGetCurrentContext(); const auto curDC = mSymbols.fGetCurrentDC(); + GLContext::ResetTLSCurrentContext(); + if (!mSymbols.fMakeCurrent(mRootDc, mDummyGlrc)) { NS_WARNING("wglMakeCurrent failed"); return false; } - const auto resetContext = - MakeScopeExit([&]() { mSymbols.fMakeCurrent(curDC, curCtx); }); + const auto resetContext = MakeScopeExit([&]() { + GLContext::ResetTLSCurrentContext(); + mSymbols.fMakeCurrent(curDC, curCtx); + }); const auto loader = GetSymbolLoader(); @@ -302,6 +306,8 @@ GLContextWGL::~GLContextWGL() { } bool GLContextWGL::MakeCurrentImpl() const { + GLContext::ResetTLSCurrentContext(); + const bool succeeded = sWGLLib.mSymbols.fMakeCurrent(mDC, mContext); NS_ASSERTION(succeeded, "Failed to make GL context current!"); return succeeded; diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index 525cf33b59e9..de296508bbb0 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -11,8 +11,7 @@ #include "base/platform_thread.h" // for PlatformThreadId #include "gfxEnv.h" -#include "GLConsts.h" -#include "GLTypes.h" +#include "GLContext.h" #include "mozilla/EnumTypeTraits.h" #include "mozilla/gfx/Logging.h" #include "mozilla/Maybe.h" @@ -266,7 +265,6 @@ class GLLibraryEGL final { const bool CHECK_CONTEXT_OWNERSHIP = true; if (CHECK_CONTEXT_OWNERSHIP) { const MutexAutoLock lock(mMutex); - const auto tid = PlatformThread::CurrentId(); const auto prevCtx = fGetCurrentContext(); @@ -289,6 +287,11 @@ class GLLibraryEGL final { } } + // Always reset the TLS current context. + // If we're called by TLS-caching MakeCurrent, after we return true, + // the caller will set the TLS correctly anyway. + GLContext::ResetTLSCurrentContext(); + WRAP(fMakeCurrent(dpy, draw, read, ctx)); } diff --git a/gfx/gl/GLXLibrary.h b/gfx/gl/GLXLibrary.h index 7a004762ff50..d2577c935cc9 100644 --- a/gfx/gl/GLXLibrary.h +++ b/gfx/gl/GLXLibrary.h @@ -6,7 +6,7 @@ #ifndef GFX_GLXLIBRARY_H #define GFX_GLXLIBRARY_H -#include "GLContextTypes.h" +#include "GLContext.h" #include "mozilla/Assertions.h" #include "mozilla/DataMutex.h" #include "mozilla/gfx/XlibDisplay.h" @@ -65,6 +65,7 @@ class GLXLibrary final { Bool fMakeCurrent(Display* display, GLXDrawable drawable, GLXContext context) const { DECL_WRAPPER_SCOPE(display) + GLContext::ResetTLSCurrentContext(); return mSymbols.fMakeCurrent(display, drawable, context); }