Bug 785734 - reject certain rare, but legal, texImage2D calls to work around a driver bug - r=jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Fri, 28 Sep 2012 07:41:45 -0400
changeset 114774 a0bae754ad5db339d4baa377ae6491df9434257a
parent 114773 3e9d3ac81cb00bfc459b81617cb0dc8b91933b05
child 114775 9946c7e4dd92a9053445fb1b0bab394f99b37553
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs785734
milestone18.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 785734 - reject certain rare, but legal, texImage2D calls to work around a driver bug - r=jgilbert
content/canvas/src/WebGLContextGL.cpp
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -667,16 +667,39 @@ WebGLContext::CopyTexSubImage2D_base(Web
     const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
     WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
     const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
 
     MakeContextCurrent();
 
+    WebGLTexture *tex = activeBoundTextureForTarget(target);
+
+    if (!tex)
+        return ErrorInvalidOperation("%s: no texture is bound to this target");
+
+#ifdef MOZ_X11
+    // bug 785734
+    if (gl->WorkAroundDriverBugs() &&
+        mIsMesa &&
+        level > 0 &&
+        !sub)
+    {
+        size_t face = WebGLTexture::FaceForTarget(target);
+        if (!tex->HasImageInfoAt(0, face) ||
+            tex->ImageInfoAt(0, face).Width() <= width)
+        {
+            return  ErrorInvalidOperation("%s: rejecting valid call to avoid Mesa driver crash. "
+                                          "See Mozilla bug 785734",
+                                          info);
+        }
+    }
+#endif
+
     if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
         if (sub)
             gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
         else
             gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
     } else {
 
         // the rect doesn't fit in the framebuffer
@@ -4661,17 +4684,16 @@ WebGLContext::TexImage2D_base(WebGLenum 
         if (!(is_pot_assuming_nonnegative(width) &&
               is_pot_assuming_nonnegative(height)))
             return ErrorInvalidValue("texImage2D: with level > 0, width and height must be powers of two");
     }
 
     if (border != 0)
         return ErrorInvalidValue("texImage2D: border must be 0");
 
-
     if (format == LOCAL_GL_DEPTH_COMPONENT || format == LOCAL_GL_DEPTH_STENCIL) {
         if (IsExtensionEnabled(WEBGL_depth_texture)) {
             if (target != LOCAL_GL_TEXTURE_2D || data != NULL || level != 0)
                 return ErrorInvalidOperation("texImage2D: "
                                              "with format of DEPTH_COMPONENT or DEPTH_STENCIL "
                                              "target must be TEXTURE_2D, "
                                              "data must be NULL, "
                                              "level must be zero");
@@ -4712,16 +4734,32 @@ WebGLContext::TexImage2D_base(WebGLenum 
         return ErrorInvalidOperation("texImage2D: no texture is bound to this target");
 
     MakeContextCurrent();
 
     // Handle ES2 and GL differences in floating point internal formats.  Note that
     // format == internalformat, as checked above and as required by ES.
     internalformat = InternalFormatForFormatAndType(format, type, gl->IsGLES2());
 
+#ifdef MOZ_X11
+    // bug 785734
+    if (gl->WorkAroundDriverBugs() &&
+        mIsMesa &&
+        level > 0)
+    {
+        size_t face = WebGLTexture::FaceForTarget(target);
+        if (!tex->HasImageInfoAt(0, face) ||
+            tex->ImageInfoAt(0, face).Width() <= width)
+        {
+            return  ErrorInvalidOperation("texImage2D: rejecting valid call to avoid Mesa driver crash. "
+                                          "See Mozilla bug 785734");
+        }
+    }
+#endif
+
     GLenum error = LOCAL_GL_NO_ERROR;
 
     if (byteLength) {
         size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
 
         size_t dstPlainRowSize = dstTexelSize * width;
         size_t unpackAlignment = mPixelStoreUnpackAlignment;
         size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;