[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

eric at webkit.org eric at webkit.org
Fri Feb 26 22:23:13 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 8a31a978b3e52679845600d38db44194e7d77396
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Feb 17 21:05:40 2010 +0000

    2010-02-17  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Refactor texImage2D and texSubImage2D taking Image to use common code
            https://bugs.webkit.org/show_bug.cgi?id=34458
    
            Merged the Safari and Chromium code which extracts the data from
            Image objects into common entry points on GraphicsContext3D. This
            immediately fixes the following three problems:
              - Chromium not implementing texSubImage2D taking Image.
              - Safari not obeying the flipY parameter to texImage2D or
                texSubImage2D taking Image.
              - Safari not obeying the premultipyAlpha parameter to texImage2D
                or texSubImage2D taking Image.
            Added new test verifying the behavior of texImage2D and
            texSubImage2D and the flipY parameter. The premultiplyAlpha
            parameter can not be tested yet as the implementation is not yet
            spec compliant. This will be fixed in a follow-on bug.
    
            Ran all WebGL demos in demo repository on Safari and Chromium;
            textures are now the right way up in both browsers, and
            transparent textures in Particles demo now look correct in Safari.
    
            * fast/canvas/webgl/resources/red-green.png: Added.
            * fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-expected.txt: Added.
            * fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html: Added.
    2010-02-17  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Refactor texImage2D and texSubImage2D taking Image to use common code
            https://bugs.webkit.org/show_bug.cgi?id=34458
    
            Merged the Safari and Chromium code which extracts the data from
            Image objects into common entry points on GraphicsContext3D. This
            immediately fixes the following three problems:
              - Chromium not implementing texSubImage2D taking Image.
              - Safari not obeying the flipY parameter to texImage2D or
                texSubImage2D taking Image.
              - Safari not obeying the premultipyAlpha parameter to texImage2D
                or texSubImage2D taking Image.
            Added new test verifying the behavior of texImage2D and
            texSubImage2D and the flipY parameter. The premultiplyAlpha
            parameter can not be tested yet as the implementation is not yet
            spec compliant. This will be fixed in a follow-on bug.
    
            Ran all WebGL demos in demo repository on Safari and Chromium;
            textures are now the right way up in both browsers, and
            transparent textures in Particles demo now look correct in Safari.
    
            Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html
    
            * WebCore.gyp/WebCore.gyp:
            * WebCore.gypi:
            * WebCore.xcodeproj/project.pbxproj:
            * platform/graphics/GraphicsContext3D.cpp: Added.
            (WebCore::GraphicsContext3D::extractImageData):
            (WebCore::GraphicsContext3D::processImageData):
            (WebCore::GraphicsContext3D::premultiplyAlpha):
            (WebCore::GraphicsContext3D::unmultiplyAlpha):
            * platform/graphics/GraphicsContext3D.h:
            (WebCore::GraphicsContext3D::):
            * platform/graphics/cg/GraphicsContext3DCG.cpp: Added.
            (WebCore::GraphicsContext3D::getImageData):
            * platform/graphics/mac/GraphicsContext3DMac.cpp:
            (WebCore::GraphicsContext3D::texImage2D):
            (WebCore::GraphicsContext3D::texSubImage2D):
            * platform/graphics/skia/GraphicsContext3DSkia.cpp: Added.
            (WebCore::GraphicsContext3D::getImageData):
    2010-02-17  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Oliver Hunt.
    
            Refactor texImage2D and texSubImage2D taking Image to use common code
            https://bugs.webkit.org/show_bug.cgi?id=34458
    
            Merged the Safari and Chromium code which extracts the data from
            Image objects into common entry points on GraphicsContext3D. This
            immediately fixes the following three problems:
              - Chromium not implementing texSubImage2D taking Image.
              - Safari not obeying the flipY parameter to texImage2D or
                texSubImage2D taking Image.
              - Safari not obeying the premultipyAlpha parameter to texImage2D
                or texSubImage2D taking Image.
            Added new test verifying the behavior of texImage2D and
            texSubImage2D and the flipY parameter. The premultiplyAlpha
            parameter can not be tested yet as the implementation is not yet
            spec compliant. This will be fixed in a follow-on bug.
    
            Ran all WebGL demos in demo repository on Safari and Chromium;
            textures are now the right way up in both browsers, and
            transparent textures in Particles demo now look correct in Safari.
    
            * src/GraphicsContext3D.cpp:
            (WebCore::GraphicsContext3D::texImage2D):
            (WebCore::GraphicsContext3D::texSubImage2D):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54907 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 06f416d..e02ff77 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,31 @@
+2010-02-17  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Refactor texImage2D and texSubImage2D taking Image to use common code
+        https://bugs.webkit.org/show_bug.cgi?id=34458
+
+        Merged the Safari and Chromium code which extracts the data from
+        Image objects into common entry points on GraphicsContext3D. This
+        immediately fixes the following three problems:
+          - Chromium not implementing texSubImage2D taking Image.
+          - Safari not obeying the flipY parameter to texImage2D or
+            texSubImage2D taking Image.
+          - Safari not obeying the premultipyAlpha parameter to texImage2D
+            or texSubImage2D taking Image.
+        Added new test verifying the behavior of texImage2D and
+        texSubImage2D and the flipY parameter. The premultiplyAlpha
+        parameter can not be tested yet as the implementation is not yet
+        spec compliant. This will be fixed in a follow-on bug.
+
+        Ran all WebGL demos in demo repository on Safari and Chromium;
+        textures are now the right way up in both browsers, and
+        transparent textures in Particles demo now look correct in Safari.
+
+        * fast/canvas/webgl/resources/red-green.png: Added.
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-expected.txt: Added.
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html: Added.
+
 2010-02-17  Nikolas Zimmermann  <nzimmermann at rim.com>
 
         Not reviewed. Try to turn windows slaves again, by skipping two websocket tests that fail reliable.
diff --git a/LayoutTests/fast/canvas/webgl/resources/red-green.png b/LayoutTests/fast/canvas/webgl/resources/red-green.png
new file mode 100644
index 0000000..605ac9b
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/red-green.png differ
diff --git a/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-expected.txt b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-expected.txt
new file mode 100644
index 0000000..a1afa58
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-expected.txt
@@ -0,0 +1,53 @@
+Verify texImage2D and texSubImage2D code paths taking Images, in particular flipY argument
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Regression test for https://bugs.webkit.org/show_bug.cgi?id=34458 : Refactor texImage2D and texSubImage2D taking Image to use common code
+Testing texImage2D with flipY=true
+Checking lower left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Checking upper left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Testing texImage2D with flipY=false
+Checking lower left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Checking upper left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Testing texSubImage2D with flipY=true
+Checking lower left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Checking upper left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Testing texSubImage2D with flipY=false
+Checking lower left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+Checking upper left corner
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS pixel is correctColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html
new file mode 100644
index 0000000..fd41707
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html
@@ -0,0 +1,198 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+<script src="resources/utils3d.js"> </script>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec3 g_Position;
+attribute vec2 g_TexCoord0;
+
+varying vec2 texCoord;
+
+void main()
+{
+    gl_Position = vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);
+    texCoord = g_TexCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+uniform sampler2D tex;
+varying vec2 texCoord;
+
+void main()
+{
+    gl_FragColor = texture2D(tex, texCoord);
+}
+</script>
+
+<script>
+var gl = null;
+var textureLoc = null;
+var successfullyParsed = false;
+
+function init()
+{
+    if (window.layoutTestController) {
+        layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    description('Verify texImage2D and texSubImage2D code paths taking Images, in particular flipY argument');
+
+    debug('Regression test for <a href="https://bugs.webkit.org/show_bug.cgi?id=34458">https://bugs.webkit.org/show_bug.cgi?id=34458</a> : <code>Refactor texImage2D and texSubImage2D taking Image to use common code</code>');
+
+    gl = initWebGL("example", "vshader", "fshader", [ "g_Position", "g_TexCoord0" ], [ 0, 0, 0, 1 ], 1);
+    gl.viewport(0, 0, 32, 32);
+
+    textureLoc = gl.getUniformLocation(gl.program, "tex");
+
+    var vertices = new WebGLFloatArray([
+         1.0,  1.0, 0.0,
+        -1.0,  1.0, 0.0,
+        -1.0, -1.0, 0.0,
+         1.0,  1.0, 0.0,
+        -1.0, -1.0, 0.0,
+         1.0, -1.0, 0.0]);
+    var texCoords = new WebGLFloatArray([
+        1.0, 1.0,
+        0.0, 1.0,
+        0.0, 0.0,
+        1.0, 1.0,
+        0.0, 0.0,
+        1.0, 0.0]);
+    var texCoordOffset = vertices.byteLength;
+
+    var vbo = gl.createBuffer();
+    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+    gl.bufferData(gl.ARRAY_BUFFER,
+                  texCoordOffset + texCoords.byteLength,
+                  gl.STATIC_DRAW);
+    gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
+    gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);
+
+    gl.enableVertexAttribArray(0);
+    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+    gl.enableVertexAttribArray(1);
+    gl.vertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
+
+    loadTexture("resources/red-green.png");
+}
+
+function loadTexture(src) {
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    var image = new Image();
+    image.onload = function() {
+        gl.bindTexture(gl.TEXTURE_2D, texture);
+        gl.texImage2D(gl.TEXTURE_2D, 0, image, true);
+        runTest(image);
+    };
+    image.src = src;
+    return texture;
+}
+
+// These two declarations need to be global for "shouldBe" to see them
+var buf = null;
+var idx = 0;
+var pixel = [0, 0, 0];
+var correctColor = null;
+
+function runOneIteration(image, useTexSubImage2D, flipY, topColor, bottomColor)
+{
+    debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
+          ' with flipY=' + flipY);
+    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+    // Disable any writes to the alpha channel
+    gl.colorMask(1, 1, 1, 0);
+    var texture = gl.createTexture();
+    // Bind the texture to texture unit 0
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    // Set up texture parameters
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    // Upload the image into the texture
+    if (useTexSubImage2D) {
+        // Initialize the texture to black first
+        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, image.width, image.height, 0,
+                      gl.RGBA, gl.UNSIGNED_BYTE, null);
+        gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, image, flipY, false);
+    } else {
+        gl.texImage2D(gl.TEXTURE_2D, 0, image, flipY, false);
+    }
+
+    // Point the uniform sampler to texture unit 0
+    gl.uniform1i(textureLoc, 0);
+    // Draw the triangles
+    gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+    // Read back the rendering results
+    var width = 32;
+    var height = 32;
+    buf = gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE);
+    // Check a few pixels near the top and bottom and make sure they have
+    // the right color.
+    var queryWidth = 2;
+    var queryHeight = 2;
+    debug("Checking lower left corner");
+    var xoff = 4;
+    var yoff = 4;
+    correctColor = bottomColor;
+    for (var y = 0; y < queryHeight; y++) {
+        for (var x = 0; x < queryWidth; x++) {
+            idx = ((yoff + y) * width * 4 +
+                   (xoff + x) * 4);
+            pixel[0] = buf[idx];
+            pixel[1] = buf[idx + 1];
+            pixel[2] = buf[idx + 2];
+            shouldBe("pixel", "correctColor");
+        }
+    }
+    debug("Checking upper left corner");
+    yoff = height - 8;
+    correctColor = topColor;
+    for (var y = 0; y < queryHeight; y++) {
+        for (var x = 0; x < queryWidth; x++) {
+            idx = ((yoff + y) * width * 4 +
+                   (xoff + x) * 4);
+            pixel[0] = buf[idx];
+            pixel[1] = buf[idx + 1];
+            pixel[2] = buf[idx + 2];
+            shouldBe("pixel", "correctColor");
+        }
+    }
+}
+
+function runTest(image)
+{
+    var red = [255, 0, 0];
+    var green = [0, 255, 0];
+    runOneIteration(image, false, true, red, green);
+    runOneIteration(image, false, false, green, red);
+    runOneIteration(image, true, true, red, green);
+    runOneIteration(image, true, false, green, red);
+
+    successfullyParsed = true;
+    var epilogue = document.createElement("script");
+    epilogue.onload = finish;
+    epilogue.src = "../../js/resources/js-test-post.js";
+    document.body.appendChild(epilogue);
+}
+
+function finish() {
+    if (window.layoutTestController) {
+        layoutTestController.notifyDone();
+    }
+}
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="32px" height="32px"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 38041c8..4976d8c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,47 @@
+2010-02-17  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Refactor texImage2D and texSubImage2D taking Image to use common code
+        https://bugs.webkit.org/show_bug.cgi?id=34458
+
+        Merged the Safari and Chromium code which extracts the data from
+        Image objects into common entry points on GraphicsContext3D. This
+        immediately fixes the following three problems:
+          - Chromium not implementing texSubImage2D taking Image.
+          - Safari not obeying the flipY parameter to texImage2D or
+            texSubImage2D taking Image.
+          - Safari not obeying the premultipyAlpha parameter to texImage2D
+            or texSubImage2D taking Image.
+        Added new test verifying the behavior of texImage2D and
+        texSubImage2D and the flipY parameter. The premultiplyAlpha
+        parameter can not be tested yet as the implementation is not yet
+        spec compliant. This will be fixed in a follow-on bug.
+
+        Ran all WebGL demos in demo repository on Safari and Chromium;
+        textures are now the right way up in both browsers, and
+        transparent textures in Particles demo now look correct in Safari.
+
+        Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-image.html
+
+        * WebCore.gyp/WebCore.gyp:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/GraphicsContext3D.cpp: Added.
+        (WebCore::GraphicsContext3D::extractImageData):
+        (WebCore::GraphicsContext3D::processImageData):
+        (WebCore::GraphicsContext3D::premultiplyAlpha):
+        (WebCore::GraphicsContext3D::unmultiplyAlpha):
+        * platform/graphics/GraphicsContext3D.h:
+        (WebCore::GraphicsContext3D::):
+        * platform/graphics/cg/GraphicsContext3DCG.cpp: Added.
+        (WebCore::GraphicsContext3D::getImageData):
+        * platform/graphics/mac/GraphicsContext3DMac.cpp:
+        (WebCore::GraphicsContext3D::texImage2D):
+        (WebCore::GraphicsContext3D::texSubImage2D):
+        * platform/graphics/skia/GraphicsContext3DSkia.cpp: Added.
+        (WebCore::GraphicsContext3D::getImageData):
+
 2010-02-17  Noam Rosenthal  <noam.rosenthal at nokia.com>
 
         Reviewed by Ariya Hidayat.
