Bug 1427668 - ColorMask(0xf) for backbuffer resolve. - r=daoshengmu draft
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 20 Dec 2017 01:55:50 -0800
changeset 716056 09ab8290f710c3b4ed307a9173333ae104e6a684
parent 716055 f7144948a0e50cc2c7287e0559b22c193d22a8ba
child 716057 5920c29cbb658ac49a968cea842eb0acf01a1fd8
push id94316
push userbmo:jgilbert@mozilla.com
push dateFri, 05 Jan 2018 03:14:09 +0000
reviewersdaoshengmu
bugs1427668
milestone59.0a1
Bug 1427668 - ColorMask(0xf) for backbuffer resolve. - r=daoshengmu MozReview-Commit-ID: KZJZ0Lc0vbC
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextFramebufferOperations.cpp
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1430,21 +1430,22 @@ WebGLContext::ForceClearFramebufferWithD
     const bool initializeDepthBuffer = bool(clearBits & LOCAL_GL_DEPTH_BUFFER_BIT);
     const bool initializeStencilBuffer = bool(clearBits & LOCAL_GL_STENCIL_BUFFER_BIT);
 
     // Fun GL fact: No need to worry about the viewport here, glViewport is just
     // setting up a coordinates transformation, it doesn't affect glClear at all.
     AssertCachedGlobalState();
 
     // Prepare GL state for clearing.
-    gl->fDisable(LOCAL_GL_SCISSOR_TEST);
+    if (mScissorTestEnabled) {
+        gl->fDisable(LOCAL_GL_SCISSOR_TEST);
+    }
 
     if (initializeColorBuffer) {
-        gl->fColorMask(1, 1, 1, 1);
-        mDriverColorMask = 0x0f;
+        DoColorMask(0x0f);
 
         if (fakeNoAlpha) {
             gl->fClearColor(0.0f, 0.0f, 0.0f, 1.0f);
         } else {
             gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         }
     }
 
@@ -1464,18 +1465,19 @@ WebGLContext::ForceClearFramebufferWithD
     if (mRasterizerDiscardEnabled) {
         gl->fDisable(LOCAL_GL_RASTERIZER_DISCARD);
     }
 
     // Do the clear!
     gl->fClear(clearBits);
 
     // And reset!
-    if (mScissorTestEnabled)
+    if (mScissorTestEnabled) {
         gl->fEnable(LOCAL_GL_SCISSOR_TEST);
+    }
 
     if (mRasterizerDiscardEnabled) {
         gl->fEnable(LOCAL_GL_RASTERIZER_DISCARD);
     }
 
     // Restore GL state after clearing.
     if (initializeColorBuffer) {
         gl->fClearColor(mColorClearValue[0],
@@ -1505,16 +1507,18 @@ WebGLContext::OnEndOfFrame() const
    }
    mDataAllocGLCallCount = 0;
    gl->ResetSyncCallCount("WebGLContext PresentScreenBuffer");
 }
 
 void
 WebGLContext::BlitBackbufferToCurDriverFB() const
 {
+    DoColorMask(0x0f);
+
     if (mScissorTestEnabled) {
         gl->fDisable(LOCAL_GL_SCISSOR_TEST);
     }
 
     [&]() {
         const auto& size = mDefaultFB->mSize;
 
         if (gl->IsSupported(GLFeature::framebuffer_blit)) {
@@ -2072,16 +2076,28 @@ WebGLContext::BindDefaultFBForRead(const
 
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB);
     BlitBackbufferToCurDriverFB();
 
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mResolvedDefaultFB->mFB);
     return true;
 }
 
+void
+WebGLContext::DoColorMask(const uint8_t bitmask) const
+{
+    if (mDriverColorMask != bitmask) {
+        mDriverColorMask = bitmask;
+        gl->fColorMask(bool(mDriverColorMask & (1 << 0)),
+                       bool(mDriverColorMask & (1 << 1)),
+                       bool(mDriverColorMask & (1 << 2)),
+                       bool(mDriverColorMask & (1 << 3)));
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 ScopedDrawCallWrapper::ScopedDrawCallWrapper(WebGLContext& webgl)
     : mWebGL(webgl)
 {
     uint8_t driverColorMask = mWebGL.mColorWriteMask;
     bool driverDepthTest    = mWebGL.mDepthTestEnabled;
     bool driverStencilTest  = mWebGL.mStencilTestEnabled;
@@ -2092,23 +2108,17 @@ ScopedDrawCallWrapper::ScopedDrawCallWra
         } else {
             driverColorMask &= ~(uint8_t(mWebGL.mNeedsFakeNoAlpha) << 3);
         }
         driverDepthTest   &= !mWebGL.mNeedsFakeNoDepth;
         driverStencilTest &= !mWebGL.mNeedsFakeNoStencil;
     }
 
     const auto& gl = mWebGL.gl;
-    if (mWebGL.mDriverColorMask != driverColorMask) {
-        mWebGL.mDriverColorMask = driverColorMask;
-        gl->fColorMask(bool(mWebGL.mDriverColorMask & (1 << 0)),
-                       bool(mWebGL.mDriverColorMask & (1 << 1)),
-                       bool(mWebGL.mDriverColorMask & (1 << 2)),
-                       bool(mWebGL.mDriverColorMask & (1 << 3)));
-    }
+    mWebGL.DoColorMask(driverColorMask);
     if (mWebGL.mDriverDepthTest != driverDepthTest) {
         // "When disabled, the depth comparison and subsequent possible updates to the
         //  depth buffer value are bypassed and the fragment is passed to the next
         //  operation." [GLES 3.0.5, p177]
         mWebGL.mDriverDepthTest = driverDepthTest;
         gl->SetEnabled(LOCAL_GL_DEPTH_TEST, mWebGL.mDriverDepthTest);
     }
     if (mWebGL.mDriverStencilTest != driverStencilTest) {
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1998,16 +1998,17 @@ protected:
     bool EnsureDefaultFB() const;
     bool ValidateAndInitFB(const char* funcName, const WebGLFramebuffer* fb);
     void DoBindFB(const WebGLFramebuffer* fb, GLenum target = LOCAL_GL_FRAMEBUFFER) const;
 
     bool BindCurFBForDraw(const char* funcName);
     bool BindCurFBForColorRead(const char* funcName,
                                const webgl::FormatUsageInfo** out_format,
                                uint32_t* out_width, uint32_t* out_height);
+    void DoColorMask(uint8_t bitmask) const;
     void BlitBackbufferToCurDriverFB() const;
     bool BindDefaultFBForRead(const char* funcName);
 
     // --
 
 public:
     void LoseOldestWebGLContextIfLimitExceeded();
     void UpdateLastUseIndex();
--- a/dom/canvas/WebGLContextFramebufferOperations.cpp
+++ b/dom/canvas/WebGLContextFramebufferOperations.cpp
@@ -126,17 +126,16 @@ WebGLContext::ClearStencil(GLint v)
 }
 
 void
 WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
 {
     if (IsContextLost())
         return;
 
-    gl->fColorMask(r, g, b, a);
     mColorWriteMask = uint8_t(bool(r)) << 0 |
                       uint8_t(bool(g)) << 1 |
                       uint8_t(bool(b)) << 2 |
                       uint8_t(bool(a)) << 3;
 }
 
 void
 WebGLContext::DepthMask(WebGLboolean b)