From 39cd4ea8339b912923717a21a59f85a4d2cc4b7d Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Wed, 11 Mar 2015 18:23:56 -0700 Subject: [PATCH] Bug 1128001 - Workaround ANGLE DEPTH16 being DEPTH24_STENCIL8. - r=kamidphish --- dom/canvas/WebGLContext.cpp | 23 ++++++++++++++++++----- dom/canvas/WebGLContext.h | 14 ++++++++++++-- dom/canvas/WebGLContextState.cpp | 6 ++++-- dom/canvas/WebGLContextUtils.cpp | 4 ++-- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 549c63e6c3fb..0c10937af4b5 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -205,6 +205,7 @@ WebGLContext::WebGLContext() , mBypassShaderValidation(false) , mGLMaxSamples(1) , mNeedsFakeNoAlpha(false) + , mNeedsFakeNoStencil(false) { mGeneration = 0; mInvalidated = false; @@ -236,9 +237,10 @@ WebGLContext::WebGLContext() mViewportWidth = 0; mViewportHeight = 0; - mScissorTestEnabled = 0; mDitherEnabled = 1; mRasterizerDiscardEnabled = 0; // OpenGL ES 3.0 spec p244 + mScissorTestEnabled = 0; + mStencilTestEnabled = 0; // initialize some GL values: we're going to get them from the GL and use them as the sizes of arrays, // so in case glGetIntegerv leaves them uninitialized because of a GL bug, we would have very weird crashes. @@ -899,9 +901,13 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) ++mGeneration; // Update our internal stuff: - if (gl->WorkAroundDriverBugs()) { + if (gl->WorkAroundDriverBugs() && gl->IsANGLE()) { if (!mOptions.alpha && gl->Caps().alpha) mNeedsFakeNoAlpha = true; + + // ANGLE doesn't quite handle this properly. + if (gl->Caps().depth && !gl->Caps().stencil) + mNeedsFakeNoStencil = true; } // Update mOptions. @@ -1862,24 +1868,31 @@ size_t mozilla::RoundUpToMultipleOf(size_t value, size_t multiple) WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl) : mWebGL(webgl) - , mNeedsChange(NeedsChange(webgl)) + , mFakeNoAlpha(ShouldFakeNoAlpha(webgl)) + , mFakeNoStencil(ShouldFakeNoStencil(webgl)) { - if (mNeedsChange) { + if (mFakeNoAlpha) { mWebGL.gl->fColorMask(mWebGL.mColorWriteMask[0], mWebGL.mColorWriteMask[1], mWebGL.mColorWriteMask[2], false); } + if (mFakeNoStencil) { + mWebGL.gl->fDisable(LOCAL_GL_STENCIL_TEST); + } } WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround() { - if (mNeedsChange) { + if (mFakeNoAlpha) { mWebGL.gl->fColorMask(mWebGL.mColorWriteMask[0], mWebGL.mColorWriteMask[1], mWebGL.mColorWriteMask[2], mWebGL.mColorWriteMask[3]); } + if (mFakeNoStencil) { + mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index e1ccceb8fc39..fc7fb7182585 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -965,6 +965,7 @@ private: realGLboolean mDitherEnabled; realGLboolean mRasterizerDiscardEnabled; realGLboolean mScissorTestEnabled; + realGLboolean mStencilTestEnabled; bool ValidateCapabilityEnum(GLenum cap, const char* info); realGLboolean* GetStateTrackingSlot(GLenum cap); @@ -1529,12 +1530,14 @@ protected: uint64_t mLastUseIndex; bool mNeedsFakeNoAlpha; + bool mNeedsFakeNoStencil; struct ScopedMaskWorkaround { WebGLContext& mWebGL; - const bool mNeedsChange; + const bool mFakeNoAlpha; + const bool mFakeNoStencil; - static bool NeedsChange(WebGLContext& webgl) { + static bool ShouldFakeNoAlpha(WebGLContext& webgl) { // We should only be doing this if we're about to draw to the backbuffer, but // the backbuffer needs to have this fake-no-alpha workaround. return !webgl.mBoundDrawFramebuffer && @@ -1542,6 +1545,13 @@ protected: webgl.mColorWriteMask[3] != false; } + static bool ShouldFakeNoStencil(WebGLContext& webgl) { + // We should only be doing this if we're about to draw to the backbuffer. + return !webgl.mBoundDrawFramebuffer && + webgl.mNeedsFakeNoStencil && + webgl.mStencilTestEnabled; + } + explicit ScopedMaskWorkaround(WebGLContext& webgl); ~ScopedMaskWorkaround(); diff --git a/dom/canvas/WebGLContextState.cpp b/dom/canvas/WebGLContextState.cpp index 7ea1cff58ba7..ea956e1d6b9b 100644 --- a/dom/canvas/WebGLContextState.cpp +++ b/dom/canvas/WebGLContextState.cpp @@ -628,12 +628,14 @@ realGLboolean* WebGLContext::GetStateTrackingSlot(GLenum cap) { switch (cap) { - case LOCAL_GL_SCISSOR_TEST: - return &mScissorTestEnabled; case LOCAL_GL_DITHER: return &mDitherEnabled; case LOCAL_GL_RASTERIZER_DISCARD: return &mRasterizerDiscardEnabled; + case LOCAL_GL_SCISSOR_TEST: + return &mScissorTestEnabled; + case LOCAL_GL_STENCIL_TEST: + return &mStencilTestEnabled; } return nullptr; diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp index 914bbec0ff4b..2666662b9861 100644 --- a/dom/canvas/WebGLContextUtils.cpp +++ b/dom/canvas/WebGLContextUtils.cpp @@ -1097,11 +1097,11 @@ WebGLContext::AssertCachedState() } // Draw state - MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled); MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled); MOZ_ASSERT_IF(IsWebGL2(), gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == mRasterizerDiscardEnabled); - + MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled); + MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_STENCIL_TEST) == mStencilTestEnabled); realGLboolean colorWriteMask[4] = {0, 0, 0, 0}; gl->fGetBooleanv(LOCAL_GL_COLOR_WRITEMASK, colorWriteMask);