diff --git a/WebCore/WebCore.gyp/WebCore.gyp b/WebCore/WebCore.gyp/WebCore.gyp
index 54a229e..0c8d035 100644
--- a/WebCore/WebCore.gyp/WebCore.gyp
+++ b/WebCore/WebCore.gyp/WebCore.gyp
@@ -956,6 +956,7 @@
             '../platform/graphics/skia/FloatPointSkia.cpp',
             '../platform/graphics/skia/FloatRectSkia.cpp',
             '../platform/graphics/skia/GradientSkia.cpp',
+            '../platform/graphics/skia/GraphicsContext3DSkia.cpp',
             '../platform/graphics/skia/GraphicsContextSkia.cpp',
             '../platform/graphics/skia/ImageBufferSkia.cpp',
             '../platform/graphics/skia/ImageSkia.cpp',
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index a9f01cf..6191360 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -1977,6 +1977,7 @@
             'platform/graphics/cg/FloatRectCG.cpp',
             'platform/graphics/cg/FloatSizeCG.cpp',
             'platform/graphics/cg/GradientCG.cpp',
+            'platform/graphics/cg/GraphicsContext3DCG.cpp',
             'platform/graphics/cg/GraphicsContextCG.cpp',
             'platform/graphics/cg/GraphicsContextPlatformPrivateCG.h',
             'platform/graphics/cg/ImageBufferCG.cpp',
