[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

zmo at google.com zmo at google.com
Sun Feb 20 22:48:05 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 5a2e490480ce7bd28814de5d70f3e7df1d19aba3
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jan 11 19:49:28 2011 +0000

    2011-01-10  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Need to consider UNPACK_ALIGNMENT in GraphicsContext3D::texImage2DResourceSafe
            https://bugs.webkit.org/show_bug.cgi?id=52068
    
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::copyTexImage2D): Use computeImageSizeInBytes.
            (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
            (WebCore::WebGLRenderingContext::readPixels): Ditto, and fix a bug on generating the wrong error.
            (WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
            (WebCore::WebGLRenderingContext::validateTexFuncData): Use computeImageSizeInBytes.
            * platform/graphics/GraphicsContext3D.cpp:
            (WebCore::GraphicsContext3D::texImage2DResourceSafe): Add a new parameter alignment.
            (WebCore::GraphicsContext3D::computeFormatAndTypeParameters): Add more supported format/type.
            (WebCore::GraphicsContext3D::computeImageSizeInBytes): Added.
            * platform/graphics/GraphicsContext3D.h:
    2011-01-10  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Need to consider UNPACK_ALIGNMENT in GraphicsContext3D::texImage2DResourceSafe
            https://bugs.webkit.org/show_bug.cgi?id=52068
    
            * fast/canvas/webgl/read-pixels-test-expected.txt:
            * fast/canvas/webgl/read-pixels-test.html: Sync with khronos.
            * fast/canvas/webgl/resources/webgl-test.js: Add finishTest().
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75524 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 003e73b..6b2d421 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2011-01-10  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Need to consider UNPACK_ALIGNMENT in GraphicsContext3D::texImage2DResourceSafe
+        https://bugs.webkit.org/show_bug.cgi?id=52068
+
+        * fast/canvas/webgl/read-pixels-test-expected.txt:
+        * fast/canvas/webgl/read-pixels-test.html: Sync with khronos.
+        * fast/canvas/webgl/resources/webgl-test.js: Add finishTest().
+
 2011-01-07  Enrica Casucci  <enrica at apple.com>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/fast/canvas/webgl/read-pixels-test-expected.txt b/LayoutTests/fast/canvas/webgl/read-pixels-test-expected.txt
index 959818e..8986c88 100644
--- a/LayoutTests/fast/canvas/webgl/read-pixels-test-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/read-pixels-test-expected.txt
@@ -131,14 +131,20 @@ PASS color pixel at 1, 1 should be about 0
 PASS getError was expected value: NO_ERROR : there should be no GL errors
 
 check disallowed formats
-PASS getError was expected value: INVALID_ENUM : Should not be able to read as RGB / UNSIGNED_BYTE
+PASS getError was expected value: INVALID_OPERATION : Should not be able to read as RGB / UNSIGNED_BYTE
 PASS getError was expected value: INVALID_OPERATION : Should not be able to read as RGB / UNSIGNED_SHORT_5_6_5
-PASS getError was expected value: INVALID_ENUM : Should not be able to read as RGBA / UNSIGNED_SHORT_5_5_5_1
-PASS getError was expected value: INVALID_ENUM : Should not be able to read as RGBA / UNSIGNED_SHORT_4_4_4_4
-PASS getError was expected value: INVALID_ENUM : Should not be able to read as ALPHA / UNSIGNED_BYTE
+PASS getError was expected value: INVALID_OPERATION : Should not be able to read as RGBA / UNSIGNED_SHORT_5_5_5_1
+PASS getError was expected value: INVALID_OPERATION : Should not be able to read as RGBA / UNSIGNED_SHORT_4_4_4_4
+PASS getError was expected value: INVALID_OPERATION : Should not be able to read as ALPHA / UNSIGNED_BYTE
 PASS getError was expected value: INVALID_ENUM : Should not be able to read as LUMINANCE / UNSIGNED_BYTE
 PASS getError was expected value: INVALID_ENUM : Should not be able to read as LUMINANCE_ALPHA / UNSIGNED_BYTE
 
+check reading with lots of drawing
+PASS actual is expected
+PASS actual is expected
+PASS actual is expected
+PASS getError was expected value: NO_ERROR : there should be no GL errors
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/read-pixels-test.html b/LayoutTests/fast/canvas/webgl/read-pixels-test.html
index 5ae0e5e..082a87f 100644
--- a/LayoutTests/fast/canvas/webgl/read-pixels-test.html
+++ b/LayoutTests/fast/canvas/webgl/read-pixels-test.html
@@ -20,173 +20,200 @@ var canvas = document.getElementById("example");
 var gl = create3DContext(canvas);
 
 if (window.initNonKhronosFramework) {
-   window.initNonKhronosFramework(false);
+   window.initNonKhronosFramework(true);
 }
 
+var actual;
+var expected;
 var width = 2;
 var height = 2;
+var continueTestFunc = continueTestPart1;
 
 gl.clearColor(1, 1, 1, 1);
 gl.clear(gl.COLOR_BUFFER_BIT);
 
 // Resize the canvas to 2x2. This is an attempt to get stuff in the backbuffer.
 // that shouldn't be there.
+canvas.addEventListener("webglcontextrestored", continueTestAfterContextRestored, false);
 canvas.width = width;
 canvas.height = height;
+if (gl.getError() != gl.CONTEXT_LOST_WEBGL) {
+  continueTestPart1();
+}
 
-gl.clearColor(0.5, 0.7, 1.0, 1);
-gl.clear(gl.COLOR_BUFFER_BIT);
-
-var innerColor = [0.5, 0.7, 1.0, 1];
-var outerColor = [0, 0, 0, 0];
-
-var tests = [
-  { msg: 'in range', checkColor: innerColor, x:  0, y:  0,
-    oneColor: innerColor, oneX: 0, oneY: 0},
-  { msg: 'off top left', checkColor: outerColor, x: -1, y: -1,
-    oneColor: innerColor, oneX: 1, oneY: 1},
-  { msg: 'off bottom right', checkColor: outerColor, x:  1, y:  1,
-    oneColor: innerColor, oneX: 0, oneY: 0},
-  { msg: 'completely off top ', checkColor: outerColor, x:  0, y: -2,
-    oneColor: outerColor, oneX: 0, oneY: 0},
-  { msg: 'completely off bottom', checkColor: outerColor, x:  0, y:  2,
-    oneColor: outerColor, oneX: 0, oneY: 0},
-  { msg: 'completely off left', checkColor: outerColor, x: -2, y:  0,
-    oneColor: outerColor, oneX: 0, oneY: 0},
-  { msg: 'completeley off right', checkColor: outerColor, x:  2, y:  0,
-    oneColor: outerColor, oneX: 0, oneY: 0}
-];
-
-for (var tt = 0; tt < tests.length; ++tt) {
-  var test = tests[tt];
-  debug("");
-  debug("checking: " + test.msg);
-  checkBuffer(test.checkColor, test.x, test.y,
-              test.oneColor, test.oneX, test.oneY);
+function continueTestAfterContextRestored() {
+  window.gl = create3DContext(canvas);
+  var func = continueTestFunc;
+  window.continueTestFunc = function() { testFailed("should not be here"); };
+  func();
 }
 
-glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
-
-function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
-  var buf = new Uint8Array(width * height * 4);
-  gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
-  for (var yy = 0; yy < height; ++yy) {
-    for (var xx = 0; xx < width; ++xx) {
-      var offset = (yy * width + xx) * 4;
-      var expectedColors = (oneX == xx && oneY == yy) ? oneColor : checkColor;
-      for (var cc = 0; cc < 4; ++cc) {
-        var expectedColor = expectedColors[cc] * 255;
-        var color = buf[offset + cc];
-        var diff = Math.abs(expectedColor - color);
-        assertMsg(diff < 3,
-                  "color pixel at " + xx + ", " + yy + " should be about " + expectedColor);
+function continueTestPart1() {
+  gl.clearColor(0.5, 0.7, 1.0, 1);
+  gl.clear(gl.COLOR_BUFFER_BIT);
+
+  var innerColor = [0.5, 0.7, 1.0, 1];
+  var outerColor = [0, 0, 0, 0];
+
+  var tests = [
+    { msg: 'in range', checkColor: innerColor, x:  0, y:  0,
+      oneColor: innerColor, oneX: 0, oneY: 0},
+    { msg: 'off top left', checkColor: outerColor, x: -1, y: -1,
+      oneColor: innerColor, oneX: 1, oneY: 1},
+    { msg: 'off bottom right', checkColor: outerColor, x:  1, y:  1,
+      oneColor: innerColor, oneX: 0, oneY: 0},
+    { msg: 'completely off top ', checkColor: outerColor, x:  0, y: -2,
+      oneColor: outerColor, oneX: 0, oneY: 0},
+    { msg: 'completely off bottom', checkColor: outerColor, x:  0, y:  2,
+      oneColor: outerColor, oneX: 0, oneY: 0},
+    { msg: 'completely off left', checkColor: outerColor, x: -2, y:  0,
+      oneColor: outerColor, oneX: 0, oneY: 0},
+    { msg: 'completeley off right', checkColor: outerColor, x:  2, y:  0,
+      oneColor: outerColor, oneX: 0, oneY: 0}
+  ];
+
+  for (var tt = 0; tt < tests.length; ++tt) {
+    var test = tests[tt];
+    debug("");
+    debug("checking: " + test.msg);
+    checkBuffer(test.checkColor, test.x, test.y,
+                test.oneColor, test.oneX, test.oneY);
+  }
+
+  glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
+
+  function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
+    var buf = new Uint8Array(width * height * 4);
+    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+    for (var yy = 0; yy < height; ++yy) {
+      for (var xx = 0; xx < width; ++xx) {
+        var offset = (yy * width + xx) * 4;
+        var expectedColors = (oneX == xx && oneY == yy) ? oneColor : checkColor;
+        for (var cc = 0; cc < 4; ++cc) {
+          var expectedColor = expectedColors[cc] * 255;
+          var color = buf[offset + cc];
+          var diff = Math.abs(expectedColor - color);
+          assertMsg(diff < 3,
+                    "color pixel at " + xx + ", " + yy + " should be about " + expectedColor);
+        }
       }
     }
   }
-}
 
-var badFormats = [
-  {
-    format: gl.RGB,
-    type: gl.UNSIGNED_BYTE,
-    dest: new Uint8Array(3)
-  },
-  {
-    format: gl.RGB,
-    type: gl.UNSIGNED_SHORT_5_6_5,
-    dest: new Uint8Array(3)
-  },
-  {
-    format: gl.RGBA,
-    type: gl.UNSIGNED_SHORT_5_5_5_1,
-    dest: new Uint16Array(1)
-  },
-  {
-    format: gl.RGBA,
-    type: gl.UNSIGNED_SHORT_4_4_4_4,
-    dest: new Uint16Array(1)
-  },
-  {
-    format: gl.ALPHA,
-    type: gl.UNSIGNED_BYTE,
-    dest: new Uint8Array(1)
-  },
-  {
-    format: gl.LUMINANCE,
-    type: gl.UNSIGNED_BYTE,
-    dest: new Uint8Array(1) },
-  {
-    format: gl.LUMINANCE_ALPHA,
-    type: gl.UNSIGNED_BYTE,
-    dest: new Uint8Array(2)
+  var badFormats = [
+    {
+      format: gl.RGB,
+      type: gl.UNSIGNED_BYTE,
+      dest: new Uint8Array(3),
+      error: gl.INVALID_OPERATION
+    },
+    {
+      format: gl.RGB,
+      type: gl.UNSIGNED_SHORT_5_6_5,
+      dest: new Uint8Array(3),
+      error: gl.INVALID_OPERATION
+    },
+    {
+      format: gl.RGBA,
+      type: gl.UNSIGNED_SHORT_5_5_5_1,
+      dest: new Uint16Array(1),
+      error: gl.INVALID_OPERATION
+    },
+    {
+      format: gl.RGBA,
+      type: gl.UNSIGNED_SHORT_4_4_4_4,
+      dest: new Uint16Array(1),
+      error: gl.INVALID_OPERATION
+    },
+    {
+      format: gl.ALPHA,
+      type: gl.UNSIGNED_BYTE,
+      dest: new Uint8Array(1),
+      error: gl.INVALID_OPERATION
+    },
+    {
+      format: gl.LUMINANCE,
+      type: gl.UNSIGNED_BYTE,
+      dest: new Uint8Array(1),
+      error: gl.INVALID_ENUM
+    },
+    {
+      format: gl.LUMINANCE_ALPHA,
+      type: gl.UNSIGNED_BYTE,
+      dest: new Uint8Array(2),
+      error: gl.INVALID_ENUM
+    }
+  ];
+  debug("");
+  debug("check disallowed formats");
+  for (var tt = 0; tt < badFormats.length; ++ tt) {
+    var info = badFormats[tt]
+    var format = info.format;
+    var type = info.type;
+    var dest = info.dest;
+    var error = info.error;
+    gl.readPixels(0, 0, 1, 1, format, type, dest);
+    // note that the GL error is INVALID_OPERATION if both format and type are invalid, but
+    // INVALID_ENUM if only one is.
+    glErrorShouldBe(
+        gl, error,
+        "Should not be able to read as " + wtu.glEnumToString(gl, format) +
+        " / " + wtu.glEnumToString(gl, type));
+  }
+
+  debug("");
+  debug("check reading with lots of drawing");
+  continueTestFunc = continueTestPart2;
+  width = 1024;
+  height = 1024;
+  canvas.width = width;
+  canvas.height = height;
+  if (gl.getError() != gl.CONTEXT_LOST_WEBGL) {
+    continueTestPart2();
   }
-];
-debug("");
-debug("check disallowed formats");
-for (var tt = 0; tt < badFormats.length; ++ tt) {
-  var info = badFormats[tt]
-  var format = info.format;
-  var type = info.type;
-  var dest = info.dest;
-  gl.readPixels(0, 0, 1, 1, format, type, dest);
-  // note that the GL error is INVALID_OPERATION if both format and type are invalid, but
-  // INVALID_ENUM if only one is.
-  glErrorShouldBe(
-      gl, (format == gl.RGBA || type == gl.UNSIGNED_BYTE) ? gl.INVALID_ENUM : gl.INVALID_OPERATION,
-      "Should not be able to read as " + wtu.glEnumToString(gl, format) +
-      " / " + wtu.glEnumToString(gl, type));
 }
 
-/*
-debug("");
-debug("check reading with lots of drawing");
-width = 1024;
-height = 1024;
-canvas.width = width;
-canvas.height = height;
-gl.viewport(0, 0, 1024, 1024);
-var program = wtu.setupTexturedQuad(gl);
-var loc = gl.getUniformLocation(program, "tex");
-gl.disable(gl.BLEND);
-gl.disable(gl.DEPTH_TEST);
-var colors = [[255, 0, 0, 1], [0, 255, 0, 1], [0, 0, 255, 1]];
-var textures = [];
-var results = [];
-for (var ii = 0; ii < colors.length; ++ii) {
-  gl.activeTexture(gl.TEXTURE0 + ii);
-  var tex = gl.createTexture();
-  wtu.fillTexture(gl, tex, 1, 1, colors[ii]);
-  textures.push(tex);
-}
-for (var ii = 0; ii < colors.length; ++ii) {
-  for (var jj = 0; jj < 300 + ii + 1; ++jj) {
-    gl.uniform1i(loc, jj % 3);
-    gl.drawArrays(gl.TRIANGLES, 0, 6);
+function continueTestPart2() {
+  gl.viewport(0, 0, 1024, 1024);
+  var program = wtu.setupTexturedQuad(gl);
+  var loc = gl.getUniformLocation(program, "tex");
+  gl.disable(gl.BLEND);
+  gl.disable(gl.DEPTH_TEST);
+  var colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255]];
+  var textures = [];
+  var results = [];
+  for (var ii = 0; ii < colors.length; ++ii) {
+    gl.activeTexture(gl.TEXTURE0 + ii);
+    var tex = gl.createTexture();
+    wtu.fillTexture(gl, tex, 1, 1, colors[ii]);
+    textures.push(tex);
   }
-  var buf = new Uint8Array(4);
-  gl.readPixels(512, 512, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
-  results.push(buf);
-  for (var kk = 0; kk < 99; ++kk) {
-    gl.uniform1i(loc, (jj + kk) % 3);
-    gl.drawArrays(gl.TRIANGLES, 0, 6);
+  for (var ii = 0; ii < colors.length; ++ii) {
+    for (var jj = 0; jj < 300 + ii + 1; ++jj) {
+      gl.uniform1i(loc, jj % 3);
+      gl.drawArrays(gl.TRIANGLES, 0, 6);
+    }
+    var buf = new Uint8Array(4);
+    gl.readPixels(512, 512, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+    results.push(buf);
+    for (var kk = 0; kk < 99; ++kk) {
+      gl.uniform1i(loc, (jj + kk) % 3);
+      gl.drawArrays(gl.TRIANGLES, 0, 6);
+    }
   }
-}
-var actual;
-var expected;
-for (var ii = 0; ii < colors.length; ++ii) {
-  var buf = results[ii];
-  var color = colors[ii];
-  actual = [buf[0], buf[1], buf[2], buf[3]];
-  expected = [color[0], color[1], color[2], color[3] * 255];
-  shouldBe("actual", "expected");
-}
-glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
-*/
+  for (var ii = 0; ii < colors.length; ++ii) {
+    var buf = results[ii];
+    var color = colors[ii];
+    actual = [buf[0], buf[1], buf[2], buf[3]];
+    expected = [color[0], color[1], color[2], color[3]];
+    shouldBe("actual", "expected");
+  }
+  glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
 
-debug("");
-successfullyParsed = true;
+  debug("");
+  finishTest();
+}
 </script>
-<script src="../../js/resources/js-test-post.js"></script>
 </body>
 </html>
 
diff --git a/LayoutTests/fast/canvas/webgl/resources/webgl-test.js b/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
index b263a4d..00b4cac 100644
--- a/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
+++ b/LayoutTests/fast/canvas/webgl/resources/webgl-test.js
@@ -27,6 +27,18 @@ function nonKhronosFrameworkNotifyDone() {
   }
 }
 
+function finishTest() {
+  successfullyParsed = true;
+  var epilogue = document.createElement("script")
+  epilogue.onload = function() {
+    if (window.nonKhronosFrameworkNotifyDone) {
+      window.nonKhronosFrameworkNotifyDone();
+    }
+  };
+  epilogue.src = "../../js/resources/js-test-post.js";
+  document.body.appendChild(epilogue);
+}
+
 //
 //----------------------------------------------------------------------
 
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 2cbd4ad..3180d3f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2011-01-10  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Need to consider UNPACK_ALIGNMENT in GraphicsContext3D::texImage2DResourceSafe
+        https://bugs.webkit.org/show_bug.cgi?id=52068
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Use computeImageSizeInBytes.
+        (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::readPixels): Ditto, and fix a bug on generating the wrong error.
+        (WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
+        (WebCore::WebGLRenderingContext::validateTexFuncData): Use computeImageSizeInBytes.
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::texImage2DResourceSafe): Add a new parameter alignment.
+        (WebCore::GraphicsContext3D::computeFormatAndTypeParameters): Add more supported format/type.
+        (WebCore::GraphicsContext3D::computeImageSizeInBytes): Added.
+        * platform/graphics/GraphicsContext3D.h:
+
 2011-01-10  Enrica Casucci  <enrica at apple.com>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 4ffd400..79a26ee 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -708,7 +708,7 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
         long clippedX, clippedY, clippedWidth, clippedHeight;
         if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
             m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
-                                              internalformat, GraphicsContext3D::UNSIGNED_BYTE);
+                                              internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);
             if (clippedWidth > 0 && clippedHeight > 0) {
                 m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
                                              clippedX, clippedY, clippedWidth, clippedHeight);
@@ -751,16 +751,14 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
         if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {
             unsigned long format = tex->getInternalFormat(target, level);
             unsigned long type = tex->getType(target, level);
-            unsigned int componentsPerPixel = 0;
-            unsigned int bytesPerComponent = 0;
-            bool valid = m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent);
-            if (!valid) {
-                m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
-                return;
-            }
             OwnArrayPtr<unsigned char> zero;
             if (width && height) {
-                unsigned long size = componentsPerPixel * bytesPerComponent * width * height;
+                unsigned int size;
+                GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
+                if (error != GraphicsContext3D::NO_ERROR) {
+                    m_context->synthesizeGLError(error);
+                    return;
+                }
                 zero = adoptArrayPtr(new unsigned char[size]);
                 if (!zero) {
                     m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -768,11 +766,7 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
                 }
                 memset(zero.get(), 0, size);
             }
-            if (zero)
-                m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
             m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, zero.get());
-            if (zero)
-                m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
             if (clippedWidth > 0 && clippedHeight > 0) {
                 m_context->copyTexSubImage2D(target, level, xoffset + clippedX - x, yoffset + clippedY - y,
                                              clippedX, clippedY, clippedWidth, clippedHeight);
@@ -2412,30 +2406,35 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
         return;
     }
     // Validate input parameters.
-    unsigned int componentsPerPixel, bytesPerComponent;
-    if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
-        return;
-    }
     if (!pixels) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
