2010-07-14 Kenneth Russell <kbr@google.com>
[WebKit-https.git] / LayoutTests / fast / canvas / webgl / context-attributes-alpha-depth-stencil-antialias.html
1 <html>
2 <head>
3 <link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
4 <script src="../../js/resources/js-test-pre.js"></script>
5 <script src="resources/webgl-test.js"></script>
6 <script id="vshader" type="x-shader/x-vertex">
7 attribute vec3 pos;
8 attribute vec4 colorIn;
9 varying vec4 color;
10
11 void main()
12 {
13     color = colorIn;
14     gl_Position = vec4(pos.xyz, 1.0);
15 }
16 </script>
17
18 <script id="fshader" type="x-shader/x-fragment">
19 varying vec4 color;
20
21 void main()
22 {
23     gl_FragColor = color;
24 }
25 </script>
26
27 <script>
28 var successfullyParsed = false;
29
30 // These four declarations need to be global for "shouldBe" to see them
31 var webGL = null;
32 var contextAttribs = null;
33 var pixel = [0, 0, 0, 1];
34 var correctColor = null;
35
36 function init()
37 {
38     if (window.layoutTestController) {
39         layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
40         layoutTestController.dumpAsText();
41         layoutTestController.waitUntilDone();
42     }
43
44     description('Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha');
45
46     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>');
47     
48     runTest();
49 }
50
51 function getWebGL(canvasName, contextAttribs, clearColor, clearDepth, clearStencil)
52 {
53     var canvas = document.getElementById(canvasName);
54     var gl = canvas.getContext("experimental-webgl", contextAttribs);
55     if (!gl) {
56         alert("No WebGL context found");
57         return null;
58     }
59     var actualContextAttribs = gl.getContextAttributes();
60     
61     // Add a console
62     gl.console = ("console" in window) ? window.console : { log: function() { } };
63
64     // create our shaders
65     var vertexShader = loadShader(gl, "vshader");
66     var fragmentShader = loadShader(gl, "fshader");
67
68     if (!vertexShader || !fragmentShader)
69         return null;
70
71     // Create the program object
72     gl.program = gl.createProgram();
73
74     if (!gl.program)
75         return null;
76
77     // Attach our two shaders to the program
78     gl.attachShader(gl.program, vertexShader);
79     gl.attachShader(gl.program, fragmentShader);
80
81     // Bind attributes
82     var attribs = [ "pos", "colorIn" ];
83     for (var i in attribs)
84         gl.bindAttribLocation(gl.program, i, attribs[i]);
85
86     // Link the program
87     gl.linkProgram(gl.program);
88
89     // Check the link status
90     var linked = gl.getProgramParameter(gl.program, gl.LINK_STATUS);
91     if (!linked) {
92         // something went wrong with the link
93         var error = gl.getProgramInfoLog (gl.program);
94         gl.console.log("Error in program linking:"+error);
95
96         gl.deleteProgram(gl.program);
97         gl.deleteProgram(fragmentShader);
98         gl.deleteProgram(vertexShader);
99
100         return null;
101     }
102
103     gl.useProgram(gl.program);
104
105     gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
106     gl.clearDepth(clearDepth);
107     gl.clearStencil(clearStencil);
108     gl.enable(gl.DEPTH_TEST);
109     gl.enable(gl.STENCIL_TEST);
110     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
111
112     return gl;
113 }
114
115 function drawAndReadPixel(gl, vertices, colors, x, y)
116 {
117     var colorOffset = vertices.byteLength;
118
119     var vbo = gl.createBuffer();
120     gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
121     gl.bufferData(gl.ARRAY_BUFFER, colorOffset + colors.byteLength, gl.STATIC_DRAW);
122     gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
123     gl.bufferSubData(gl.ARRAY_BUFFER, colorOffset, colors);
124
125     gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
126     gl.enableVertexAttribArray(0);
127     gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, colorOffset);
128     gl.enableVertexAttribArray(1);
129
130     gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);
131
132     var buf = new Uint8Array(1 * 1 * 4);
133     gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
134     return buf;
135 }
136
137 function testAlpha(alpha)
138 {
139     debug("Testing alpha = " + alpha);
140     if (alpha)
141         shouldBeNonNull("webGL = getWebGL('alphaOn', { alpha: true, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
142     else
143         shouldBeNonNull("webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
144     shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
145     shouldBe("contextAttribs.alpha", (alpha ? "true" : "false"));
146     shouldBe("contextAttribs.depth", "false");
147     shouldBe("contextAttribs.stencil", "false");
148     shouldBe("contextAttribs.antialias", "false");
149     shouldBe("contextAttribs.premultipliedAlpha", "true");
150
151     var buf = new Uint8Array(1 * 1 * 4);
152     webGL.readPixels(0, 0, 1, 1, webGL.RGBA, webGL.UNSIGNED_BYTE, buf);
153     pixel[0] = buf[0];
154     pixel[1] = buf[1];
155     pixel[2] = buf[2];
156     pixel[3] = buf[3];
157     correctColor = (alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]);
158     shouldBe("pixel", "correctColor");
159 }
160
161 function testDepth(depth)
162 {
163     debug("Testing depth = " + depth);
164     if (depth)
165         shouldBeNonNull("webGL = getWebGL('depthOn', { stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
166     else
167         shouldBeNonNull("webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
168     shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
169     shouldBe("contextAttribs.depth", (depth ? "true" : "false"));
170     shouldBe("contextAttribs.alpha", "true");
171     shouldBe("contextAttribs.stencil", "false");
172     shouldBe("contextAttribs.antialias", "false");
173     shouldBe("contextAttribs.premultipliedAlpha", "true");
174
175     webGL.depthFunc(webGL.NEVER);
176
177     var vertices = new WebGLFloatArray([
178          1.0,  1.0, 0.0,
179         -1.0,  1.0, 0.0,
180         -1.0, -1.0, 0.0,
181          1.0,  1.0, 0.0,
182         -1.0, -1.0, 0.0,
183          1.0, -1.0, 0.0]);
184     var colors = new WebGLUnsignedByteArray([
185         255, 0, 0, 255,
186         255, 0, 0, 255,
187         255, 0, 0, 255,
188         255, 0, 0, 255,
189         255, 0, 0, 255,
190         255, 0, 0, 255]);
191
192     var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
193     pixel[0] = buf[0];
194     pixel[1] = buf[1];
195     pixel[2] = buf[2];
196     pixel[3] = buf[3];
197     correctColor = (depth ? [0, 0, 0, 255] : [255, 0, 0, 255]);
198     shouldBe("pixel", "correctColor");
199 }
200
201 function testStencil(stencil)
202 {
203     debug("Testing stencil = " + stencil);
204     if (stencil)
205         shouldBeNonNull("webGL = getWebGL('stencilOn', { depth: false, stencil: true, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
206     else
207         shouldBeNonNull("webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
208     shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
209     // If EXT_packed_depth_stencil is supported, both depth & stencil will be true; otherwise, both will be false.
210     shouldBe("contextAttribs.depth == contextAttribs.stencil", "true");
211     shouldBe("contextAttribs.alpha", "true");
212     shouldBe("contextAttribs.antialias", "false");
213     shouldBe("contextAttribs.premultipliedAlpha", "true");
214
215     webGL.depthFunc(webGL.ALWAYS);
216
217     webGL.stencilFunc(webGL.NEVER, 1, 1);
218     webGL.stencilOp(webGL.KEEP, webGL.KEEP, webGL.KEEP);
219
220     var vertices = new WebGLFloatArray([
221          1.0, 1.0, 0.0,
222         -1.0, 1.0, 0.0,
223         -1.0, -1.0, 0.0,
224          1.0, 1.0, 0.0,
225         -1.0, -1.0, 0.0,
226          1.0, -1.0, 0.0]);
227     var colors = new WebGLUnsignedByteArray([
228         255, 0, 0, 255,
229         255, 0, 0, 255,
230         255, 0, 0, 255,
231         255, 0, 0, 255,
232         255, 0, 0, 255,
233         255, 0, 0, 255]);
234
235     var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
236     pixel[0] = buf[0];
237     pixel[1] = buf[1];
238     pixel[2] = buf[2];
239     pixel[3] = buf[3];
240     correctColor = (stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
241     // If stencil is requested but not supported, we fake the effect.
242     if (stencil && !contextAttribs.stencil)
243         pixel[0] = 0;
244     shouldBe("pixel", "correctColor");
245 }
246
247 function testAntialias(antialias)
248 {
249     debug("Testing antialias = " + antialias);
250     if (antialias)
251         shouldBeNonNull("webGL = getWebGL('antialiasOn', { depth: false, stencil: false, alpha: false, antialias: true }, [ 0, 0, 0, 1 ], 1, 0)");
252     else
253         shouldBeNonNull("webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
254     shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
255     shouldBe("contextAttribs.depth", "false");
256     shouldBe("contextAttribs.stencil", "false");
257     shouldBe("contextAttribs.alpha", "false");
258     shouldBe("contextAttribs.antialias == true || contextAttribs.antialias == false", "true");
259     shouldBe("contextAttribs.premultipliedAlpha", "true");
260
261     var vertices = new WebGLFloatArray([
262          1.0, 1.0, 0.0,
263         -1.0, 1.0, 0.0,
264         -1.0, -1.0, 0.0]);
265     var colors = new WebGLUnsignedByteArray([
266         255, 0, 0, 255,
267         255, 0, 0, 255,
268         255, 0, 0, 255]);
269     var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
270     pixel[0] = buf[0];
271     // If antialias is requested but not supported, we fake the effect.
272     if (antialias && !contextAttribs.antialias)
273         pixel[0] = 127;
274     shouldBe("pixel[0] == 255 || pixel[0] == 0", (antialias ? "false" : "true"));
275 }
276
277 function runTest()
278 {
279
280     testAlpha(true);
281     testAlpha(false);
282     testDepth(true);
283     testDepth(false);
284     testStencil(true);
285     testStencil(false);
286     testAntialias(true);
287     testAntialias(false);
288
289     successfullyParsed = true;
290     var epilogue = document.createElement("script");
291     epilogue.onload = finish;
292     epilogue.src = "../../js/resources/js-test-post.js";
293     document.body.appendChild(epilogue);
294 }
295
296 function finish() {
297     if (window.layoutTestController) {
298         layoutTestController.notifyDone();
299     }
300 }
301 </script>
302 </head>
303 <body onload="init()">
304 <canvas id="alphaOn" width="1px" height="1px"></canvas>
305 <canvas id="alphaOff" width="1px" height="1px"></canvas>
306 <canvas id="depthOn" width="1px" height="1px"></canvas>
307 <canvas id="depthOff" width="1px" height="1px"></canvas>
308 <canvas id="stencilOn" width="1px" height="1px"></canvas>
309 <canvas id="stencilOff" width="1px" height="1px"></canvas>
310 <canvas id="antialiasOn" width="2px" height="2px"></canvas>
311 <canvas id="antialiasOff" width="2px" height="2px"></canvas>
312 <div id="description"></div>
313 <div id="console"></div>
314 </body>
315 </html>