Skip to content
Permalink
Browse files
2010-07-13 Zhenyao Mo <zmo@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@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@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.


Canonical link: https://commits.webkit.org/54342@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@63502 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Zhenyao Mo committed Jul 16, 2010
1 parent d7701bb commit 30ade48eb839c6bc97e7a27afd990015ed79ca98
@@ -1,3 +1,15 @@
2010-07-13 Zhenyao Mo <zmo@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@chromium.org>

Unreviewed.
@@ -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

@@ -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>
@@ -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

@@ -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>

0 comments on commit 30ade48

Please sign in to comment.