@@ -2140,6 +2141,7 @@
             'platform/graphics/skia/GradientSkia.cpp',
             'platform/graphics/skia/GraphicsContextPlatformPrivate.h',
             'platform/graphics/skia/GraphicsContextSkia.cpp',
+            'platform/graphics/skia/GraphicsContext3DSkia.cpp',
             'platform/graphics/skia/ImageBufferSkia.cpp',
             'platform/graphics/skia/ImageSkia.cpp',
             'platform/graphics/skia/IntPointSkia.cpp',
@@ -2277,6 +2279,7 @@
             'platform/graphics/Gradient.h',
             'platform/graphics/GraphicsContext.cpp',
             'platform/graphics/GraphicsContext.h',
+            'platform/graphics/GraphicsContext3D.cpp',
             'platform/graphics/GraphicsContext3D.h',
             'platform/graphics/GraphicsContextPrivate.h',
             'platform/graphics/GraphicsLayer.cpp',
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 27db90c..8ba5e4b 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -1237,6 +1237,8 @@
 		65DF323C09D1DE65000BE325 /* JSCanvasPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DF323609D1DE65000BE325 /* JSCanvasPattern.h */; };
 		65DF326109D1E199000BE325 /* UserAgentStyleSheetsData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 656581AF09D14EE6000E61D7 /* UserAgentStyleSheetsData.cpp */; };
 		65FEA86909833ADE00BED4AB /* Page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FEA86809833ADE00BED4AB /* Page.cpp */; };
