[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373
kbr at google.com
kbr at google.com
Thu Apr 8 02:23:58 UTC 2010
The following commit has been merged in the webkit-1.2 branch:
commit e50ac1dfe0a451653730d75d4b2b30e194086241
Author: kbr at google.com <kbr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Mar 16 18:53:34 2010 +0000
2010-03-16 Zhenyao Mo <zmo at google.com>
Reviewed by Darin Fisher.
Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416
Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
* src/GraphicsContext3D.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Windows.
2010-03-16 Zhenyao Mo <zmo at google.com>
Reviewed by Darin Fisher.
Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416
Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
* bindings/v8/custom/V8HTMLCanvasElementCustom.cpp: Fix an index bug.
* platform/graphics/GraphicsContext3D.h: Add members/functions for multisampling/stencil buffer purpose.
* platform/graphics/mac/Canvas3DLayer.h: Add GraphicsContext3D as a member of Canvas3DLayer.
* platform/graphics/mac/Canvas3DLayer.mm: Add multisampling support.
* platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac.
* platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call.
2010-03-16 Zhenyao Mo <zmo at google.com>
Reviewed by Darin Fisher.
Hook up WebGLContextAttributes to OpenGL context creation code
https://bugs.webkit.org/show_bug.cgi?id=33416
* fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt: Added.
* fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html: Added.
* fast/canvas/webgl/context-attributes-expected.txt: WebGL context attributes behavior changed with this fix.
* fast/canvas/webgl/context-attributes.html: Ditto.
* fast/canvas/webgl/gl-get-calls-expected.txt: Stencil buffer is enabled, thus Stencil Bits is no longer 0.
* fast/canvas/webgl/gl-get-calls.html: Ditto.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@56074 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3a4176e..685845c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2010-03-16 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Darin Fisher.
+
+ Hook up WebGLContextAttributes to OpenGL context creation code
+ https://bugs.webkit.org/show_bug.cgi?id=33416
+
+ * fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt: Added.
+ * fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html: Added.
+ * fast/canvas/webgl/context-attributes-expected.txt: WebGL context attributes behavior changed with this fix.
+ * fast/canvas/webgl/context-attributes.html: Ditto.
+ * fast/canvas/webgl/gl-get-calls-expected.txt: Stencil buffer is enabled, thus Stencil Bits is no longer 0.
+ * fast/canvas/webgl/gl-get-calls.html: Ditto.
+
2010-03-16 Joanmarie Diggs <joanmarie.diggs at gmail.com>
Reviewed by Xan Lopez.
diff --git a/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt b/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt
new file mode 100644
index 0000000..4b62b55
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-expected.txt
@@ -0,0 +1,82 @@
+
+Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha
+
+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=33416 : Hook up WebGLContextAttributes to OpenGL context creation code
+Testing alpha = true
+PASS webGL = getWebGL('alphaOn', { alpha: true, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.alpha is true
+PASS contextAttribs.depth is false
+PASS contextAttribs.stencil is false
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing alpha = false
+PASS webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.alpha is false
+PASS contextAttribs.depth is false
+PASS contextAttribs.stencil is false
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing depth = true
+PASS webGL = getWebGL('depthOn', { stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is true
+PASS contextAttribs.alpha is true
+PASS contextAttribs.stencil is false
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing depth = false
+PASS webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is false
+PASS contextAttribs.alpha is true
+PASS contextAttribs.stencil is false
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing stencil = true
+PASS webGL = getWebGL('stencilOn', { depth: false, stencil: true, antialias: false }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is true
+PASS contextAttribs.stencil is true
+PASS contextAttribs.alpha is true
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing stencil = false
+PASS webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is false
+PASS contextAttribs.stencil is false
+PASS contextAttribs.alpha is true
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel is correctColor
+Testing antialias = true
+PASS webGL = getWebGL('antialiasOn', { depth: false, stencil: false, alpha: false, antialias: true }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is false
+PASS contextAttribs.stencil is false
+PASS contextAttribs.alpha is false
+PASS contextAttribs.antialias is true
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel[0] == 255 || pixel[0] == 0 is false
+Testing antialias = false
+PASS webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0) is non-null.
+PASS contextAttribs = webGL.getContextAttributes() is non-null.
+PASS contextAttribs.depth is false
+PASS contextAttribs.stencil is false
+PASS contextAttribs.alpha is false
+PASS contextAttribs.antialias is false
+PASS contextAttribs.premultipliedAlpha is true
+PASS pixel[0] == 255 || pixel[0] == 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html b/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
new file mode 100644
index 0000000..f1691cd
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
@@ -0,0 +1,307 @@
+<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 pos;
+attribute vec4 colorIn;
+varying vec4 color;
+
+void main()
+{
+ color = colorIn;
+ gl_Position = vec4(pos.xyz, 1.0);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+varying vec4 color;
+
+void main()
+{
+ gl_FragColor = color;
+}
+</script>
+
+<script>
+var successfullyParsed = false;
+
+// These four declarations need to be global for "shouldBe" to see them
+var webGL = null;
+var contextAttribs = null;
+var pixel = [0, 0, 0, 1];
+var correctColor = null;
+
+function init()
+{
+ if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ }
+
+ description('Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha');
+
+ debug('Regression test for <a href="https://bugs.webkit.org/show_bug.cgi?id=33416">https://bugs.webkit.org/show_bug.cgi?id=33416</a> : <code>Hook up WebGLContextAttributes to OpenGL context creation code</code>');
+
+ runTest();
+}
+
+function getWebGL(canvasName, contextAttribs, clearColor, clearDepth, clearStencil)
+{
+ var canvas = document.getElementById(canvasName);
+ var gl = canvas.getContext("experimental-webgl", contextAttribs);
+ if (!gl) {
+ alert("No WebGL context found");
+ return null;
+ }
+ var actualContextAttribs = gl.getContextAttributes();
+
+ // Add a console
+ gl.console = ("console" in window) ? window.console : { log: function() { } };
+
+ // create our shaders
+ var vertexShader = loadShader(gl, "vshader");
+ var fragmentShader = loadShader(gl, "fshader");
+
+ if (!vertexShader || !fragmentShader)
+ return null;
+
+ // Create the program object
+ gl.program = gl.createProgram();
+
+ if (!gl.program)
+ return null;
+
+ // Attach our two shaders to the program
+ gl.attachShader(gl.program, vertexShader);
+ gl.attachShader(gl.program, fragmentShader);
+
+ // Bind attributes
+ var attribs = [ "pos", "colorIn" ];
+ for (var i in attribs)
+ gl.bindAttribLocation(gl.program, i, attribs[i]);
+
+ // Link the program
+ gl.linkProgram(gl.program);
+
+ // Check the link status
+ var linked = gl.getProgramParameter(gl.program, gl.LINK_STATUS);
+ if (!linked) {
+ // something went wrong with the link
+ var error = gl.getProgramInfoLog (gl.program);
+ gl.console.log("Error in program linking:"+error);
+
+ gl.deleteProgram(gl.program);
+ gl.deleteProgram(fragmentShader);
+ gl.deleteProgram(vertexShader);
+
+ return null;
+ }
+
+ gl.useProgram(gl.program);
+
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+ gl.clearDepth(clearDepth);
+ gl.clearStencil(clearStencil);
+ gl.enable(gl.DEPTH_TEST);
+ gl.enable(gl.STENCIL_TEST);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ return gl;
+}
+
+function drawAndReadPixel(gl, vertices, colors, x, y)
+{
+ var colorOffset = vertices.byteLength;
+
+ var vbo = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, colorOffset + colors.byteLength, gl.STATIC_DRAW);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
+ gl.bufferSubData(gl.ARRAY_BUFFER, colorOffset, colors);
+
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, colorOffset);
+ gl.enableVertexAttribArray(1);
+
+ gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);
+
+ return gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE);
+}
+
+function testAlpha(alpha)
+{
+ debug("Testing alpha = " + alpha);
+ if (alpha)
+ shouldBeNonNull("webGL = getWebGL('alphaOn', { alpha: true, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
+ else
+ shouldBeNonNull("webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
+ shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
+ shouldBe("contextAttribs.alpha", (alpha ? "true" : "false"));
+ shouldBe("contextAttribs.depth", "false");
+ shouldBe("contextAttribs.stencil", "false");
+ shouldBe("contextAttribs.antialias", "false");
+ shouldBe("contextAttribs.premultipliedAlpha", "true");
+
+ var buf = webGL.readPixels(0, 0, 1, 1, webGL.RGBA, webGL.UNSIGNED_BYTE);
+ pixel[0] = buf[0];
+ pixel[1] = buf[1];
+ pixel[2] = buf[2];
+ pixel[3] = buf[3];
+ correctColor = (alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]);
+ shouldBe("pixel", "correctColor");
+}
+
+function testDepth(depth)
+{
+ debug("Testing depth = " + depth);
+ if (depth)
+ shouldBeNonNull("webGL = getWebGL('depthOn', { stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
+ else
+ shouldBeNonNull("webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
+ shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
+ shouldBe("contextAttribs.depth", (depth ? "true" : "false"));
+ shouldBe("contextAttribs.alpha", "true");
+ shouldBe("contextAttribs.stencil", "false");
+ shouldBe("contextAttribs.antialias", "false");
+ shouldBe("contextAttribs.premultipliedAlpha", "true");
+
+ webGL.depthFunc(webGL.NEVER);
+
+ 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 colors = new WebGLUnsignedByteArray([
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255]);
+
+ var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
+ pixel[0] = buf[0];
+ pixel[1] = buf[1];
+ pixel[2] = buf[2];
+ pixel[3] = buf[3];
+ correctColor = (depth ? [0, 0, 0, 255] : [255, 0, 0, 255]);
+ shouldBe("pixel", "correctColor");
+}
+
+function testStencil(stencil)
+{
+ debug("Testing stencil = " + stencil);
+ if (stencil)
+ shouldBeNonNull("webGL = getWebGL('stencilOn', { depth: false, stencil: true, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
+ else
+ shouldBeNonNull("webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
+ shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
+ shouldBe("contextAttribs.depth", (stencil ? "true" : "false"));
+ shouldBe("contextAttribs.stencil", (stencil ? "true" : "false"));
+ shouldBe("contextAttribs.alpha", "true");
+ shouldBe("contextAttribs.antialias", "false");
+ shouldBe("contextAttribs.premultipliedAlpha", "true");
+
+ webGL.depthFunc(webGL.ALWAYS);
+
+ webGL.stencilFunc(webGL.NEVER, 1, 1);
+ webGL.stencilOp(webGL.KEEP, webGL.KEEP, webGL.KEEP);
+
+ 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 colors = new WebGLUnsignedByteArray([
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255]);
+
+ var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
+ pixel[0] = buf[0];
+ pixel[1] = buf[1];
+ pixel[2] = buf[2];
+ pixel[3] = buf[3];
+ correctColor = (stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
+ shouldBe("pixel", "correctColor");
+}
+
+function testAntialias(antialias)
+{
+ debug("Testing antialias = " + antialias);
+ if (antialias)
+ shouldBeNonNull("webGL = getWebGL('antialiasOn', { depth: false, stencil: false, alpha: false, antialias: true }, [ 0, 0, 0, 1 ], 1, 0)");
+ else
+ shouldBeNonNull("webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
+ shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
+ shouldBe("contextAttribs.depth", "false");
+ shouldBe("contextAttribs.stencil", "false");
+ shouldBe("contextAttribs.alpha", "false");
+ shouldBe("contextAttribs.antialias", (antialias ? "true" : "false"));
+ shouldBe("contextAttribs.premultipliedAlpha", "true");
+
+ var vertices = new WebGLFloatArray([
+ 1.0, 1.0, 0.0,
+ -1.0, 1.0, 0.0,
+ -1.0, -1.0, 0.0]);
+ var colors = new WebGLUnsignedByteArray([
+ 255, 0, 0, 255,
+ 255, 0, 0, 255,
+ 255, 0, 0, 255]);
+ var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
+ pixel[0] = buf[0];
+ shouldBe("pixel[0] == 255 || pixel[0] == 0", (antialias ? "false" : "true"));
+}
+
+function runTest()
+{
+
+ testAlpha(true);
+ testAlpha(false);
+ testDepth(true);
+ testDepth(false);
+ testStencil(true);
+ testStencil(false);
+ testAntialias(true);
+ testAntialias(false);
+
+ 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="alphaOn" width="1px" height="1px"></canvas>
+<canvas id="alphaOff" width="1px" height="1px"></canvas>
+<canvas id="depthOn" width="1px" height="1px"></canvas>
+<canvas id="depthOff" width="1px" height="1px"></canvas>
+<canvas id="stencilOn" width="1px" height="1px"></canvas>
+<canvas id="stencilOff" width="1px" height="1px"></canvas>
+<canvas id="antialiasOn" width="2px" height="2px"></canvas>
+<canvas id="antialiasOff" width="2px" height="2px"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt b/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt
index d963c65..daa36c2 100644
--- a/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/context-attributes-expected.txt
@@ -7,8 +7,8 @@ PASS context = create3DContext() is non-null.
PASS attribs = context.getContextAttributes() is non-null.
PASS attribs.depth is true
PASS attribs.alpha is true
-PASS (attribs.stencil == true || attribs.stencil == false) is true
-PASS (attribs.antialias == true || attribs.antialias == false) is true
+PASS attribs.stencil is true
+PASS attribs.antialias is true
PASS attribs.premultipliedAlpha is true
Test customized values
PASS context = create3DContext({ stencil: false, antialias: false }) is non-null.
@@ -18,6 +18,22 @@ PASS attribs.alpha is true
PASS attribs.stencil is false
PASS attribs.antialias is false
PASS attribs.premultipliedAlpha is true
+Test customized values
+PASS context = create3DContext({ depth: false, stencil: true }) is non-null.
+PASS attribs = context.getContextAttributes() is non-null.
+PASS attribs.depth is true
+PASS attribs.alpha is true
+PASS attribs.stencil is true
+PASS attribs.antialias is true
+PASS attribs.premultipliedAlpha is true
+Test customized values
+PASS context = create3DContext({ premultipliedAlpha: false }) is non-null.
+PASS attribs = context.getContextAttributes() is non-null.
+PASS attribs.depth is true
+PASS attribs.alpha is true
+PASS attribs.stencil is true
+PASS attribs.antialias is true
+PASS attribs.premultipliedAlpha is true
PASS successfullyParsed is true
TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/context-attributes.html b/LayoutTests/fast/canvas/webgl/context-attributes.html
index 7e3949a..0bfebce 100644
--- a/LayoutTests/fast/canvas/webgl/context-attributes.html
+++ b/LayoutTests/fast/canvas/webgl/context-attributes.html
@@ -18,9 +18,8 @@ shouldBeNonNull("context = create3DContext()");
shouldBeNonNull("attribs = context.getContextAttributes()");
shouldBe("attribs.depth", "true");
shouldBe("attribs.alpha", "true");
-// The following two depend on whether the implementation actually supports them
-shouldBe("(attribs.stencil == true || attribs.stencil == false)", "true");
-shouldBe("(attribs.antialias == true || attribs.antialias == false)", "true");
+shouldBe("attribs.stencil", "true");
+shouldBe("attribs.antialias", "true");
shouldBe("attribs.premultipliedAlpha", "true");
debug ("Test customized values");
@@ -32,6 +31,26 @@ shouldBe("attribs.stencil", "false");
shouldBe("attribs.antialias", "false");
shouldBe("attribs.premultipliedAlpha", "true");
+debug("Test customized values");
+// (stencil == true && depth == false) is not supported, default depth to true
+shouldBeNonNull("context = create3DContext({ depth: false, stencil: true })");
+shouldBeNonNull("attribs = context.getContextAttributes()");
+shouldBe("attribs.depth", "true");
+shouldBe("attribs.alpha", "true");
+shouldBe("attribs.stencil", "true");
+shouldBe("attribs.antialias", "true");
+shouldBe("attribs.premultipliedAlpha", "true");
+
+debug("Test customized values");
+// (premultipliedAlpha == false) is not supported, default to true
+shouldBeNonNull("context = create3DContext({ premultipliedAlpha: false })");
+shouldBeNonNull("attribs = context.getContextAttributes()");
+shouldBe("attribs.depth", "true");
+shouldBe("attribs.alpha", "true");
+shouldBe("attribs.stencil", "true");
+shouldBe("attribs.antialias", "true");
+shouldBe("attribs.premultipliedAlpha", "true");
+
successfullyParsed = true;
</script>
diff --git a/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt b/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt
index ad80582..a986a96 100644
--- a/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/gl-get-calls-expected.txt
@@ -53,7 +53,7 @@ PASS context.getParameter(context.STENCIL_BACK_FUNC) is context.ALWAYS
PASS context.getParameter(context.STENCIL_BACK_PASS_DEPTH_FAIL) is context.KEEP
PASS context.getParameter(context.STENCIL_BACK_PASS_DEPTH_PASS) is context.KEEP
PASS context.getParameter(context.STENCIL_BACK_REF) is 0
-PASS context.getParameter(context.STENCIL_BITS) is 0
+PASS context.getParameter(context.STENCIL_BITS) > 0 is true
PASS context.getParameter(context.STENCIL_CLEAR_VALUE) is 0
PASS context.getParameter(context.STENCIL_FAIL) is context.KEEP
PASS context.getParameter(context.STENCIL_FUNC) is context.ALWAYS
diff --git a/LayoutTests/fast/canvas/webgl/gl-get-calls.html b/LayoutTests/fast/canvas/webgl/gl-get-calls.html
index 955704a..215e6ad 100644
--- a/LayoutTests/fast/canvas/webgl/gl-get-calls.html
+++ b/LayoutTests/fast/canvas/webgl/gl-get-calls.html
@@ -82,7 +82,7 @@ else {
// FIXME: Current WebKit implementation returns the wrong value (https://bugs.webkit.org/show_bug.cgi?id=31842)
//shouldBe('context.getParameter(context.STENCIL_BACK_VALUE_MASK)', '0xFFFFFFFF');
//shouldBe('context.getParameter(context.STENCIL_BACK_WRITEMASK)', '0xFFFFFFFF');
- shouldBe('context.getParameter(context.STENCIL_BITS)', '0');
+ shouldBe('context.getParameter(context.STENCIL_BITS) > 0', 'true');
shouldBe('context.getParameter(context.STENCIL_CLEAR_VALUE)', '0');
shouldBe('context.getParameter(context.STENCIL_FAIL)', 'context.KEEP');
shouldBe('context.getParameter(context.STENCIL_FUNC)', 'context.ALWAYS');
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3df47eb..e17936e 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2010-03-16 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Darin Fisher.
+
+ Hook up WebGLContextAttributes to OpenGL context creation code
+ https://bugs.webkit.org/show_bug.cgi?id=33416
+
+ Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
+
+ * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp: Fix an index bug.
+ * platform/graphics/GraphicsContext3D.h: Add members/functions for multisampling/stencil buffer purpose.
+ * platform/graphics/mac/Canvas3DLayer.h: Add GraphicsContext3D as a member of Canvas3DLayer.
+ * platform/graphics/mac/Canvas3DLayer.mm: Add multisampling support.
+ * platform/graphics/mac/GraphicsContext3DMac.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Mac.
+ * platform/graphics/mac/GraphicsLayerCA.mm: Adjust to modified Canvas3DLayer init call.
+
2010-03-16 Joanmarie Diggs <joanmarie.diggs at gmail.com>
Reviewed by Xan Lopez.
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index 8aa3b78..67ba38b 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -56,7 +56,7 @@ v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Argument
if (contextId == "experimental-webgl" || contextId == "webkit-3d") {
attrs = WebGLContextAttributes::create();
WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get());
- if (args.Length() > 1 && args[0]->IsObject()) {
+ if (args.Length() > 1 && args[1]->IsObject()) {
v8::Handle<v8::Object> jsAttrs = args[1]->ToObject();
v8::Handle<v8::String> alpha = v8::String::New("alpha");
if (jsAttrs->Has(alpha))
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 3acbebf..f15583d 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -425,7 +425,12 @@ namespace WebCore {
Platform3DObject platformTexture() const { return NullPlatform3DObject; }
#endif
void makeContextCurrent();
-
+
+#if PLATFORM(MAC)
+ // With multisampling on, blit from multisampleFBO to regular FBO.
+ void prepareTexture();
+#endif
+
// Helper to return the size in bytes of OpenGL data types
// like GL_FLOAT, GL_INT, etc.
int sizeInBytes(int type);
@@ -717,7 +722,16 @@ namespace WebCore {
CGLContextObj m_contextObj;
GLuint m_texture;
GLuint m_fbo;
- GLuint m_depthBuffer;
+ GLuint m_depthStencilBuffer;
+
+ // For tracking which FBO is bound
+ GLuint m_boundFBO;
+
+ // For multisampling
+ GLuint m_multisampleFBO;
+ GLuint m_multisampleDepthStencilBuffer;
+ GLuint m_multisampleColorBuffer;
+
// Errors raised by synthesizeGLError().
ListHashSet<unsigned long> m_syntheticErrors;
#endif
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.h b/WebCore/platform/graphics/mac/Canvas3DLayer.h
index 122ef39..4609010 100644
--- a/WebCore/platform/graphics/mac/Canvas3DLayer.h
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.h
@@ -32,16 +32,18 @@
namespace WebCore {
class GraphicsLayer;
+ class GraphicsContext3D;
}
@interface Canvas3DLayer : CAOpenGLLayer
{
WebCore::GraphicsLayer* m_layerOwner;
+ WebCore::GraphicsContext3D* m_context;
CGLContextObj m_contextObj;
GLuint m_texture;
}
-- (id)initWithContext:(CGLContextObj)context texture:(GLuint)texture;
+- (id)initWithContext:(WebCore::GraphicsContext3D*)context;
- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.mm b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
index 59a7384..22a0a10 100644
--- a/WebCore/platform/graphics/mac/Canvas3DLayer.mm
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
@@ -41,10 +41,11 @@ using namespace WebCore;
@implementation Canvas3DLayer
--(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture
+-(id)initWithContext:(GraphicsContext3D*)context
{
- m_contextObj = context;
- m_texture = texture;
+ m_context = context;
+ m_contextObj = static_cast<CGLContextObj>(context->platformGraphicsContext3D());
+ m_texture = static_cast<GLuint>(context->platformTexture());
self = [super init];
return self;
}
@@ -70,8 +71,8 @@ using namespace WebCore;
-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
- CGLSetCurrentContext(m_contextObj);
- glFinish();
+ m_context->prepareTexture();
+
CGLSetCurrentContext(glContext);
CGRect frame = [self frame];
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index 096cdbd..0eb801d 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -86,16 +86,19 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs)
, m_contextObj(0)
, m_texture(0)
, m_fbo(0)
- , m_depthBuffer(0)
-{
- // FIXME: we need to take into account the user's requested
- // context creation attributes, in particular stencil and
- // antialias, and determine which could and could not be honored
- // based on the capabilities of the OpenGL implementation.
- m_attrs.alpha = true;
- m_attrs.depth = true;
- m_attrs.stencil = false;
- m_attrs.antialias = false;
+ , m_depthStencilBuffer(0)
+ , m_boundFBO(0)
+ , m_multisampleFBO(0)
+ , m_multisampleDepthStencilBuffer(0)
+ , m_multisampleColorBuffer(0)
+{
+ // Take into account the user's requested context creation attributes, in
+ // particular stencil and antialias, and determine which could and could
+ // not be honored based on the capabilities of the OpenGL implementation.
+ if (m_attrs.stencil && !m_attrs.depth)
+ m_attrs.depth = true;
+ // FIXME: instead of enforcing premultipliedAlpha = true, implement the
+ // correct behavior when premultipliedAlpha = false is requested.
m_attrs.premultipliedAlpha = true;
Vector<CGLPixelFormatAttribute> attribs;
@@ -152,21 +155,25 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs)
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
::glBindTexture(GL_TEXTURE_2D, 0);
-
+
// create an FBO
::glGenFramebuffersEXT(1, &m_fbo);
::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
-
- ::glGenRenderbuffersEXT(1, &m_depthBuffer);
- ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
- ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1);
- ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
-
- ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
-
+ m_boundFBO = m_fbo;
+ if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
+ ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
+
+ // create an multisample FBO
+ if (m_attrs.antialias) {
+ ::glGenFramebuffersEXT(1, &m_multisampleFBO);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ m_boundFBO = m_multisampleFBO;
+ ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ }
+
::glClearColor(0, 0, 0, 0);
}
@@ -174,8 +181,16 @@ GraphicsContext3D::~GraphicsContext3D()
{
if (m_contextObj) {
CGLSetCurrentContext(m_contextObj);
- ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
::glDeleteTextures(1, &m_texture);
+ if (m_attrs.antialias) {
+ ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
+ } else {
+ if (m_attrs.stencil || m_attrs.depth)
+ ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
+ }
::glDeleteFramebuffersEXT(1, &m_fbo);
CGLSetCurrentContext(0);
CGLDestroyContext(m_contextObj);
@@ -205,25 +220,87 @@ void GraphicsContext3D::reshape(int width, int height)
m_currentHeight = height;
CGLSetCurrentContext(m_contextObj);
-
+
+ GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0;
+ if (m_attrs.alpha) {
+ internalColorFormat = GL_RGBA8;
+ colorFormat = GL_RGBA;
+ } else {
+ internalColorFormat = GL_RGB8;
+ colorFormat = GL_RGB;
+ }
+ if (m_attrs.stencil || m_attrs.depth) {
+ // We don't allow the logic where stencil is required and depth is not.
+ // See GraphicsContext3D constructor.
+ if (m_attrs.stencil && m_attrs.depth)
+ internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
+ else
+ internalDepthStencilFormat = GL_DEPTH_COMPONENT;
+ }
+
+ bool mustRestoreFBO = false;
+
+ // resize multisample FBO
+ if (m_attrs.antialias) {
+ GLint maxSampleCount;
+ ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
+ GLint sampleCount = std::min(8, maxSampleCount);
+ if (sampleCount > maxSampleCount)
+ sampleCount = maxSampleCount;
+ if (m_boundFBO != m_multisampleFBO) {
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ mustRestoreFBO = true;
+ }
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
+ ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth) {
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
+ if (m_attrs.stencil)
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ if (m_attrs.depth)
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ }
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ // FIXME: cleanup.
+ notImplemented();
+ }
+ }
+
+ // resize regular FBO
+ if (m_boundFBO != m_fbo) {
+ mustRestoreFBO = true;
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ }
::glBindTexture(GL_TEXTURE_2D, m_texture);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- ::glBindTexture(GL_TEXTURE_2D, 0);
-
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
- ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
- ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
- ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
-
+ ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
- ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
- GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- // FIXME: cleanup
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+ if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
+ if (m_attrs.stencil)
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ if (m_attrs.depth)
+ ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
+ if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ // FIXME: cleanup.
notImplemented();
}
- ::glClear(GL_COLOR_BUFFER_BIT);
+ if (mustRestoreFBO)
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
+
+ GLenum clearMask = GL_COLOR_BUFFER_BIT;
+ if (m_attrs.depth)
+ clearMask |= GL_DEPTH_BUFFER_BIT;
+ if (m_attrs.stencil)
+ clearMask |= GL_STENCIL_BUFFER_BIT;
+ ::glClear(clearMask);
::glFlush();
}
@@ -243,6 +320,18 @@ void GraphicsContext3D::activeTexture(unsigned long texture)
::glActiveTexture(texture);
}
+void GraphicsContext3D::prepareTexture()
+{
+ if (m_attrs.antialias) {
+ ensureContext(m_contextObj);
+ ::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_boundFBO);
+ ::glFinish();
+ }
+}
+
void GraphicsContext3D::attachShader(WebGLProgram* program, WebGLShader* shader)
{
ASSERT(program);
@@ -268,7 +357,15 @@ void GraphicsContext3D::bindBuffer(unsigned long target, WebGLBuffer* buffer)
void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer)
{
ensureContext(m_contextObj);
- ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo);
+ GLuint fbo;
+ if (buffer && buffer->object())
+ fbo = (GLuint)buffer->object();
+ else
+ fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
+ if (fbo != m_boundFBO) {
+ ::glBindFramebufferEXT(target, fbo);
+ m_boundFBO = fbo;
+ }
}
void GraphicsContext3D::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderbuffer)
@@ -675,9 +772,25 @@ PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, unsigned lo
// FIXME: Also, we should throw when an unacceptable value is passed
if (type != GL_UNSIGNED_BYTE || format != GL_RGBA)
return 0;
-
+
+ if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
+ ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
+ ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
+ ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ }
RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());
+ if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ if (!m_attrs.alpha) {
+ // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
+ // This is a hack until ::glReadPixels fixes its behavior.
+ GLubyte* data = reinterpret_cast<GLubyte*>(array->data());
+ unsigned byteLength = array->byteLength();
+ for (unsigned i = 3; i < byteLength; i += 4)
+ data[i] = 255;
+ }
return array;
}
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index caf2622..c946412 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -1716,7 +1716,7 @@ void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* gr
if (m_platformGraphicsContext3D != NullPlatformGraphicsContext3D && m_platformTexture != NullPlatform3DObject) {
// create the inner 3d layer
- m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:static_cast<CGLContextObj>(m_platformGraphicsContext3D) texture:static_cast<GLuint>(m_platformTexture)]);
+ m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:const_cast<GraphicsContext3D*>(graphicsContext3D)]);
#ifndef NDEBUG
[m_contentsLayer.get() setName:@"3D Layer"];
#endif
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index a43a71e..7acaa9f 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,14 @@
+2010-03-16 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Darin Fisher.
+
+ Hook up WebGLContextAttributes to OpenGL context creation code
+ https://bugs.webkit.org/show_bug.cgi?id=33416
+
+ Test: fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias.html
+
+ * src/GraphicsContext3D.cpp: Hook up WebGLContextAttributes to OpenGL context creation code for Windows.
+
2010-03-16 Yury Semikhatsky <yurys at chromium.org>
Unreviewed.
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index 807a794..5610fe6 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -124,16 +124,23 @@ public:
unsigned long stride, unsigned long offset);
void viewportImpl(long x, long y, unsigned long width, unsigned long height);
+ void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* buffer);
+
void synthesizeGLError(unsigned long error);
private:
GraphicsContext3D::Attributes m_attrs;
-
+
unsigned int m_texture;
unsigned int m_fbo;
- unsigned int m_depthBuffer;
+ unsigned int m_depthStencilBuffer;
unsigned int m_cachedWidth, m_cachedHeight;
+ // For multisampling
+ unsigned int m_multisampleFBO;
+ unsigned int m_multisampleDepthStencilBuffer;
+ unsigned int m_multisampleColorBuffer;
+
// For tracking which FBO is bound
unsigned int m_boundFBO;
@@ -351,7 +358,10 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
: m_attrs(attrs)
, m_texture(0)
, m_fbo(0)
- , m_depthBuffer(0)
+ , m_depthStencilBuffer(0)
+ , m_multisampleFBO(0)
+ , m_multisampleDepthStencilBuffer(0)
+ , m_multisampleColorBuffer(0)
, m_boundFBO(0)
#ifdef FLIP_FRAMEBUFFER_VERTICALLY
, m_scanline(0)
@@ -375,14 +385,21 @@ GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attribut
#error Must port to your platform
#endif
{
- // FIXME: we need to take into account the user's requested
- // context creation attributes, in particular stencil and
- // antialias, and determine which could and could not be honored
- // based on the capabilities of the OpenGL implementation.
- m_attrs.alpha = true;
- m_attrs.depth = true;
- m_attrs.stencil = false;
- m_attrs.antialias = false;
+ // Take into account the user's requested context creation attributes, in
+ // particular stencil and antialias, and determine which could and could
+ // not be honored based on the capabilities of the OpenGL implementation.
+ if (m_attrs.stencil) {
+ if (GLEW_EXT_packed_depth_stencil) {
+ if (!m_attrs.depth)
+ m_attrs.depth = true;
+ } else {
+ m_attrs.stencil = false;
+ }
+ }
+ if (m_attrs.antialias && !GLEW_EXT_framebuffer_multisample)
+ m_attrs.antialias = false;
+ // FIXME: instead of enforcing premultipliedAlpha = true, implement the
+ // correct behavior when premultipliedAlpha = false is requested.
m_attrs.premultipliedAlpha = true;
#if OS(WINDOWS)
@@ -572,7 +589,15 @@ GraphicsContext3DInternal::~GraphicsContext3DInternal()
{
makeContextCurrent();
#ifndef RENDER_TO_DEBUGGING_WINDOW
- glDeleteRenderbuffersEXT(1, &m_depthBuffer);
+ if (m_attrs.antialias) {
+ glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.depth || m_attrs.stencil)
+ glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ glDeleteFramebuffersEXT(1, &m_multisampleFBO);
+ } else {
+ if (m_attrs.depth || m_attrs.stencil)
+ glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
+ }
glDeleteTextures(1, &m_texture);
#ifdef FLIP_FRAMEBUFFER_VERTICALLY
if (m_scanline)
@@ -669,23 +694,88 @@ void GraphicsContext3DInternal::reshape(int width, int height)
m_texture = createTextureObject(target);
// Generate the framebuffer object
glGenFramebuffersEXT(1, &m_fbo);
- // Generate the depth buffer
- glGenRenderbuffersEXT(1, &m_depthBuffer);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ m_boundFBO = m_fbo;
+ if (m_attrs.depth || m_attrs.stencil)
+ glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
+ // Generate the multisample framebuffer object
+ if (m_attrs.antialias) {
+ glGenFramebuffersEXT(1, &m_multisampleFBO);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ m_boundFBO = m_multisampleFBO;
+ glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ if (m_attrs.depth || m_attrs.stencil)
+ glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ }
}
- // Reallocate the color and depth buffers
- glBindTexture(target, m_texture);
- glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glBindTexture(target, 0);
+ GLint internalColorFormat, colorFormat, internalDepthStencilFormat;
+ if (m_attrs.alpha) {
+ internalColorFormat = GL_RGBA8;
+ colorFormat = GL_RGBA;
+ } else {
+ internalColorFormat = GL_RGB8;
+ colorFormat = GL_RGB;
+ }
+ if (m_attrs.stencil || m_attrs.depth) {
+ // We don't allow the logic where stencil is required and depth is not.
+ // See GraphicsContext3DInternal constructor.
+ if (m_attrs.stencil && m_attrs.depth)
+ internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT;
+ else
+ internalDepthStencilFormat = GL_DEPTH_COMPONENT;
+ }
+
+ bool mustRestoreFBO = false;
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
- m_boundFBO = m_fbo;
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ // Resize multisampling FBO
+ if (m_attrs.antialias) {
+ GLint maxSampleCount;
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount);
+ GLint sampleCount = std::min(8, maxSampleCount);
+ if (m_boundFBO != m_multisampleFBO) {
+ mustRestoreFBO = true;
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ }
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
+ glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth) {
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height);
+ if (m_attrs.stencil)
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ if (m_attrs.depth)
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer);
+ }
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ printf("GraphicsContext3D: multisampling framebuffer was incomplete\n");
+ // FIXME: cleanup.
+ notImplemented();
+ }
+ }
+
+ // Resize regular FBO
+ if (m_boundFBO != m_fbo) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ mustRestoreFBO = true;
+ }
+ glBindTexture(target, m_texture);
+ glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
+ glBindTexture(target, 0);
+ if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) {
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height);
+ if (m_attrs.stencil)
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ if (m_attrs.depth)
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+ }
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
printf("GraphicsContext3D: framebuffer was incomplete\n");
@@ -693,6 +783,9 @@ void GraphicsContext3DInternal::reshape(int width, int height)
// FIXME: cleanup.
notImplemented();
}
+
+ if (mustRestoreFBO)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
#endif // RENDER_TO_DEBUGGING_WINDOW
#ifdef FLIP_FRAMEBUFFER_VERTICALLY
@@ -703,7 +796,12 @@ void GraphicsContext3DInternal::reshape(int width, int height)
m_scanline = new unsigned char[width * 4];
#endif // FLIP_FRAMEBUFFER_VERTICALLY
- glClear(GL_COLOR_BUFFER_BIT);
+ GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
+ if (m_attrs.stencil)
+ clearMask |= GL_STENCIL_BUFFER_BIT;
+ if (m_attrs.depth)
+ clearMask |= GL_DEPTH_BUFFER_BIT;
+ glClear(clearMask);
#if PLATFORM(CG)
// Need to reallocate the client-side backing store.
@@ -758,9 +856,19 @@ void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
unsigned char* pixels = 0;
- bool mustRestoreFBO = (m_boundFBO != m_fbo);
- if (mustRestoreFBO)
+ bool mustRestoreFBO;
+ if (m_attrs.antialias) {
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
+ glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, 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);
+ }
+ }
#if PLATFORM(SKIA)
const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
const SkBitmap* readbackBitmap = 0;
@@ -865,6 +973,23 @@ void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context)
#endif // RENDER_TO_DEBUGGING_WINDOW
}
+void GraphicsContext3DInternal::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* buffer)
+{
+#ifndef RENDER_TO_DEBUGGING_WINDOW
+ if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
+ glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ }
+#endif
+ glReadPixels(x, y, width, height, format, type, buffer);
+#ifndef RENDER_TO_DEBUGGING_WINDOW
+ if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
+#endif
+}
+
void GraphicsContext3DInternal::activeTexture(unsigned long texture)
{
// FIXME: query number of textures available.
@@ -892,9 +1017,11 @@ void GraphicsContext3DInternal::bindFramebuffer(unsigned long target,
makeContextCurrent();
GLuint id = EXTRACT(framebuffer);
if (!id)
- id = m_fbo;
- glBindFramebufferEXT(target, id);
- m_boundFBO = id;
+ id = (m_attrs.antialias ? m_multisampleFBO : m_fbo);
+ if (id != m_boundFBO) {
+ glBindFramebufferEXT(target, id);
+ m_boundFBO = id;
+ }
}
// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps,
@@ -1809,7 +1936,18 @@ PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y,
// FIXME: take into account pack alignment.
RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4);
- glReadPixels(x, y, width, height, format, type, array->baseAddress());
+ m_internal->readPixels(x, y, width, height, format, type, array->baseAddress());
+#if OS(DARWIN)
+ GraphicsContext3D::Attributes attrs = m_internal->getContextAttributes();
+ if (!attrs.alpha) {
+ // If alpha is off, by default glReadPixels should set the alpha to 255 instead of 0.
+ // This is a hack until ::glReadPixels fixes its behavior.
+ GLubyte* data = reinterpret_cast<GLubyte*>(array->baseAddress());
+ unsigned byteLength = array->byteLength();
+ for (unsigned i = 3; i < byteLength; i += 4)
+ data[i] = 255;
+ }
+#endif
return array;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list