Bug 1243907 - Don't query _BITS enums on Core profiles. - r=jrmuizel
authorJeff Gilbert <jgilbert@mozilla.com>
Fri, 22 Jan 2016 18:00:54 -0800
changeset 305947 78bd3a5e7968df4535c711f4665a707be91e8f11
parent 305946 f6e4f2f869a326e461989bd4c821b7228ee45cb5
child 305948 344e78cc7e06cf0650967cb024343387b9ccaf0d
push id9214
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:25:21 +0000
treeherdermozilla-aurora@8849dd1a4a79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1243907
milestone47.0a1
Bug 1243907 - Don't query _BITS enums on Core profiles. - r=jrmuizel
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextState.cpp
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -822,17 +822,18 @@ protected:
     WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
     WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
 
 // -----------------------------------------------------------------------------
 // State and State Requests (WebGLContextState.cpp)
 public:
     void Disable(GLenum cap);
     void Enable(GLenum cap);
-    bool GetStencilBits(GLint* out_stencilBits);
+    bool GetStencilBits(GLint* const out_stencilBits);
+    bool GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val);
     virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
 
     void GetParameter(JSContext* cx, GLenum pname,
                       JS::MutableHandle<JS::Value> retval, ErrorResult& rv)
     {
         retval.set(GetParameter(cx, pname, rv));
     }
 
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -989,16 +989,20 @@ WebGLContext::Hint(GLenum target, GLenum
 {
     if (IsContextLost())
         return;
 
     bool isValid = false;
 
     switch (target) {
     case LOCAL_GL_GENERATE_MIPMAP_HINT:
+        // Deprecated and removed in desktop GL Core profiles.
+        if (gl->IsCoreProfile())
+            return;
+
         isValid = true;
         break;
 
     case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
         if (IsWebGL2() ||
             IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives))
         {
             isValid = true;
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -68,17 +68,17 @@ StringValue(JSContext* cx, const nsAStri
         rv.Throw(NS_ERROR_OUT_OF_MEMORY);
         return JS::NullValue();
     }
 
     return JS::StringValue(jsStr);
 }
 
 bool
-WebGLContext::GetStencilBits(GLint* out_stencilBits)
+WebGLContext::GetStencilBits(GLint* const out_stencilBits)
 {
     *out_stencilBits = 0;
     if (mBoundDrawFramebuffer) {
         if (mBoundDrawFramebuffer->StencilAttachment().IsDefined() &&
             mBoundDrawFramebuffer->DepthStencilAttachment().IsDefined())
         {
             // Error, we don't know which stencil buffer's bits to use
             ErrorInvalidFramebufferOperation("getParameter: framebuffer has two stencil buffers bound");
@@ -92,19 +92,117 @@ WebGLContext::GetStencilBits(GLint* out_
         }
     } else if (mOptions.stencil) {
         *out_stencilBits = 8;
     }
 
     return true;
 }
 
+bool
+WebGLContext::GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val)
+{
+    if (mBoundDrawFramebuffer) {
+        if (!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
+            return false;
+    }
+
+    if (!mBoundDrawFramebuffer) {
+        switch (pname) {
+        case LOCAL_GL_RED_BITS:
+        case LOCAL_GL_GREEN_BITS:
+        case LOCAL_GL_BLUE_BITS:
+            *out_val = 8;
+            break;
+
+        case LOCAL_GL_ALPHA_BITS:
+            *out_val = (mOptions.alpha ? 8 : 0);
+            break;
+
+        case LOCAL_GL_DEPTH_BITS:
+            if (mOptions.depth) {
+                const auto& glFormats = gl->GetGLFormats();
+
+                GLenum depthFormat = glFormats.depth;
+                if (mOptions.stencil && glFormats.depthStencil) {
+                    depthFormat = glFormats.depthStencil;
+                }
+
+                if (depthFormat == LOCAL_GL_DEPTH_COMPONENT16) {
+                    *out_val = 16;
+                } else {
+                    *out_val = 24;
+                }
+            } else {
+                *out_val = 0;
+            }
+            break;
+
+        case LOCAL_GL_STENCIL_BITS:
+            *out_val = (mOptions.stencil ? 8 : 0);
+            break;
+
+        default:
+            MOZ_CRASH("bad pname");
+        }
+        return true;
+    }
+
+    if (!gl->IsCoreProfile()) {
+        gl->fGetIntegerv(pname, out_val);
+        return true;
+    }
+
+    GLenum fbAttachment = 0;
+    GLenum fbPName = 0;
+    switch (pname) {
+    case LOCAL_GL_RED_BITS:
+        fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
+        break;
+
+    case LOCAL_GL_GREEN_BITS:
+        fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
+        break;
+
+    case LOCAL_GL_BLUE_BITS:
+        fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
+        break;
+
+    case LOCAL_GL_ALPHA_BITS:
+        fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
+        break;
+
+    case LOCAL_GL_DEPTH_BITS:
+        fbAttachment = LOCAL_GL_DEPTH_ATTACHMENT;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
+        break;
+
+    case LOCAL_GL_STENCIL_BITS:
+        fbAttachment = LOCAL_GL_STENCIL_ATTACHMENT;
+        fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
+        break;
+
+    default:
+        MOZ_CRASH("bad pname");
+    }
+
+    gl->fGetFramebufferAttachmentParameteriv(LOCAL_GL_DRAW_FRAMEBUFFER, fbAttachment,
+                                             fbPName, out_val);
+    return true;
+}
+
 JS::Value
 WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
 {
+    const char funcName[] = "getParameter";
+
     if (IsContextLost())
         return JS::NullValue();
 
     MakeContextCurrent();
 
     if (MinCapabilityMode()) {
         switch(pname) {
             ////////////////////////////
@@ -351,52 +449,46 @@ WebGLContext::GetParameter(JSContext* cx
             // Assuming stencils have 8 bits
             const GLint stencilMask = (1 << stencilBits) - 1;
 
             GLint refValue = 0;
             gl->fGetIntegerv(pname, &refValue);
 
             return JS::Int32Value(refValue & stencilMask);
         }
-        case LOCAL_GL_STENCIL_BITS: {
-            GLint stencilBits = 0;
-            GetStencilBits(&stencilBits);
-            return JS::Int32Value(stencilBits);
-        }
+
         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_MAX_VERTEX_ATTRIBS:
         case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
         case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-        case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
-        case LOCAL_GL_RED_BITS:
-        case LOCAL_GL_GREEN_BITS:
-        case LOCAL_GL_BLUE_BITS: {
+        case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: {
             GLint i = 0;
             gl->fGetIntegerv(pname, &i);
             return JS::Int32Value(i);
         }
-        case LOCAL_GL_DEPTH_BITS: {
-            GLint i = 0;
-            if (!mNeedsFakeNoDepth) {
-                gl->fGetIntegerv(pname, &i);
-            }
-            return JS::Int32Value(i);
+
+        case LOCAL_GL_RED_BITS:
+        case LOCAL_GL_GREEN_BITS:
+        case LOCAL_GL_BLUE_BITS:
+        case LOCAL_GL_ALPHA_BITS:
+        case LOCAL_GL_DEPTH_BITS:
+        case LOCAL_GL_STENCIL_BITS: {
+            // Deprecated and removed in GL Core profiles, so special handling required.
+            GLint val;
+            if (!GetChannelBits(funcName, pname, &val))
+                return JS::NullValue();
+
+            return JS::Int32Value(val);
         }
-        case LOCAL_GL_ALPHA_BITS: {
-            GLint i = 0;
-            if (!mNeedsFakeNoAlpha) {
-                gl->fGetIntegerv(pname, &i);
-            }
-            return JS::Int32Value(i);
-        }
+
         case LOCAL_GL_MAX_TEXTURE_SIZE:
             return JS::Int32Value(mImplMaxTextureSize);
 
         case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
             return JS::Int32Value(mImplMaxCubeMapTextureSize);
 
         case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
             return JS::Int32Value(mImplMaxRenderbufferSize);