+		6E21C6C01126338500A7BE02 /* GraphicsContext3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E21C6BF1126338500A7BE02 /* GraphicsContext3D.cpp */; };
+		6E21C6C21126339900A7BE02 /* GraphicsContext3DCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E21C6C11126339900A7BE02 /* GraphicsContext3DCG.cpp */; };
 		6E47E66010B7944B00B186C8 /* WebGLGetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E47E65E10B7944B00B186C8 /* WebGLGetInfo.cpp */; };
 		6E47E66110B7944B00B186C8 /* WebGLGetInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E47E65F10B7944B00B186C8 /* WebGLGetInfo.h */; };
 		6E4E91AC10F7FB3100A2779C /* CanvasContextAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E4E91A710F7FB3100A2779C /* CanvasContextAttributes.cpp */; };
@@ -6650,6 +6652,8 @@
 		65DF323609D1DE65000BE325 /* JSCanvasPattern.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCanvasPattern.h; sourceTree = "<group>"; };
 		65F80697054D9F86008BF776 /* BlockExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockExceptions.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
 		65FEA86809833ADE00BED4AB /* Page.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Page.cpp; sourceTree = "<group>"; };
+		6E21C6BF1126338500A7BE02 /* GraphicsContext3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3D.cpp; sourceTree = "<group>"; };
+		6E21C6C11126339900A7BE02 /* GraphicsContext3DCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DCG.cpp; sourceTree = "<group>"; };
 		6E47E65E10B7944B00B186C8 /* WebGLGetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebGLGetInfo.cpp; path = canvas/WebGLGetInfo.cpp; sourceTree = "<group>"; };
 		6E47E65F10B7944B00B186C8 /* WebGLGetInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebGLGetInfo.h; path = canvas/WebGLGetInfo.h; sourceTree = "<group>"; };
 		6E4E91A710F7FB3100A2779C /* CanvasContextAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CanvasContextAttributes.cpp; path = canvas/CanvasContextAttributes.cpp; sourceTree = "<group>"; };
@@ -14319,6 +14323,7 @@
 				B275352C0B053814002CE64F /* FloatRectCG.cpp */,
 				B275352D0B053814002CE64F /* FloatSizeCG.cpp */,
 				BC53C60A0DA56CF10021EB5D /* GradientCG.cpp */,
+				6E21C6C11126339900A7BE02 /* GraphicsContext3DCG.cpp */,
 				B2ED97700B1F55CE00257D0F /* GraphicsContextCG.cpp */,
 				A80D67070E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h */,
 				B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */,
@@ -14434,6 +14439,7 @@
 				BC53C5F40DA56B920021EB5D /* Gradient.h */,
 				B2A015920AF6CD53006BCE0E /* GraphicsContext.cpp */,
 				B2A015930AF6CD53006BCE0E /* GraphicsContext.h */,
+				6E21C6BF1126338500A7BE02 /* GraphicsContext3D.cpp */,
 				49C7B9FB1042D3650009D447 /* GraphicsContext3D.h */,
 				A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */,
 				0F580B090F12A2690051D689 /* GraphicsLayer.cpp */,
@@ -20711,6 +20717,8 @@
 				76FF17E311235673001D61B5 /* PluginViewNone.cpp in Sources */,
 				9F2A322B1125A0A2003C3056 /* JavaScriptProfile.cpp in Sources */,
 				9F2A322D1125A0A2003C3056 /* JavaScriptProfileNode.cpp in Sources */,
