Bug 1449264 - Handle texStorage3D's `levels` better. - r=kvark draft
authorJeff Gilbert <jgilbert@mozilla.com>
Mon, 02 Apr 2018 12:31:00 -0700
changeset 776353 59d0854859b91e290d1b535ae38f05c470c9b385
parent 775051 dcd10220d55aea46db212314c46d25a96a7be243
push id104844
push userbmo:jgilbert@mozilla.com
push dateMon, 02 Apr 2018 21:30:04 +0000
reviewerskvark
bugs1449264
milestone61.0a1
Bug 1449264 - Handle texStorage3D's `levels` better. - r=kvark MozReview-Commit-ID: G6ubd4iR67s
dom/canvas/WebGLTextureUpload.cpp
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1103,26 +1103,22 @@ WebGLTexture::TexStorage(const char* fun
     if (!width || !height || !depth) {
         mContext->ErrorInvalidValue("%s: Dimensions must be non-zero.", funcName);
         return;
     }
 
     const TexImageTarget testTarget = IsCubeMap() ? LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X
                                                   : target.get();
     WebGLTexture::ImageInfo* baseImageInfo;
-    WebGLTexture::ImageInfo* lastImageInfo;
     if (!ValidateTexImageSpecification(funcName, testTarget, 0, width, height, depth,
-                                       &baseImageInfo) ||
-        !ValidateTexImageSpecification(funcName, testTarget, levels-1, 1, 1, 1,
-                                       &lastImageInfo))
+                                       &baseImageInfo))
     {
         return;
     }
     MOZ_ALWAYS_TRUE(baseImageInfo);
-    MOZ_ALWAYS_TRUE(lastImageInfo);
 
     auto dstUsage = mContext->mFormatUsage->GetSizedTexUsage(sizedFormat);
     if (!dstUsage) {
         mContext->ErrorInvalidEnum("%s: Invalid internalformat: 0x%04x", funcName,
                                    sizedFormat);
         return;
     }
     auto dstFormat = dstUsage->format;
@@ -1135,25 +1131,34 @@ WebGLTexture::TexStorage(const char* fun
                                                     dstFormat, width, height, depth))
         {
             return;
         }
     }
 
     ////////////////////////////////////
 
-    const auto lastLevel = levels - 1;
-    MOZ_ASSERT(lastLevel <= 31, "Right-shift is only defined for bits-1.");
+    const bool levelsOk = [&]() {
+        // Right-shift is only defined for bits-1, which is too large anyways.
+        const auto lastLevel = uint32_t(levels - 1);
+        if (lastLevel > 31)
+            return false;
+
+        const auto lastLevelWidth = uint32_t(width) >> lastLevel;
+        const auto lastLevelHeight = uint32_t(height) >> lastLevel;
 
-    const uint32_t lastLevelWidth = uint32_t(width) >> lastLevel;
-    const uint32_t lastLevelHeight = uint32_t(height) >> lastLevel;
-    const uint32_t lastLevelDepth = uint32_t(depth) >> lastLevel;
-
-    // If these are all zero, then some earlier level was the final 1x1x1 level.
-    if (!lastLevelWidth && !lastLevelHeight && !lastLevelDepth) {
+        // If these are all zero, then some earlier level was the final 1x1(x1) level.
+        bool ok = lastLevelWidth && lastLevelHeight;
+        if (target == LOCAL_GL_TEXTURE_3D) {
+            const auto lastLevelDepth = uint32_t(depth) >> lastLevel;
+            ok &= bool(lastLevelDepth);
+        }
+        return ok;
+    }();
+    if (!levelsOk) {
         mContext->ErrorInvalidOperation("%s: Too many levels requested for the given"
                                         " dimensions. (levels: %u, width: %u, height: %u,"
                                         " depth: %u)",
                                         funcName, levels, width, height, depth);
         return;
     }
 
     ////////////////////////////////////