-    if (width < 0 || height < 0) {
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+    switch (format) {
+    case GraphicsContext3D::ALPHA:
+    case GraphicsContext3D::RGB:
+    case GraphicsContext3D::RGBA:
+        break;
+    default:
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
-    if (format != GraphicsContext3D::RGBA && type != GraphicsContext3D::UNSIGNED_BYTE) {
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+    switch (type) {
+    case GraphicsContext3D::UNSIGNED_BYTE:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+        break;
+    default:
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
         return;
     }
     if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     // Validate array type against pixel type.
-    if ((type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray())
-        || (type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray())) {
+    if (!pixels->isUnsignedByteArray()) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
@@ -2444,37 +2443,31 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
         return;
     }
     // Calculate array size, taking into consideration of PACK_ALIGNMENT.
-    unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
-    unsigned long padding = 0;
-    unsigned long residualBytes = bytesPerRow % m_packAlignment;
-    if (residualBytes) {
-        padding = m_packAlignment - residualBytes;
-        bytesPerRow += padding;
-    }
-    // The last row needs no padding.
-    unsigned long totalBytes = bytesPerRow * height - padding;
-    unsigned long num = totalBytes / bytesPerComponent;
-    if (pixels->byteLength() / bytesPerComponent < num) {
+    unsigned int totalBytesRequired;
+    unsigned int padding;
+    GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+    if (error != GraphicsContext3D::NO_ERROR) {
+        m_context->synthesizeGLError(error);
+        return;
+    }
+    if (pixels->byteLength() < totalBytesRequired) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
     void* data = pixels->baseAddress();
     m_context->readPixels(x, y, width, height, format, type, data);
-#if PLATFORM(CG)
+#if OS(DARWIN)
     // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
     // when alpha is off, readPixels should set alpha to 255 instead of 0.
-    if ((format == GraphicsContext3D::ALPHA || format == GraphicsContext3D::RGBA) && !m_context->getContextAttributes().alpha) {
-        if (type == GraphicsContext3D::UNSIGNED_BYTE) {
-            unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
-            for (long iy = 0; iy < height; ++iy) {
-                for (long ix = 0; ix < width; ++ix) {
-                    pixels[componentsPerPixel - 1] = 255;
-                    pixels += componentsPerPixel;
-                }
-                pixels += padding;
+    if (!m_context->getContextAttributes().alpha) {
+        unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+        for (long iy = 0; iy < height; ++iy) {
+            for (long ix = 0; ix < width; ++ix) {
+                pixels[3] = 255;
+                pixels += 4;
             }
+            pixels += padding;
         }
-        // FIXME: check whether we need to do the same with UNSIGNED_SHORT.
     }
 #endif
     cleanupAfterGraphicsCall(false);
@@ -2668,7 +2661,7 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
     }
     if (!pixels && !isResourceSafe()) {
         bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
-                                                         border, format, type);
+                                                         border, format, type, m_unpackAlignment);
         if (!succeed)
             return;
     } else {
@@ -4001,20 +3994,12 @@ bool WebGLRenderingContext::validateTexFuncData(long width, long height,
         ASSERT_NOT_REACHED();
     }
 
-    unsigned int componentsPerPixel, bytesPerComponent;
-    if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
-        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+    unsigned int totalBytesRequired;
+    GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+    if (error != GraphicsContext3D::NO_ERROR) {
+        m_context->synthesizeGLError(error);
         return false;
     }
-
-    if (!width || !height)
-        return true;
-    unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent;
-    unsigned int totalRowBytes = validRowBytes;
-    unsigned int remainder = validRowBytes % m_unpackAlignment;
-    if (remainder)
-        totalRowBytes += (m_unpackAlignment - remainder);
-    unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes;
     if (pixels->byteLength() < totalBytesRequired) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return false;
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
index 1224bce..f7c5a66 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -33,6 +33,7 @@
 #include "ArrayBufferView.h"
 #include "CheckedInt.h"
 #include "DrawingBuffer.h"
+#include "Extensions3D.h"
 #include "Image.h"
 #include "ImageData.h"
 
@@ -43,62 +44,6 @@ namespace WebCore {
 
 namespace {
 
-    unsigned int bytesPerComponent(GC3Denum type)
-    {
-        switch (type) {
-        case GraphicsContext3D::UNSIGNED_BYTE:
-            return 1;
-        case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-        case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-        case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-            return 2;
-        case GraphicsContext3D::FLOAT:
-            return 4;
-        default:
-            return 1;
-        }
-    }
-
-    unsigned int componentsPerPixel(GC3Denum format, GC3Denum type)
-    {
-        switch (type) {
-        case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
-        case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
-        case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
-        case GraphicsContext3D::FLOAT:
-            return 1;
-        default:
-            break;
-        }
-        switch (format) {
-        case GraphicsContext3D::ALPHA:
-        case GraphicsContext3D::LUMINANCE:
-            return 1;
-        case GraphicsContext3D::LUMINANCE_ALPHA:
-            return 2;
-        case GraphicsContext3D::RGB:
-            return 3;
-        case GraphicsContext3D::RGBA:
-            return 4;
-        default:
-            return 4;
-        }
-    }
-
-    // This function should only be called if width and height is non-zero and
-    // format/type are valid.  Return 0 if overflow happens.
-    unsigned int imageSizeInBytes(GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type)
-    {
-        ASSERT(width > 0 && height > 0);
-        CheckedInt<uint32_t> checkedWidth(width);
-        CheckedInt<uint32_t> checkedHeight(height);
-        CheckedInt<uint32_t> checkedBytesPerPixel(bytesPerComponent(type) * componentsPerPixel(format, type));
-        CheckedInt<uint32_t> checkedSize = checkedWidth * checkedHeight * checkedBytesPerPixel;
-        if (checkedSize.valid())
-            return checkedSize.value();
-        return 0;
-    }
-
     uint8_t convertColor16LittleTo8(uint16_t value)
     {
         return value >> 8;
@@ -117,17 +62,19 @@ PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize&
     return DrawingBuffer::create(this, size);
 }
 
-bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
+bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment)
 {
+    ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);
     OwnArrayPtr<unsigned char> zero;
     if (width > 0 && height > 0) {
-        unsigned int size = imageSizeInBytes(width, height, format, type);
-        if (!size) {
-            synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+        unsigned int size;
+        GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0);
+        if (error != GraphicsContext3D::NO_ERROR) {
+            synthesizeGLError(error);
             return false;
         }
         zero = adoptArrayPtr(new unsigned char[size]);
-        if (!zero.get()) {
+        if (!zero) {
             synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
             return false;
         }
@@ -155,6 +102,7 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format,
         *componentsPerPixel = 3;
         break;
     case GraphicsContext3D::RGBA:
+    case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
         *componentsPerPixel = 4;
         break;
     default:
@@ -162,16 +110,16 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format,
     }
     switch (type) {
     case GraphicsContext3D::UNSIGNED_BYTE:
-        *bytesPerComponent = sizeof(unsigned char);
+        *bytesPerComponent = sizeof(GC3Dubyte);
         break;
     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
         *componentsPerPixel = 1;
-        *bytesPerComponent = sizeof(unsigned short);
+        *bytesPerComponent = sizeof(GC3Dushort);
         break;
     case GraphicsContext3D::FLOAT: // OES_texture_float
-        *bytesPerComponent = sizeof(float);
+        *bytesPerComponent = sizeof(GC3Dfloat);
         break;
     default:
         return false;
@@ -179,6 +127,44 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format,
     return true;
 }
 
+GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum type, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment,
+                                                    unsigned int* imageSizeInBytes, unsigned int* paddingInBytes)
+{
+    ASSERT(imageSizeInBytes);
+    ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
+    if (width < 0 || height < 0)
+        return GraphicsContext3D::INVALID_VALUE;
+    unsigned int bytesPerComponent, componentsPerPixel;
+    if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
+        return GraphicsContext3D::INVALID_ENUM;
+    if (!width || !height) {
+        *imageSizeInBytes = 0;
+        if (paddingInBytes)
+            *paddingInBytes = 0;
+        return GraphicsContext3D::NO_ERROR;
+    }
+    CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
+    checkedValue *=  width;
+    if (!checkedValue.valid())
+        return GraphicsContext3D::INVALID_VALUE;
+    unsigned int validRowSize = checkedValue.value();
+    unsigned int padding = 0;
+    unsigned int residual = validRowSize % alignment;
+    if (residual) {
+        padding = alignment - residual;
+        checkedValue += padding;
+    }
+    // Last row needs no padding.
+    checkedValue *= (height - 1);
+    checkedValue += validRowSize;
+    if (!checkedValue.valid())
+        return GraphicsContext3D::INVALID_VALUE;
+    *imageSizeInBytes = checkedValue.value();
+    if (paddingInBytes)
+        *paddingInBytes = padding;
+    return GraphicsContext3D::NO_ERROR;
+}
+
 bool GraphicsContext3D::extractImageData(Image* image,
                                          GC3Denum format,
                                          GC3Denum type,
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index a0d2778..10aa0d7 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -47,6 +47,8 @@
 typedef unsigned int GC3Denum;
 typedef unsigned char GC3Dboolean;
 typedef unsigned int GC3Dbitfield;
+typedef unsigned char GC3Dubyte;
+typedef unsigned short GC3Dushort;
 typedef int GC3Dint;
 typedef int GC3Dsizei;
 typedef unsigned int GC3Duint;
@@ -491,7 +493,8 @@ public:
 
     // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
     // Return true if no GL error is synthesized.
-    bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type);
+    // By default, alignment is 4, the OpenGL default setting.
+    bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint alignment = 4);
 
     bool isGLES2Compliant() const;
 
@@ -507,6 +510,19 @@ public:
                                         unsigned int* componentsPerPixel,
                                         unsigned int* bytesPerComponent);
 
+    // Computes the image size in bytes. If paddingInBytes is not null, padding
+    // is also calculated in return. Returns NO_ERROR if succeed, otherwise
+    // return the suggested GL error indicating the cause of the failure:
+    //   INVALID_VALUE if width/height is negative or overflow happens.
+    //   INVALID_ENUM if format/type is illegal.
+    GC3Denum computeImageSizeInBytes(GC3Denum format,
+                                     GC3Denum type,
+                                     GC3Dsizei width,
+                                     GC3Dsizei height,
+                                     GC3Dint alignment,
+                                     unsigned int* imageSizeInBytes,
+                                     unsigned int* paddingInBytes);
+
     // Extracts the contents of the given Image into the passed Vector,
     // packing the pixel data according to the given format and type,
     // and obeying the flipY, premultiplyAlpha, and ignoreGammaAndColorProfile

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list