Bug 1382185 - Clear MakeCurrent when MakeCurrent fails. - r=nical
MozReview-Commit-ID: GVvkNUbg3dZ
--- 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;