[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