Bug 1305832 - Only glClear for ANGLE's ANGLE_depth_texture textures. - r=ethlin draft
authorJeff Gilbert <jdashg@gmail.com>
Thu, 08 Dec 2016 12:58:23 -1000
changeset 448304 0a2d81b9f4065d25a8cfec010d96a9e34c7decab
parent 447845 16e8874ba87f7b055aae1f32e90a1c20ccbc33d3
child 448305 f60be4d2cd1568cfc400309a590ad956c35e90e3
push id38310
push userbmo:jgilbert@mozilla.com
push dateFri, 09 Dec 2016 20:23:01 +0000
reviewersethlin
bugs1305832
milestone53.0a1
Bug 1305832 - Only glClear for ANGLE's ANGLE_depth_texture textures. - r=ethlin MozReview-Commit-ID: H6yE1ib2TRI
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLTextureUpload.cpp
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -2216,77 +2216,55 @@ Intersect(uint32_t srcSize, int32_t dstS
     // [=====|==]    // dst box
     // ^-----^
     *out_intStartInDst = std::max<int32_t>(0, 0 - dstStartInSrc);
 
     int32_t intEndInSrc = std::min<int32_t>(srcSize, dstStartInSrc + dstSize);
     *out_intSize = std::max<int32_t>(0, intEndInSrc - *out_intStartInSrc);
 }
 
-static bool
-ZeroTexImageWithClear(WebGLContext* webgl, GLContext* gl, TexImageTarget target,
-                      GLuint tex, uint32_t level, const webgl::FormatUsageInfo* usage,
-                      uint32_t width, uint32_t height)
+static void
+ZeroANGLEDepthTexture(WebGLContext* webgl, GLuint tex,
+                      const webgl::FormatUsageInfo* usage, uint32_t width,
+                      uint32_t height)
 {
-    MOZ_ASSERT(gl->IsCurrent());
-
-    ScopedFramebuffer scopedFB(gl);
-    ScopedBindFramebuffer scopedBindFB(gl, scopedFB.FB());
-
-    const auto format = usage->format;
-
+    const auto& format = usage->format;
     GLenum attachPoint = 0;
     GLbitfield clearBits = 0;
 
-    if (format->IsColorFormat()) {
-        attachPoint = LOCAL_GL_COLOR_ATTACHMENT0;
-        clearBits = LOCAL_GL_COLOR_BUFFER_BIT;
-    }
-
     if (format->d) {
         attachPoint = LOCAL_GL_DEPTH_ATTACHMENT;
         clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
     }
 
     if (format->s) {
         attachPoint = (format->d ? LOCAL_GL_DEPTH_STENCIL_ATTACHMENT
                                  : LOCAL_GL_STENCIL_ATTACHMENT);
         clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
     }
 
     MOZ_RELEASE_ASSERT(attachPoint && clearBits, "GFX: No bits cleared.");
 
-    {
-        gl::GLContext::LocalErrorScope errorScope(*gl);
-        MOZ_ASSERT(target != LOCAL_GL_TEXTURE_2D_ARRAY &&
-                   target != LOCAL_GL_TEXTURE_3D);
-        gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachPoint, target.get(), tex,
-                                  level);
-        if (errorScope.GetError()) {
-            MOZ_ASSERT(false);
-            return false;
-        }
-    }
-
-    auto status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
-    if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
-        return false;
-
-    {
-        gl::GLContext::LocalErrorScope errorScope(*gl);
-
-        const bool fakeNoAlpha = false;
-        webgl->ForceClearFramebufferWithDefaultValues(clearBits, fakeNoAlpha);
-        if (errorScope.GetError()) {
-            MOZ_ASSERT(false);
-            return false;
-        }
-    }
-
-    return true;
+    ////
+    const auto& gl = webgl->gl;
+    MOZ_ASSERT(gl->IsCurrent());
+
+    ScopedFramebuffer scopedFB(gl);
+    ScopedBindFramebuffer scopedBindFB(gl, scopedFB.FB());
+
+    gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachPoint, LOCAL_GL_TEXTURE_2D,
+                              tex, 0);
+
+    const auto& status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+    MOZ_RELEASE_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
+
+    ////
+
+    const bool fakeNoAlpha = false;
+    webgl->ForceClearFramebufferWithDefaultValues(clearBits, fakeNoAlpha);
 }
 
 bool
 ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
                 TexImageTarget target, uint32_t level,
                 const webgl::FormatUsageInfo* usage, uint32_t width, uint32_t height,
                 uint32_t depth)
 {
@@ -2355,22 +2333,26 @@ ZeroTextureData(WebGLContext* webgl, con
                                                    width, height, depth, sizedFormat,
                                                    byteCount, zeros.get());
         return !error;
     }
 
     const auto driverUnpackInfo = usage->idealUnpack;
     MOZ_RELEASE_ASSERT(driverUnpackInfo, "GFX: ideal unpack info not set.");
 
-    if (!webgl->IsWebGL2() && usage->format->d) {
+    if (webgl->IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture) &&
+        gl->IsANGLE() &&
+        usage->format->d)
+    {
         // ANGLE_depth_texture does not allow uploads, so we have to clear.
-        const bool success = ZeroTexImageWithClear(webgl, gl, target, tex, level, usage,
-                                                   width, height);
-        MOZ_ASSERT(success);
-        return success;
+        // (Restriction because of D3D9)
+        MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D);
+        MOZ_ASSERT(level == 0);
+        ZeroANGLEDepthTexture(webgl, tex, usage, width, height);
+        return true;
     }
 
     const webgl::PackingInfo packing = driverUnpackInfo->ToPacking();
 
     const auto bytesPerPixel = webgl::BytesPerPixel(packing);
 
     CheckedUint32 checkedByteCount = bytesPerPixel;
     checkedByteCount *= width;
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1952,26 +1952,39 @@ DoCopyTexOrSubImage(WebGLContext* webgl,
     Intersect(srcTotalHeight, yWithinSrc, dstHeight, &readY, &writeY, &rwHeight);
 
     ////
 
     GLenum error = 0;
     do {
         const auto& idealUnpack = dstUsage->idealUnpack;
         if (!isSubImage) {
-            const auto& pi = idealUnpack->ToPacking();
-            const auto& bpp = BytesPerPixel(pi);
-            const UniqueBuffer zeros(calloc(1, dstWidth * dstHeight * bpp));
-            if (!zeros.get()) {
-                webgl->ErrorOutOfMemory("%s: Ran out of memory allocating zeros.",
-                                        funcName);
-                return false;
+            UniqueBuffer buffer;
+
+            if (rwWidth != dstWidth || rwHeight != dstHeight) {
+                const auto& pi = idealUnpack->ToPacking();
+                CheckedUint32 byteCount = BytesPerPixel(pi);
+                byteCount *= dstWidth;
+                byteCount *= dstHeight;
+
+                if (byteCount.isValid()) {
+                    buffer = calloc(1, byteCount.value());
+                }
+
+                if (!buffer.get()) {
+                    webgl->ErrorOutOfMemory("%s: Ran out of memory allocating zeros.",
+                                            funcName);
+                    return false;
+                }
             }
+
+            const ScopedUnpackReset unpackReset(webgl);
+            gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1);
             error = DoTexImage(gl, target, level, idealUnpack, dstWidth, dstHeight, 1,
-                               zeros.get());
+                               buffer.get());
             if (error)
                 break;
         }
 
         if (!rwWidth || !rwHeight) {
             // There aren't any pixels to copy, so we're 'done'.
             return true;
         }