Bug 1081286 - WebGL2: account for the fact that SRGB formats break the 1:1 mapping between sized formats and (unsized format, type) pairs - r=jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Sat, 11 Oct 2014 19:07:33 -0400
changeset 209980 27fdae08d9d80fa38cb823b04ebe14001becf216
parent 209979 e1e2f5a56066a898fa1c5737bba016bc6f889154
child 209981 72af2eacba6553a55078db5f3a1f9dd939421e9b
push id50309
push userbjacob@mozilla.com
push dateSat, 11 Oct 2014 23:07:50 +0000
treeherdermozilla-inbound@27fdae08d9d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1081286
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1081286 - WebGL2: account for the fact that SRGB formats break the 1:1 mapping between sized formats and (unsized format, type) pairs - r=jgilbert
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLContextValidate.cpp
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -3870,34 +3870,30 @@ WebGLContext::TexSubImage2D_base(TexImag
     }
 
     if (!tex->HasImageInfoAt(texImageTarget, level)) {
         return ErrorInvalidOperation("texSubImage2D: no previously defined texture image");
     }
 
     const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
     const TexInternalFormat existingEffectiveInternalFormat = imageInfo.EffectiveInternalFormat();
-    TexInternalFormat existingUnsizedInternalFormat = LOCAL_GL_NONE;
-    TexType existingType = LOCAL_GL_NONE;
-    UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(existingEffectiveInternalFormat,
-                                                            &existingUnsizedInternalFormat,
-                                                            &existingType);
-
-    if (!ValidateTexImage(2, texImageTarget, level, existingUnsizedInternalFormat.get(),
+
+    if (!ValidateTexImage(2, texImageTarget, level,
+                          existingEffectiveInternalFormat.get(),
                           xoffset, yoffset, 0,
                           width, height, 0,
                           0, format, type, func))
     {
         return;
     }
 
     if (!ValidateTexInputData(type, jsArrayType, func))
         return;
 
-    if (type != existingType) {
+    if (type != TypeFromInternalFormat(existingEffectiveInternalFormat)) {
         return ErrorInvalidOperation("texSubImage2D: type differs from that of the existing image");
     }
 
     size_t srcTexelSize = size_t(-1);
     if (srcFormat == WebGLTexelFormat::Auto) {
         const size_t bitsPerTexel = GetBitsPerTexel(existingEffectiveInternalFormat);
         MOZ_ASSERT((bitsPerTexel % 8) == 0); // should not have compressed formats here.
         srcTexelSize = bitsPerTexel / 8;
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -1137,32 +1137,54 @@ WebGLContext::ValidateTexImage(GLuint di
         ErrorInvalidValue("%s: border must be 0", info);
         return false;
     }
 
     /* Check incoming image format and type */
     if (!ValidateTexImageFormatAndType(format, type, func))
         return false;
 
+    if (!TexInternalFormat::IsValueLegal(internalFormat)) {
+        ErrorInvalidEnum("%s: invalid internalformat enum %s", info, EnumName(internalFormat));
+        return false;
+    }
+    TexInternalFormat unsizedInternalFormat =
+        UnsizedInternalFormatFromInternalFormat(internalFormat);
+
     if (IsCompressedFunc(func)) {
         if (!ValidateCompTexImageInternalFormat(internalFormat, func)) {
             return false;
         }
     } else if (IsCopyFunc(func)) {
-        if (!ValidateCopyTexImageInternalFormat(internalFormat, func)) {
+        if (!ValidateCopyTexImageInternalFormat(unsizedInternalFormat.get(), func)) {
             return false;
         }
-    } else if (format != internalFormat) {
+    } else if (format != unsizedInternalFormat) {
         if (IsWebGL2()) {
             // In WebGL2, it's OK to have internalformat != format if internalformat is the sized
             // internal format corresponding to the (format, type) pair according to Table 3.2
             // in the OpenGL ES 3.0.3 spec.
             if (internalFormat != EffectiveInternalFormatFromInternalFormatAndType(format, type)) {
-                ErrorInvalidOperation("%s: internalformat does not match format and type", info);
-                return false;
+                bool exceptionallyAllowed = false;
+                if (internalFormat == LOCAL_GL_SRGB8_ALPHA8 &&
+                    format == LOCAL_GL_RGBA &&
+                    type == LOCAL_GL_UNSIGNED_BYTE)
+                {
+                    exceptionallyAllowed = true;
+                }
+                else if (internalFormat == LOCAL_GL_SRGB8 &&
+                         format == LOCAL_GL_RGB &&
+                         type == LOCAL_GL_UNSIGNED_BYTE)
+                {
+                    exceptionallyAllowed = true;
+                }
+                if (!exceptionallyAllowed) {
+                    ErrorInvalidOperation("%s: internalformat does not match format and type", info);
+                    return false;
+                }
             }
         } else {
             // in WebGL 1, format must be equal to internalformat
             ErrorInvalidOperation("%s: internalformat does not match format", info);
             return false;
         }
     }