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