+				6E21C6C01126338500A7BE02 /* GraphicsContext3D.cpp in Sources */,
+				6E21C6C21126339900A7BE02 /* GraphicsContext3DCG.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
new file mode 100644
index 0000000..3eb9818
--- /dev/null
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "GraphicsContext3D.h"
+
+#include "Image.h"
+
+namespace WebCore {
+
+bool GraphicsContext3D::extractImageData(Image* image,
+                                         bool flipY,
+                                         bool premultiplyAlpha,
+                                         Vector<uint8_t>& imageData,
+                                         unsigned int* format,
+                                         unsigned int* internalFormat)
+{
+    if (!image)
+        return false;
+    AlphaOp alphaOp = kAlphaDoNothing;
+    bool hasAlphaChannel = true;
+    if (!getImageData(image, imageData, premultiplyAlpha,
+                      &hasAlphaChannel, &alphaOp, format))
+        return false;
+    processImageData(imageData.data(),
+                     image->width(),
+                     image->height(),
+                     flipY,
+                     alphaOp);
+    *internalFormat = (hasAlphaChannel ? RGBA : RGB);
+    return true;
+}
+
+void GraphicsContext3D::processImageData(uint8_t* imageData,
+                                         unsigned width,
+                                         unsigned height,
+                                         bool flipVertically,
+                                         AlphaOp alphaOp)
+{
+    switch (alphaOp) {
+    case kAlphaDoPremultiply:
+        premultiplyAlpha(imageData, width * height);
+        break;
+    case kAlphaDoUnmultiply:
+        unmultiplyAlpha(imageData, width * height);
+        break;
+    default:
+        break;
+    }
+
+    if (flipVertically && width && height) {
+        int rowBytes = width * 4;
+        uint8_t* tempRow = new uint8_t[rowBytes];
+        for (unsigned i = 0; i < height / 2; i++) {
+            uint8_t* lowRow = imageData + (rowBytes * i);
+            uint8_t* highRow = imageData + (rowBytes * (height - i - 1));
+            memcpy(tempRow, lowRow, rowBytes);
+            memcpy(lowRow, highRow, rowBytes);
+            memcpy(highRow, tempRow, rowBytes);
+        }
+        delete[] tempRow;
+    }
+}
+
+// Premultiply alpha into color channels.
+void GraphicsContext3D::premultiplyAlpha(unsigned char* rgbaData, int numPixels)
+{
+    for (int j = 0; j < numPixels; j++) {
+        float r = rgbaData[4*j+0] / 255.0f;
+        float g = rgbaData[4*j+1] / 255.0f;
+        float b = rgbaData[4*j+2] / 255.0f;
+        float a = rgbaData[4*j+3] / 255.0f;
+        rgbaData[4*j+0] = (unsigned char) (r * a * 255.0f);
+        rgbaData[4*j+1] = (unsigned char) (g * a * 255.0f);
+        rgbaData[4*j+2] = (unsigned char) (b * a * 255.0f);
+    }
+}
+
+// Remove premultiplied alpha from color channels.
+// FIXME: this is lossy. Must retrieve original values from HTMLImageElement.
+void GraphicsContext3D::unmultiplyAlpha(unsigned char* rgbaData, int numPixels)
+{
+    for (int j = 0; j < numPixels; j++) {
+        float r = rgbaData[4*j+0] / 255.0f;
+        float g = rgbaData[4*j+1] / 255.0f;
+        float b = rgbaData[4*j+2] / 255.0f;
+        float a = rgbaData[4*j+3] / 255.0f;
+        if (a > 0.0f) {
+            r /= a;
+            g /= a;
+            b /= a;
+            r = (r > 1.0f) ? 1.0f : r;
+            g = (g > 1.0f) ? 1.0f : g;
+            b = (b > 1.0f) ? 1.0f : b;
+            rgbaData[4*j+0] = (unsigned char) (r * 255.0f);
+            rgbaData[4*j+1] = (unsigned char) (g * 255.0f);
+            rgbaData[4*j+2] = (unsigned char) (b * 255.0f);
+        }
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index b7be8fc..0a41dc6 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -419,6 +419,43 @@ namespace WebCore {
         // like GL_FLOAT, GL_INT, etc.
         int sizeInBytes(int type);
 
+        //----------------------------------------------------------------------
+        // Helpers for texture uploading.
+        //
+
+        // Extracts the contents of the given Image into the passed
+        // Vector, obeying the flipY and premultiplyAlpha flags.
+        // Returns the applicable OpenGL format and internalFormat for
+        // the subsequent glTexImage2D or glTexSubImage2D call.
+        // Returns true upon success.
+        bool extractImageData(Image* image,
+                              bool flipY,
+                              bool premultiplyAlpha,
+                              Vector<uint8_t>& imageData,
+                              unsigned int* format,
+                              unsigned int* internalFormat);
+
+        // Processes the given image data in preparation for uploading
+        // via texImage2D or texSubImage2D. The input data must be in
+        // 4-component format with the alpha channel last (i.e., RGBA
+        // or BGRA), tightly packed, with no space between rows.
+
+        enum AlphaOp {
+            kAlphaDoNothing = 0,
+            kAlphaDoPremultiply = 1,
+            kAlphaDoUnmultiply = 2
+        };
+
+        void processImageData(uint8_t* imageData,
+                              unsigned width,
+                              unsigned height,
+                              bool flipVertically,
+                              AlphaOp alphaOp);
+
+        //----------------------------------------------------------------------
+        // Entry points for WebGL.
+        //
+
         void activeTexture(unsigned long texture);
         void attachShader(WebGLProgram* program, WebGLShader* shader);
         void bindAttribLocation(WebGLProgram*, unsigned long index, const String& name);
@@ -624,6 +661,34 @@ namespace WebCore {
     private:        
         GraphicsContext3D(Attributes attrs);
 
+        // Helpers for texture uploading.
+        void premultiplyAlpha(unsigned char* rgbaData, int numPixels);
+        void unmultiplyAlpha(uint8_t* imageData, int numPixels);
+
+        // Each platform must provide an implementation of this method.
+        //
+        // Gets the data for the given Image into outputVector,
+        // without doing any processing of the data (vertical flip or
+        // otherwise).
+        //
+        // premultiplyAlpha indicates whether the user will eventually
+        // want the alpha channel multiplied into the color channels.
+        //
+        // The out parameter hasAlphaChannel indicates whether the
+        // image actually had an alpha channel.
+        //
+        // The out parameter neededAlphaOp should be passed to a
+        // subsequent call of processImageData.
+        //
+        // The out parameter format should be passed to subsequent
+        // invocations of texImage2D and texSubImage2D.
+        bool getImageData(Image* image,
+                          Vector<uint8_t>& outputVector,
+                          bool premultiplyAlpha,
+                          bool* hasAlphaChannel,
+                          AlphaOp* neededAlphaOp,
+                          unsigned int* format);
+
         int m_currentWidth, m_currentHeight;
         
 #if PLATFORM(MAC)
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
new file mode 100644
index 0000000..c6a8f83
--- /dev/null
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "GraphicsContext3D.h"
+
+#include "Image.h"
+
+#include <CoreGraphics/CGBitmapContext.h>
+#include <CoreGraphics/CGContext.h>
+#include <CoreGraphics/CGImage.h>
+
+namespace WebCore {
+
+bool GraphicsContext3D::getImageData(Image* image,
+                                     Vector<uint8_t>& outputVector,
+                                     bool premultiplyAlpha,
+                                     bool* hasAlphaChannel,
+                                     AlphaOp* neededAlphaOp,
+                                     unsigned int* format)
+{
+    if (!image)
+        return false;
+    CGImageRef cgImage = image->nativeImageForCurrentFrame();
+    if (!cgImage)
+        return false;
+    int width = CGImageGetWidth(cgImage);
+    int height = CGImageGetHeight(cgImage);
+    int rowBytes = width * 4;
+    CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage);
+    *hasAlphaChannel = (info != kCGImageAlphaNone
+                        && info != kCGImageAlphaNoneSkipLast
+                        && info != kCGImageAlphaNoneSkipFirst);
+    if (!premultiplyAlpha && *hasAlphaChannel)
+        // FIXME: must fetch the image data before the premultiplication step
+        *neededAlphaOp = kAlphaDoUnmultiply;
+    *format = RGBA;
+    outputVector.resize(height * rowBytes);
+    // Try to reuse the color space from the image to preserve its colors.
+    // Some images use a color space (such as indexed) unsupported by the bitmap context.
+    CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
+    bool releaseColorSpace = false;
+    CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
+    switch (colorSpaceModel) {
+    case kCGColorSpaceModelMonochrome:
+    case kCGColorSpaceModelRGB:
+    case kCGColorSpaceModelCMYK:
+    case kCGColorSpaceModelLab:
+    case kCGColorSpaceModelDeviceN:
+        break;
+    default:
+        colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+        releaseColorSpace = true;
+        break;
+    }
+    CGContextRef tmpContext = CGBitmapContextCreate(outputVector.data(),
+                                                    width, height, 8, rowBytes,
+                                                    colorSpace,
+                                                    kCGImageAlphaPremultipliedLast);
+    if (releaseColorSpace)
+        CGColorSpaceRelease(colorSpace);
+    if (!tmpContext)
+        return false;
+    CGContextSetBlendMode(tmpContext, kCGBlendModeCopy);
+    CGContextDrawImage(tmpContext,
+                       CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
+                       cgImage);
+    CGContextRelease(tmpContext);
+    return true;
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index 99ad130..096cdbd 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -1126,31 +1126,6 @@ long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long
     return reinterpret_cast<long>(pointer);
 }
 
-// Returned pointer must be freed by fastFree()
-static bool imageToTexture(Image* image, GLubyte*& buffer, size_t& width, size_t& height)
-{
-    if (!image)
-        return false;
-    
-    CGImageRef textureImage = image->getCGImageRef();
-    if (!textureImage)
-        return false;
-    
-    width = CGImageGetWidth(textureImage);
-    height = CGImageGetHeight(textureImage);
-    
-    buffer = (GLubyte*) fastMalloc(width * height * 4);
-    if (!buffer)
-        return false;
-        
-    CGContextRef textureContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4, 
-                                                        CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast);
-    CGContextSetBlendMode(textureContext, kCGBlendModeCopy);
-    CGContextDrawImage(textureContext, CGRectMake(0, 0, (CGFloat)width, (CGFloat)height), textureImage);
-    CGContextRelease(textureContext);
-    return true;
-}
-
 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
 {
     // FIXME: Need to do bounds checking on the buffer here.
@@ -1160,20 +1135,12 @@ int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned inte
 
 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha)
 {
-    // FIXME: need to support flipY and premultiplyAlpha
-    UNUSED_PARAM(flipY);
-    UNUSED_PARAM(premultiplyAlpha);
-    ASSERT(image);
-    
     ensureContext(m_contextObj);
-    GLubyte* buffer;
-    size_t width;
-    size_t height;
-    if (!imageToTexture(image, buffer, width, height))
+    Vector<uint8_t> imageData;
+    unsigned int format, internalFormat;
+    if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
         return -1;
-    
-    ::glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-    fastFree(buffer);
+    ::glTexImage2D(target, level, internalFormat, image->width(), image->height(), 0, format, GL_UNSIGNED_BYTE, imageData.data());
     return 0;
 }
     
@@ -1188,20 +1155,12 @@ int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned x
 int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, unsigned xoff, unsigned yoff, Image* image, bool flipY, bool premultiplyAlpha)
 {
     // FIXME: we will need to deal with PixelStore params when dealing with image buffers that differ from the subimage size
-    // FIXME: need to support flipY and premultiplyAlpha
-    UNUSED_PARAM(flipY);
-    UNUSED_PARAM(premultiplyAlpha);
-    ASSERT(image);
-    
     ensureContext(m_contextObj);
-    GLubyte* buffer;
-    size_t width;
-    size_t height;
-    if (!imageToTexture(image, buffer, width, height))
+    Vector<uint8_t> imageData;
+    unsigned int format, internalFormat;
+    if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
         return -1;
-    
-    ::glTexSubImage2D(target, level, xoff, yoff, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
-    fastFree(buffer);
+    ::glTexSubImage2D(target, level, xoff, yoff, image->width(), image->height(), format, GL_UNSIGNED_BYTE, imageData.data());
     return 0;
 }
 
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
new file mode 100644
index 0000000..cd86e6d
--- /dev/null
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "GraphicsContext3D.h"
+
+#include "Image.h"
+#include "NativeImageSkia.h"
+
+namespace WebCore {
+
+bool GraphicsContext3D::getImageData(Image* image,
+                                     Vector<uint8_t>& outputVector,
+                                     bool premultiplyAlpha,
+                                     bool* hasAlphaChannel,
+                                     AlphaOp* neededAlphaOp,
+                                     unsigned int* format)
+{
+    if (!image)
+        return false;
+    NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
+    if (!skiaImage)
+        return false;
+    SkBitmap::Config skiaConfig = skiaImage->config();
+    // FIXME: must support more image configurations.
+    if (skiaConfig != SkBitmap::kARGB_8888_Config)
+        return false;
+    SkBitmap& skiaImageRef = *skiaImage;
+    SkAutoLockPixels lock(skiaImageRef);
+    int width = skiaImage->width();
+    int height = skiaImage->height();
+    int rowBytes = skiaImage->rowBytes();
+    ASSERT(rowBytes == width * 4);
+    uint8_t* pixels = reinterpret_cast<uint8_t*>(skiaImage->getPixels());
+    outputVector.resize(rowBytes * height);
+    memcpy(outputVector.data(), pixels, rowBytes * height);
+    *hasAlphaChannel = true;
+    if (!premultiplyAlpha)
+        // FIXME: must fetch the image data before the premultiplication step
+        *neededAlphaOp = kAlphaDoUnmultiply;
+    // FIXME: remove this dependency on desktop OpenGL
+    *format = 0x80E1; // GL_BGRA
+    return true;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index b7bb876..6954369 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,31 @@
+2010-02-17  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Refactor texImage2D and texSubImage2D taking Image to use common code
+        https://bugs.webkit.org/show_bug.cgi?id=34458
+
+        Merged the Safari and Chromium code which extracts the data from
+        Image objects into common entry points on GraphicsContext3D. This
+        immediately fixes the following three problems:
+          - Chromium not implementing texSubImage2D taking Image.
+          - Safari not obeying the flipY parameter to texImage2D or
+            texSubImage2D taking Image.
+          - Safari not obeying the premultipyAlpha parameter to texImage2D
+            or texSubImage2D taking Image.
+        Added new test verifying the behavior of texImage2D and
+        texSubImage2D and the flipY parameter. The premultiplyAlpha
+        parameter can not be tested yet as the implementation is not yet
+        spec compliant. This will be fixed in a follow-on bug.
+
+        Ran all WebGL demos in demo repository on Safari and Chromium;
+        textures are now the right way up in both browsers, and
+        transparent textures in Particles demo now look correct in Safari.
+
+        * src/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::texImage2D):
+        (WebCore::GraphicsContext3D::texSubImage2D):
+
 2010-02-17  Alok Priyadarshi  <alokp at chromium.org>
 
         Reviewed by Ariya Hidayat.
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index 83574da..807a794 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -65,17 +65,12 @@
 #if PLATFORM(CG)
 #include "GraphicsContext.h"
 #include <CoreGraphics/CGContext.h>
-#include <CoreGraphics/CGBitmapContext.h>
 #include <CoreGraphics/CGImage.h>
 #include <OpenGL/OpenGL.h>
 #else
 #define FLIP_FRAMEBUFFER_VERTICALLY
 #endif
 
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#endif
-
 #if OS(DARWIN)
 #define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
 #endif
@@ -1878,178 +1873,17 @@ int GraphicsContext3D::texImage2D(unsigned target,
     return 0;
 }
 
-// Remove premultiplied alpha from color channels.
-// FIXME: this is lossy. Must retrieve original values from HTMLImageElement.
-static void unmultiplyAlpha(unsigned char* rgbaData, int numPixels)
-{
-    for (int j = 0; j < numPixels; j++) {
-        float b = rgbaData[4*j+0] / 255.0f;
-        float g = rgbaData[4*j+1] / 255.0f;
-        float r = rgbaData[4*j+2] / 255.0f;
-        float a = rgbaData[4*j+3] / 255.0f;
-        if (a > 0.0f) {
-            b /= a;
-            g /= a;
-            r /= a;
-            b = (b > 1.0f) ? 1.0f : b;
-            g = (g > 1.0f) ? 1.0f : g;
-            r = (r > 1.0f) ? 1.0f : r;
-            rgbaData[4*j+0] = (unsigned char) (b * 255.0f);
-            rgbaData[4*j+1] = (unsigned char) (g * 255.0f);
-            rgbaData[4*j+2] = (unsigned char) (r * 255.0f);
-        }
-    }
-}
-
-// FIXME: this must be changed to refer to the original image data
-// rather than unmultiplying the alpha channel.
-static int texImage2DHelper(unsigned target, unsigned level,
-                            int width, int height,
-                            int rowBytes,
-                            bool flipY,
-                            bool premultiplyAlpha,
-                            GLenum format,
-                            bool skipAlpha,
-                            unsigned char* pixels)
-{
-    ASSERT(format == GL_RGBA || format == GL_BGRA);
-    GLint internalFormat = GL_RGBA8;
-    if (skipAlpha) {
-        internalFormat = GL_RGB8;
-        // Ignore the alpha channel
-        premultiplyAlpha = true;
-    }
-    if (flipY) {
-        // Need to flip images vertically. To avoid making a copy of
-        // the entire image, we perform a ton of glTexSubImage2D
-        // calls. FIXME: should rethink this strategy for efficiency.
-        glTexImage2D(target, level, internalFormat,
-                     width,
-                     height,
-                     0,
-                     format,
-                     GL_UNSIGNED_BYTE,
-                     0);
-        unsigned char* row = 0;
-        bool allocatedRow = false;
-        if (!premultiplyAlpha) {
-            row = new unsigned char[rowBytes];
-            allocatedRow = true;
-        }
-        for (int i = 0; i < height; i++) {
-            if (premultiplyAlpha)
-                row = pixels + (rowBytes * i);
-            else {
-                memcpy(row, pixels + (rowBytes * i), rowBytes);
-                unmultiplyAlpha(row, width);
-            }
-            glTexSubImage2D(target, level, 0, height - i - 1,
-                            width, 1,
-                            format,
-                            GL_UNSIGNED_BYTE,
-                            row);
-        }
-        if (allocatedRow)
-            delete[] row;
-    } else {
-        // The pixels of cube maps' faces are defined with a top-down
-        // scanline ordering, unlike GL_TEXTURE_2D, so when uploading
-        // these, the above vertical flip is the wrong thing to do.
-        if (premultiplyAlpha)
-            glTexImage2D(target, level, internalFormat,
-                         width,
-                         height,
-                         0,
-                         format,
-                         GL_UNSIGNED_BYTE,
-                         pixels);
-        else {
-            glTexImage2D(target, level, internalFormat,
-                         width,
-                         height,
-                         0,
-                         format,
-                         GL_UNSIGNED_BYTE,
-                         0);
-            unsigned char* row = new unsigned char[rowBytes];
-            for (int i = 0; i < height; i++) {
-                memcpy(row, pixels + (rowBytes * i), rowBytes);
-                unmultiplyAlpha(row, width);
-                glTexSubImage2D(target, level, 0, i,
-                                width, 1,
-                                format,
-                                GL_UNSIGNED_BYTE,
-                                row);
-            }
-            delete[] row;
-        }
-    }
-    return 0;
-}
-
 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image,
                                   bool flipY, bool premultiplyAlpha)
 {
-    ASSERT(image);
-
-    int res = -1;
-#if PLATFORM(SKIA)
-    NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
-    if (!skiaImage) {
-        ASSERT_NOT_REACHED();
+    Vector<uint8_t> imageData;
+    unsigned int format, internalFormat;
+    if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
         return -1;
-    }
-    SkBitmap::Config skiaConfig = skiaImage->config();
-    // FIXME: must support more image configurations.
-    if (skiaConfig != SkBitmap::kARGB_8888_Config) {
-        ASSERT_NOT_REACHED();
-        return -1;
-    }
-    SkBitmap& skiaImageRef = *skiaImage;
-    SkAutoLockPixels lock(skiaImageRef);
-    int width = skiaImage->width();
-    int height = skiaImage->height();
-    unsigned char* pixels =
-        reinterpret_cast<unsigned char*>(skiaImage->getPixels());
-    int rowBytes = skiaImage->rowBytes();
-    res = texImage2DHelper(target, level,
-                           width, height,
-                           rowBytes,
-                           flipY, premultiplyAlpha,
-                           GL_BGRA,
-                           false,
-                           pixels);
-#elif PLATFORM(CG)
-    CGImageRef cgImage = image->nativeImageForCurrentFrame();
-    if (!cgImage) {
-        ASSERT_NOT_REACHED();
-        return -1;
-    }
-    int width = CGImageGetWidth(cgImage);
-    int height = CGImageGetHeight(cgImage);
-    int rowBytes = width * 4;
-    CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage);
-    bool skipAlpha = (info == kCGImageAlphaNone
-                   || info == kCGImageAlphaNoneSkipLast
-                   || info == kCGImageAlphaNoneSkipFirst);
-    unsigned char* imageData = new unsigned char[height * rowBytes];
-    CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
-    CGContextRef tmpContext = CGBitmapContextCreate(imageData, width, height, 8, rowBytes,
-                                                    colorSpace,
-                                                    kCGImageAlphaPremultipliedLast);
-    CGColorSpaceRelease(colorSpace);
-    CGContextSetBlendMode(tmpContext, kCGBlendModeCopy);
-    CGContextDrawImage(tmpContext,
-                       CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
-                       cgImage);
-    CGContextRelease(tmpContext);
-    res = texImage2DHelper(target, level, width, height, rowBytes,
-                           flipY, premultiplyAlpha, GL_RGBA, skipAlpha, imageData);
-    delete[] imageData;
-#else
-#error Must port to your platform
-#endif
-    return res;
+    glTexImage2D(target, level, internalFormat,
+                 image->width(), image->height(), 0,
+                 format, GL_UNSIGNED_BYTE, imageData.data());
+    return 0;
 }
 
 GL_SAME_METHOD_3(TexParameterf, texParameterf, unsigned, unsigned, float);
@@ -2078,9 +1912,14 @@ int GraphicsContext3D::texSubImage2D(unsigned target,
                                      bool flipY,
                                      bool premultiplyAlpha)
 {
-    // FIXME: implement.
-    notImplemented();
-    return -1;
+    Vector<uint8_t> imageData;
+    unsigned int format, internalFormat;
+    if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat))
+        return -1;
+    glTexSubImage2D(target, level, xoffset, yoffset,
+                    image->width(), image->height(),
+                    format, GL_UNSIGNED_BYTE, imageData.data());
+    return 0;
 }
 
 GL_SAME_METHOD_2(Uniform1f, uniform1f, long, float)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list