Bug 1427668 - Use shadows instead of calling into GL. - r=daoshengmu draft
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 20 Dec 2017 16:47:17 -0800
changeset 716058 fbf39a9ef3f4101680592b266aeb637af731b6f7
parent 716057 5920c29cbb658ac49a968cea842eb0acf01a1fd8
child 716059 6db100ee45ef15813d7e98c419b56445f7bea1c5
push id94316
push userbmo:jgilbert@mozilla.com
push dateFri, 05 Jan 2018 03:14:09 +0000
reviewersdaoshengmu
bugs1427668
milestone59.0a1
Bug 1427668 - Use shadows instead of calling into GL. - r=daoshengmu MozReview-Commit-ID: 1ZFwDNboet3
dom/canvas/WebGLContextState.cpp
dom/canvas/WebGLFramebuffer.h
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebGLContext.h"
 
 #include "GLContext.h"
 #include "GLScreenBuffer.h"
 #include "mozilla/dom/ToJSValue.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/Preferences.h"
 #include "nsString.h"
 #include "WebGLBuffer.h"
 #include "WebGLContextUtils.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLProgram.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLShader.h"
@@ -100,21 +101,17 @@ WebGLContext::GetChannelBits(const char*
             *out_val = 8;
             break;
 
         case LOCAL_GL_ALPHA_BITS:
             *out_val = (mOptions.alpha ? 8 : 0);
             break;
 
         case LOCAL_GL_DEPTH_BITS:
-            if (mOptions.depth) {
-                *out_val = gl->Screen()->DepthBits();
-            } else {
-                *out_val = 0;
-            }
+            *out_val = (mOptions.depth ? 24 : 0);
             break;
 
         case LOCAL_GL_STENCIL_BITS:
             *out_val = (mOptions.stencil ? 8 : 0);
             break;
 
         default:
             MOZ_CRASH("GFX: bad pname");
@@ -367,22 +364,44 @@ WebGLContext::GetParameter(JSContext* cx
             const GLint stencilMask = (1 << stencilBits) - 1;
 
             GLint refValue = 0;
             gl->fGetIntegerv(pname, &refValue);
 
             return JS::Int32Value(refValue & stencilMask);
         }
 
+        case LOCAL_GL_SAMPLE_BUFFERS:
+        case LOCAL_GL_SAMPLES: {
+            const auto& fb = mBoundDrawFramebuffer;
+            auto samples = [&]() -> Maybe<uint32_t> {
+                if (!fb) {
+                    if (!EnsureDefaultFB())
+                        return Nothing();
+                    return Some(mDefaultFB->mSamples);
+                }
+
+                if (!fb->IsCheckFramebufferStatusComplete(funcName))
+                    return Some(0);
+
+                DoBindFB(fb, LOCAL_GL_FRAMEBUFFER);
+                return Some(gl->GetIntAs<uint32_t>(LOCAL_GL_SAMPLES));
+            }();
+            if (samples && pname == LOCAL_GL_SAMPLE_BUFFERS) {
+                samples = Some(uint32_t(bool(samples.value())));
+            }
+            if (!samples)
+                return JS::NullValue();
+            return JS::NumberValue(samples.value());
+        }
+
         case LOCAL_GL_STENCIL_CLEAR_VALUE:
         case LOCAL_GL_UNPACK_ALIGNMENT:
         case LOCAL_GL_PACK_ALIGNMENT:
-        case LOCAL_GL_SUBPIXEL_BITS:
-        case LOCAL_GL_SAMPLE_BUFFERS:
-        case LOCAL_GL_SAMPLES: {
+        case LOCAL_GL_SUBPIXEL_BITS: {
             GLint i = 0;
             gl->fGetIntegerv(pname, &i);
             return JS::Int32Value(i);
         }
 
         case LOCAL_GL_RED_BITS:
         case LOCAL_GL_GREEN_BITS:
         case LOCAL_GL_BLUE_BITS:
@@ -460,19 +479,22 @@ WebGLContext::GetParameter(JSContext* cx
         case LOCAL_GL_POLYGON_OFFSET_UNITS:
         case LOCAL_GL_SAMPLE_COVERAGE_VALUE: {
             GLfloat f = 0.f;
             gl->fGetFloatv(pname, &f);
             return JS::DoubleValue(f);
         }
 
         // bool
+        case LOCAL_GL_DEPTH_TEST:
+            return JS::BooleanValue(mDepthTestEnabled);
+        case LOCAL_GL_STENCIL_TEST:
+            return JS::BooleanValue(mStencilTestEnabled);
+
         case LOCAL_GL_BLEND:
-        case LOCAL_GL_DEPTH_TEST:
-        case LOCAL_GL_STENCIL_TEST:
         case LOCAL_GL_CULL_FACE:
         case LOCAL_GL_DITHER:
         case LOCAL_GL_POLYGON_OFFSET_FILL:
         case LOCAL_GL_SCISSOR_TEST:
         case LOCAL_GL_SAMPLE_COVERAGE_INVERT:
         case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE:
         case LOCAL_GL_SAMPLE_COVERAGE:
         case LOCAL_GL_DEPTH_WRITEMASK: {
@@ -551,20 +573,20 @@ WebGLContext::GetParameter(JSContext* cx
             if (!obj) {
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
             return JS::ObjectOrNullValue(obj);
         }
 
         // 4 bools
         case LOCAL_GL_COLOR_WRITEMASK: {
-            realGLboolean gl_bv[4] = { 0 };
-            gl->fGetBooleanv(pname, gl_bv);
-            bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]),
-                             bool(gl_bv[2]), bool(gl_bv[3]) };
+            const bool vals[4] = { bool(mColorWriteMask & (1 << 0)),
+                                   bool(mColorWriteMask & (1 << 1)),
+                                   bool(mColorWriteMask & (1 << 2)),
+                                   bool(mColorWriteMask & (1 << 3)) };
             JS::Rooted<JS::Value> arr(cx);
             if (!dom::ToJSValue(cx, vals, &arr)) {
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
             return arr;
         }
 
         case LOCAL_GL_ARRAY_BUFFER_BINDING: {
--- a/dom/canvas/WebGLFramebuffer.h
+++ b/dom/canvas/WebGLFramebuffer.h
@@ -263,16 +263,20 @@ public:
 
     bool IsResolvedComplete() const { return bool(mResolvedCompleteData); }
     void InvalidateFramebufferStatus(const char* funcName);
     void RefreshResolvedData();
 
     ////////////////
     // WebGL funcs
 
+    bool IsCheckFramebufferStatusComplete(const char* const funcName) const {
+        return CheckFramebufferStatus(funcName) == LOCAL_GL_FRAMEBUFFER_COMPLETE;
+    }
+
     FBStatus CheckFramebufferStatus(const char* funcName) const;
     void FramebufferRenderbuffer(const char* funcName, GLenum attachment, GLenum rbtarget,
                                  WebGLRenderbuffer* rb);
     void FramebufferTexture2D(const char* funcName, GLenum attachment,
                               GLenum texImageTarget, WebGLTexture* tex, GLint level);
     void FramebufferTextureLayer(const char* funcName, GLenum attachment,
                                  WebGLTexture* tex, GLint level, GLint layer);
     void DrawBuffers(const char* funcName, const dom::Sequence<GLenum>& buffers);