[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
zmo at google.com
zmo at google.com
Wed Dec 22 11:15:15 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 54d574e22ae7c3da1a51aa24ea9e6ab6bb9550e3
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jul 16 01:00:28 2010 +0000
2010-07-13 Zhenyao Mo <zmo at google.com>
Reviewed by Nate Chapin.
WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719
* src/GraphicsContext3D.cpp:
(WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
(WebCore::GraphicsContext3DInternal::beginPaint): Just use paintRenderingResultsToCanvas().
2010-07-13 Zhenyao Mo <zmo at google.com>
Reviewed by Nate Chapin.
WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719
Tests: fast/canvas/webgl/canvas-test.html
fast/canvas/webgl/gl-pixelstorei.html
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::makeRenderingResultsAvailable): Paint the WebGL rendering results to canvas if it's 3d.
(WebCore::HTMLCanvasElement::toDataURL): Paint the WebGL rendering results to canvas if it's 3d.
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawImage): Paint the WebGL rendering results to canvas if it's 3d before drawing.
* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::markContextChanged): Mark it always for canvas2d.drawImage purpose.
(WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas): Paint the WebGL rendering results to canvas if it's dirty.
* html/canvas/WebGLRenderingContext.h: Declare paintRenderingResultsToCanvas().
* platform/graphics/GraphicsContext3D.h: Declare paintRenderingResultsToCanvas() & paintToCanvas().
* platform/graphics/cg/GraphicsContext3DCG.cpp:
(WebCore::GraphicsContext3D::paintToCanvas): Paint the rendered image pixels to the canvas.
* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
* platform/graphics/qt/GraphicsContext3DQt.cpp:
(WebCore::GraphicsContext3D::beginPaint): Just call paintRenderingResultsToCanvas().
(WebCore::GraphicsContext3D::endPaint):
(WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
2010-07-13 Zhenyao Mo <zmo at google.com>
Reviewed by Nate Chapin.
WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
https://bugs.webkit.org/show_bug.cgi?id=34719
* fast/canvas/webgl/canvas-test-expected.txt: Added.
* fast/canvas/webgl/canvas-test.html: Added.
* fast/canvas/webgl/gl-pixelstorei-expected.txt: Added.
* fast/canvas/webgl/gl-pixelstorei.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63502 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7e3bbf3..13c00c2 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-13 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Nate Chapin.
+
+ WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
+ https://bugs.webkit.org/show_bug.cgi?id=34719
+
+ * fast/canvas/webgl/canvas-test-expected.txt: Added.
+ * fast/canvas/webgl/canvas-test.html: Added.
+ * fast/canvas/webgl/gl-pixelstorei-expected.txt: Added.
+ * fast/canvas/webgl/gl-pixelstorei.html: Added.
+
2010-07-15 Ojan Vafai <ojan at chromium.org>
Unreviewed.
diff --git a/LayoutTests/fast/canvas/webgl/canvas-test-expected.txt b/LayoutTests/fast/canvas/webgl/canvas-test-expected.txt
new file mode 100644
index 0000000..fe5b8ca
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/canvas-test-expected.txt
@@ -0,0 +1,30 @@
+This test ensures WebGL implementations interact correctly with the canvas tag.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Canvas.getContext
+PASS context exists
+
+Checking canvas and WebGL interaction
+PASS canvas.width is 300
+PASS canvas.height is 150
+PASS pixels are 0,0,0,0
+PASS getViewport() is "0,0,300,150"
+
+change display size of canvas and see that viewport does not change
+PASS getViewport() is "0,0,300,150"
+PASS canvas.width is 300
+PASS canvas.height is 150
+
+change the actual size of the canvas and see that the viewport does not change
+PASS pixels are 64,128,192,255
+PASS gl.clearColor should not change after canvas resize
+PASS gl.colorMask should not change after canvas resize
+PASS getViewport() is "0,0,300,150"
+PASS pixels are 0,0,0,0
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/canvas-test.html b/LayoutTests/fast/canvas/webgl/canvas-test.html
new file mode 100644
index 0000000..9d8e80c
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/canvas-test.html
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Canvas Conformance Tests</title>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<canvas id="canvas2d" width="40" height="40"> </canvas>
+<script>
+if (window.initNonKhronosFramework) {
+ window.initNonKhronosFramework(true);
+}
+
+description("This test ensures WebGL implementations interact correctly with the canvas tag.");
+
+debug("");
+debug("Canvas.getContext");
+
+var canvas = document.getElementById("canvas");
+var canvas2d = document.getElementById("canvas2d");
+var ctx2d = canvas2d.getContext("2d");
+var gl = create3DContext(canvas);
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking canvas and WebGL interaction");
+
+ // Check that a canvas with no width or height is 300x150 pixels
+ shouldBe('canvas.width', '300');
+ shouldBe('canvas.height', '150');
+
+ // Check get a 4 value gl parameter as a csv string.
+ function getValue4v(name) {
+ var v = gl.getParameter(name);
+ var result = '' +
+ v[0] + ',' +
+ v[1] + ',' +
+ v[2] + ',' +
+ v[3];
+ return result;
+ }
+
+ function getViewport() {
+ return getValue4v(gl.VIEWPORT);
+ }
+
+ function getClearColor() {
+ return getValue4v(gl.COLOR_CLEAR_VALUE);
+ }
+
+ function isAboutEqual(a, b) {
+ return Math.abs(a - b) < 0.01;
+ }
+
+ function isAboutEqualInt(a, b) {
+ return Math.abs(a - b) < 3;
+ }
+
+ function checkCanvasContentIs(r3d,g3d,b3d,a3d) {
+ var r2d;
+ var g2d;
+ var b2d;
+ var a2d;
+
+ function checkPixel(x, y, r3d,g3d,b3d,a3d) {
+ var offset = (y * 40 + x) * 4;
+ r2d = imgData.data[offset];
+ g2d = imgData.data[offset + 1];
+ b2d = imgData.data[offset + 2];
+ a2d = imgData.data[offset + 3];
+ //debug('' + x + ', ' + y + "(" + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d);
+ return isAboutEqualInt(r2d, r3d) &&
+ isAboutEqualInt(g2d, g3d) &&
+ isAboutEqualInt(b2d, b3d) &&
+ isAboutEqualInt(a2d, a3d);
+ }
+
+ function checkPixels(r3d,g3d,b3d,a3d) {
+ return checkPixel(0, 0, r3d, g3d, b3d, a3d) &&
+ checkPixel(0, 39, r3d, g3d, b3d, a3d) &&
+ checkPixel(39, 0, r3d, g3d, b3d, a3d) &&
+ checkPixel(39, 39, r3d, g3d, b3d, a3d) &&
+ checkPixel(0, 0, r3d, g3d, b3d, a3d);
+ };
+
+ // Set to just take the color from the 3d canvas
+ ctx2d.globalCompositeOperation = 'copy';
+
+ // fill 2d canvas with orange
+ ctx2d.fillStyle = "rgb(255,192,128)";
+ ctx2d.fillRect (0, 0, 40, 40);
+
+ // get the image data
+ var imgData = ctx2d.getImageData(0, 0, 40, 40);
+
+ // check it got cleared.
+ if (!checkPixels(255, 192, 128, 255)) {
+ testFailed("unable to fill 2d context.");
+ return;
+ }
+
+ // draw 3d canvas on top.
+ ctx2d.drawImage(canvas, 0,0, 40, 40);
+
+ // get the image data
+ var imgData = ctx2d.getImageData(0, 0, 40, 40);
+
+ // Check it's the expected color.
+ if (!checkPixels(r3d, g3d, b3d, a3d)) {
+ testFailed("pixels are " + r2d + "," + g2d + "," + b2d + "," + a2d +
+ " expected " + r3d + "," + g3d + "," + b3d + "," + a3d);
+ } else {
+ testPassed("pixels are " + r3d + "," + g3d + "," + b3d + "," + a3d);
+ }
+ }
+
+ checkCanvasContentIs(0, 0, 0, 0);
+ shouldBe('getViewport()', '"0,0,300,150"');
+
+ // Change the display size of the canvas and check
+ // the viewport size does not change.
+ debug("");
+ debug("change display size of canvas and see that viewport does not change");
+ canvas.style.width = "100px";
+ canvas.style.height = "25px";
+ var intervalId;
+ intervalId = window.setInterval(function() {
+ if (canvas.clientWidth == 100 &&
+ canvas.clientHeight == 25) {
+ window.clearInterval(intervalId);
+ shouldBe('getViewport()', '"0,0,300,150"');
+ shouldBe('canvas.width', '300');
+ shouldBe('canvas.height', '150');
+
+ // Change the actual size of the canvas
+ // Check that the viewport does not change.
+ // Check that the clear color does not change.
+ // Check that the color mask does not change.
+ debug("");
+ debug("change the actual size of the canvas and see that the viewport does not change");
+ gl.clearColor(0.25, 0.5, 0.75, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ checkCanvasContentIs(64, 128, 192, 255);
+ gl.colorMask(0,0,0,0);
+ canvas.width = 400;
+ canvas.height = 10;
+
+ var v = gl.getParameter(gl.COLOR_CLEAR_VALUE);
+ assertMsg(isAboutEqual(v[0], 0.25) &&
+ isAboutEqual(v[1], 0.5) &&
+ isAboutEqual(v[2], 0.75) &&
+ isAboutEqual(v[3], 1),
+ "gl.clearColor should not change after canvas resize");
+ v = gl.getParameter(gl.COLOR_WRITEMASK);
+ assertMsg(isAboutEqual(v[0], 0) &&
+ isAboutEqual(v[1], 0) &&
+ isAboutEqual(v[2], 0) &&
+ isAboutEqual(v[3], 0),
+ "gl.colorMask should not change after canvas resize");
+ shouldBe('getViewport()', '"0,0,300,150"');
+ checkCanvasContentIs(0, 0, 0, 0);
+
+ debug("");
+ successfullyParsed = true;
+ var epilogue = document.createElement("script");
+ epilogue.onload = finish;
+ epilogue.src = "../../js/resources/js-test-post.js";
+ document.body.appendChild(epilogue);
+ }
+ }, 1000/30);
+}
+
+function finish() {
+ if (window.nonKhronosFrameworkNotifyDone) {
+ window.nonKhronosFrameworkNotifyDone();
+ }
+}
+
+</script>
+<script>
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/canvas/webgl/gl-pixelstorei-expected.txt b/LayoutTests/fast/canvas/webgl/gl-pixelstorei-expected.txt
new file mode 100644
index 0000000..088ce3a
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/gl-pixelstorei-expected.txt
@@ -0,0 +1,21 @@
+
+There should be 5 red triangles on 5 black squares above
+
+This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa
+
+PASS drawing is correct in 3d context
+PASS drawing is correct in 2d context
+PASS PACK_ALIGNMENT is 1
+PASS drawing is correct in 3d context
+PASS drawing is correct in 2d context
+PASS PACK_ALIGNMENT is 2
+PASS drawing is correct in 3d context
+PASS drawing is correct in 2d context
+PASS PACK_ALIGNMENT is 4
+PASS drawing is correct in 3d context
+PASS drawing is correct in 2d context
+PASS PACK_ALIGNMENT is 8
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/gl-pixelstorei.html b/LayoutTests/fast/canvas/webgl/gl-pixelstorei.html
new file mode 100644
index 0000000..654baed
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/gl-pixelstorei.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>WebGL pixelStorei Test</title>
+<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/desktop-gl-constants.js" type="text/javascript"></script>
+</head>
+<body>
+<canvas id="example" width="50" height="50"></canvas>
+<canvas id="2d00" width="50" height="50"></canvas>
+<canvas id="2d01" width="50" height="50"></canvas>
+<canvas id="2d02" width="50" height="50"></canvas>
+<canvas id="2d03" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+void main() {
+ gl_FragColor = vec4(1.0,0.0,0.0,1.0);
+}
+</script>
+
+<script>
+function fail(x,y, name, buf, shouldBe) {
+ var i = (y*50+x) * 4;
+ var reason = "pixel in "+name+" at ("+x+","+y+") is ("+buf[i]+","+buf[i+1]+","+buf[i+2]+","+buf[i+3]+"), should be "+shouldBe;
+ testFailed(reason);
+}
+
+function pass(name) {
+ testPassed("drawing is correct in " + name);
+}
+
+function init() {
+ debug("There should be 5 red triangles on 5 black squares above");
+ debug("");
+
+ debug("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
+ debug("");
+
+ var canvas3d = document.getElementById("example");
+ gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+
+ function checkData(buf, name) {
+ // Test several locations
+ // First line should be all black
+ for (var i = 0; i < 50; ++i) {
+ if (buf[i*4] != 0 || buf[i*4+1] != 0 || buf[i*4+2] != 0 || buf[i*4+3] != 255) {
+ fail(i, 0, name, buf, "(0,0,0,255)");
+ return;
+ }
+ }
+
+ // Line 25 should be red for at least 6 red pixels starting 22 pixels in
+ var offset = (25*50+22) * 4;
+ for (var i = 0; i < 6; ++i) {
+ if (buf[offset+i*4] != 255 || buf[offset+i*4+1] != 0 || buf[offset+i*4+2] != 0 || buf[offset+i*4+3] != 255) {
+ fail(22 + i, 25, name, buf, "(255,0,0,255)");
+ return;
+ }
+ }
+
+ // Last line should be all black
+ offset = (49*50) * 4;
+ for (var i = 0; i < 50; ++i) {
+ if (buf[offset+i*4] != 0 || buf[offset+i*4+1] != 0 || buf[offset+i*4+2] != 0 || buf[offset+i*4+3] != 255) {
+ fail(i, 49, name, buf, "(0,0,0,255)");
+ return;
+ }
+ }
+
+ pass(name);
+ }
+
+ function checkColors() {
+ var buf = new Uint8Array(50 * 50 * 4);
+ gl.readPixels(0, 0, 50, 50, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ checkData(buf, "3d context");
+ var imgData = ctx2d.getImageData(0, 0, 50, 50);
+ checkData(imgData.data, "2d context");
+ }
+
+ var table = [1, 2, 4, 8];
+ for (var ii = 0; ii < table.length; ++ii) {
+ gl.pixelStorei(gl.PACK_ALIGNMENT, table[ii]);
+ ctx2d = document.getElementById("2d0" + ii).getContext("2d");
+ ctx2d.globalCompositeOperation = 'copy';
+ ctx2d.drawImage(canvas3d, 0, 0);
+ checkColors();
+ assertMsg(gl.getParameter(gl.PACK_ALIGNMENT) == table[ii],
+ "PACK_ALIGNMENT is " + table[ii]);
+ }
+}
+
+init();
+successfullyParsed = true;
+</script>
+</body>
+<script src="../../js/resources/js-test-post.js"></script>
+
+<script>
+</script>
+
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0c60b52..b3608fe 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2010-07-13 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Nate Chapin.
+
+ WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
+ https://bugs.webkit.org/show_bug.cgi?id=34719
+
+ Tests: fast/canvas/webgl/canvas-test.html
+ fast/canvas/webgl/gl-pixelstorei.html
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::makeRenderingResultsAvailable): Paint the WebGL rendering results to canvas if it's 3d.
+ (WebCore::HTMLCanvasElement::toDataURL): Paint the WebGL rendering results to canvas if it's 3d.
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::drawImage): Paint the WebGL rendering results to canvas if it's 3d before drawing.
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::markContextChanged): Mark it always for canvas2d.drawImage purpose.
+ (WebCore::WebGLRenderingContext::paintRenderingResultsToCanvas): Paint the WebGL rendering results to canvas if it's dirty.
+ * html/canvas/WebGLRenderingContext.h: Declare paintRenderingResultsToCanvas().
+ * platform/graphics/GraphicsContext3D.h: Declare paintRenderingResultsToCanvas() & paintToCanvas().
+ * platform/graphics/cg/GraphicsContext3DCG.cpp:
+ (WebCore::GraphicsContext3D::paintToCanvas): Paint the rendered image pixels to the canvas.
+ * platform/graphics/mac/GraphicsContext3DMac.mm:
+ (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
+ * platform/graphics/qt/GraphicsContext3DQt.cpp:
+ (WebCore::GraphicsContext3D::beginPaint): Just call paintRenderingResultsToCanvas().
+ (WebCore::GraphicsContext3D::endPaint):
+ (WebCore::GraphicsContext3D::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
+
2010-07-15 Nico Weber <thakis at chromium.org>
Reviewed by Ojan Vafai.
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index ffd87c4..6174f51 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -297,6 +297,16 @@ bool HTMLCanvasElement::is3D() const
}
#endif
+void HTMLCanvasElement::makeRenderingResultsAvailable()
+{
+#if ENABLE(3D_CANVAS)
+ if (is3D()) {
+ WebGLRenderingContext* context3d = reinterpret_cast<WebGLRenderingContext*>(renderingContext());
+ context3d->paintRenderingResultsToCanvas();
+ }
+#endif
+}
+
void HTMLCanvasElement::recalcStyle(StyleChange change)
{
HTMLElement::recalcStyle(change);
@@ -327,6 +337,8 @@ String HTMLCanvasElement::toDataURL(const String& mimeType, const double* qualit
String lowercaseMimeType = mimeType.lower();
+ makeRenderingResultsAvailable();
+
// FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this method to be used on a worker thread).
if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(lowercaseMimeType))
return buffer()->toDataURL("image/png");
diff --git a/WebCore/html/HTMLCanvasElement.h b/WebCore/html/HTMLCanvasElement.h
index 05bc256..b222007 100644
--- a/WebCore/html/HTMLCanvasElement.h
+++ b/WebCore/html/HTMLCanvasElement.h
@@ -32,10 +32,6 @@
#include "HTMLElement.h"
#include "IntSize.h"
-#if ENABLE(3D_CANVAS)
-#include "GraphicsContext3D.h"
-#endif
-
namespace WebCore {
class CanvasContextAttributes;
@@ -114,6 +110,8 @@ public:
bool is3D() const;
#endif
+ void makeRenderingResultsAvailable();
+
private:
HTMLCanvasElement(const QualifiedName&, Document*);
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index b3bafc6..c573dd8 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1157,6 +1157,8 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const
if (!sourceCanvas->originClean())
canvas()->setOriginTainted();
+ sourceCanvas->makeRenderingResultsAvailable();
+
c->drawImage(buffer->image(), DeviceColorSpace, destRect, sourceRect, state().m_globalComposite);
willDraw(destRect); // This call comes after drawImage, since the buffer we draw into may be our own, and we need to make sure it is dirty.
// FIXME: Arguably willDraw should become didDraw and occur after drawing calls and not before them to avoid problems like this.
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 2bbcad1..35dc64a 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -141,17 +141,23 @@ void WebGLRenderingContext::markContextChanged()
RenderBox* renderBox = canvas()->renderBox();
if (renderBox && renderBox->hasLayer() && renderBox->layer()->hasAcceleratedCompositing())
renderBox->layer()->rendererContentChanged();
- else {
#endif
- if (!m_markedCanvasDirty) {
- // Make sure the canvas's image buffer is allocated.
- canvas()->buffer();
- canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
- m_markedCanvasDirty = true;
- }
-#if USE(ACCELERATED_COMPOSITING)
+ if (!m_markedCanvasDirty) {
+ // Make sure the canvas's image buffer is allocated.
+ canvas()->buffer();
+ canvas()->willDraw(FloatRect(0, 0, canvas()->width(), canvas()->height()));
+ m_markedCanvasDirty = true;
}
-#endif
+}
+
+bool WebGLRenderingContext::paintRenderingResultsToCanvas()
+{
+ if (m_markedCanvasDirty) {
+ m_markedCanvasDirty = false;
+ m_context->paintRenderingResultsToCanvas(this);
+ return true;
+ }
+ return false;
}
void WebGLRenderingContext::beginPaint()
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index fa0d9d0..1dd7d53 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -306,6 +306,10 @@ class WebKitCSSMatrix;
void reshape(int width, int height);
+ // Return value true indicates canvas is updated during the call,
+ // false indicates no updates.
+ bool paintRenderingResultsToCanvas();
+
// Helpers for notification about paint events.
void beginPaint();
void endPaint();
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 2887e62..28388f4 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -68,6 +68,10 @@ typedef int Platform3DObject;
const Platform3DObject NullPlatform3DObject = 0;
#endif
+#if PLATFORM(CG)
+#include <CoreGraphics/CGContext.h>
+#endif
+
namespace WebCore {
class WebGLActiveInfo;
class ArrayBuffer;
@@ -710,7 +714,14 @@ namespace WebCore {
void viewport(long x, long y, unsigned long width, unsigned long height);
void reshape(int width, int height);
-
+
+#if PLATFORM(CG)
+ void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
+ int canvasWidth, int canvasHeight, CGContextRef context);
+#endif
+
+ void paintRenderingResultsToCanvas(WebGLRenderingContext* context);
+
// Helpers for notification about paint events
void beginPaint(WebGLRenderingContext* context);
void endPaint();
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index 9f0f353..8af3d0e 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -36,6 +36,8 @@
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGImage.h>
+#include <wtf/RetainPtr.h>
+
namespace WebCore {
bool GraphicsContext3D::getImageData(Image* image,
@@ -104,6 +106,41 @@ bool GraphicsContext3D::getImageData(Image* image,
format, type, neededAlphaOp, outputVector.data());
}
+void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, CGContextRef context)
+{
+ if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
+ return;
+ int rowBytes = imageWidth * 4;
+ RetainPtr<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0, imagePixels, rowBytes * imageHeight, 0);
+ RetainPtr<CGColorSpaceRef> colorSpace = CGColorSpaceCreateDeviceRGB();
+ RetainPtr<CGImageRef> cgImage = CGImageCreate(imageWidth,
+ imageHeight,
+ 8,
+ 32,
+ rowBytes,
+ colorSpace.get(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ dataProvider.get(),
+ 0,
+ false,
+ kCGRenderingIntentDefault);
+ // CSS styling may cause the canvas's content to be resized on
+ // the page. Go back to the Canvas to figure out the correct
+ // width and height to draw.
+ CGRect rect = CGRectMake(0, 0,
+ canvasWidth,
+ canvasHeight);
+ // We want to completely overwrite the previous frame's
+ // rendering results.
+ CGContextSaveGState(context);
+ CGContextSetBlendMode(context,
+ kCGBlendModeCopy);
+ CGContextSetInterpolationQuality(context,
+ kCGInterpolationNone);
+ CGContextDrawImage(context,
+ rect, cgImage.get());
+ CGContextRestoreGState(context);
+}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index ae9ace2..57664b6 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -39,10 +39,13 @@
#include "WebGLBuffer.h"
#include "Float32Array.h"
#include "WebGLFramebuffer.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
#include "Int32Array.h"
#include "WebGLLayer.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
+#include "WebGLRenderingContext.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "Uint8Array.h"
@@ -237,6 +240,54 @@ void GraphicsContext3D::makeContextCurrent()
CGLSetCurrentContext(m_contextObj);
}
+void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
+{
+ HTMLCanvasElement* canvas = context->canvas();
+ ImageBuffer* imageBuffer = canvas->buffer();
+
+ int rowBytes = m_currentWidth * 4;
+ int totalBytes = rowBytes * m_currentHeight;
+
+ OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]);
+ if (!pixels)
+ return;
+
+ CGLSetCurrentContext(m_contextObj);
+
+ bool mustRestoreFBO;
+ if (m_attrs.antialias) {
+ ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
+ ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
+ ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ mustRestoreFBO = true;
+ } else {
+ if (m_boundFBO != m_fbo) {
+ mustRestoreFBO = true;
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ }
+ }
+
+ GLint packAlignment = 4;
+ bool mustRestorePackAlignment = false;
+ ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
+ if (packAlignment > 4) {
+ ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ mustRestorePackAlignment = true;
+ }
+
+ ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get());
+
+ if (mustRestorePackAlignment)
+ ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
+
+ if (mustRestoreFBO)
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
+
+ paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
+ canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
+}
+
void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
{
UNUSED_PARAM(context);
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 002765f..311d3a3 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -521,6 +521,15 @@ void GraphicsContext3D::makeContextCurrent()
void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
{
+ paintRenderingResultsToCanvas();
+}
+
+void GraphicsContext3D::endPaint()
+{
+}
+
+void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
+{
m_internal->m_glWidget->makeCurrent();
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
@@ -528,10 +537,6 @@ void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
paint(painter, QRect(QPoint(0, 0), QSize(m_currentWidth, m_currentHeight)));
}
-void GraphicsContext3D::endPaint()
-{
-}
-
void GraphicsContext3D::paint(QPainter* painter, const QRect& rect) const
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 43bf858..5c48757 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,14 @@
+2010-07-13 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Nate Chapin.
+
+ WebGL rendering results must be made available to Canvas.toDataURL and 2D drawImage
+ https://bugs.webkit.org/show_bug.cgi?id=34719
+
+ * src/GraphicsContext3D.cpp:
+ (WebCore::GraphicsContext3DInternal::paintRenderingResultsToCanvas): Implement paintRenderingResultsToCanvas().
+ (WebCore::GraphicsContext3DInternal::beginPaint): Just use paintRenderingResultsToCanvas().
+
2010-07-15 Victor Wang <victorw at chromium.org>
Reviewed by David Levin.
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index aad9645..fec0b20 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -112,6 +112,7 @@ public:
void reshape(int width, int height);
+ void paintRenderingResultsToCanvas(WebGLRenderingContext* context);
void beginPaint(WebGLRenderingContext* context);
void endPaint();
@@ -399,7 +400,7 @@ WebGLLayerChromium* GraphicsContext3DInternal::platformLayer() const
}
#endif
-void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
+void GraphicsContext3DInternal::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
{
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
@@ -449,44 +450,20 @@ void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
}
#elif PLATFORM(CG)
- if (m_renderOutput) {
- int rowBytes = m_impl->width() * 4;
- CGDataProviderRef dataProvider = CGDataProviderCreateWithData(0, m_renderOutput, rowBytes * m_impl->height(), 0);
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGImageRef cgImage = CGImageCreate(m_impl->width(),
- m_impl->height(),
- 8,
- 32,
- rowBytes,
- colorSpace,
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
- dataProvider,
- 0,
- false,
- kCGRenderingIntentDefault);
- // CSS styling may cause the canvas's content to be resized on
- // the page. Go back to the Canvas to figure out the correct
- // width and height to draw.
- CGRect rect = CGRectMake(0, 0,
- context->canvas()->width(),
- context->canvas()->height());
- // We want to completely overwrite the previous frame's
- // rendering results.
- CGContextSetBlendMode(imageBuffer->context()->platformContext(),
- kCGBlendModeCopy);
- CGContextSetInterpolationQuality(imageBuffer->context()->platformContext(),
- kCGInterpolationNone);
- CGContextDrawImage(imageBuffer->context()->platformContext(),
- rect, cgImage);
- CGImageRelease(cgImage);
- CGColorSpaceRelease(colorSpace);
- CGDataProviderRelease(dataProvider);
- }
+ if (m_renderOutput)
+ context->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(),
+ canvas->width(), canvas->height(),
+ imageBuffer->context()->platformContext());
#else
#error Must port to your platform
#endif
}
+void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
+{
+ paintRenderingResultsToCanvas(context);
+}
+
void GraphicsContext3DInternal::endPaint()
{
}
@@ -1325,6 +1302,7 @@ DELEGATE_TO_INTERNAL_6(vertexAttribPointer, unsigned long, int, int, bool, unsig
DELEGATE_TO_INTERNAL_4(viewport, long, long, unsigned long, unsigned long)
+DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, WebGLRenderingContext*)
DELEGATE_TO_INTERNAL_1(beginPaint, WebGLRenderingContext*)
DELEGATE_TO_INTERNAL(endPaint)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list