Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 <!--
2 Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 Use of this source code is governed by a BSD-style license that can be
4 found in the LICENSE file.
5 -->
6 <!DOCTYPE html>
7 <html>
8 <head>
9 <meta charset="utf-8">
10 <title>WebGL OES_standard_derivatives Conformance Tests</title>
11 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
12 <script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
13 <script src="../../resources/js-test-pre.js"></script>
14 <script src="../resources/webgl-test.js"></script>
15 <script src="../resources/webgl-test-utils.js"></script>
16 </head>
17 <body>
18 <div id="description"></div>
19 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
20 <div id="console"></div>
21 <!-- Shaders for testing standard derivatives -->
23 <!-- Shader omitting the required #extension pragma -->
24 <script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
25 precision mediump float;
26 varying vec2 texCoord;
27 void main() {
28 float dx = dFdx(texCoord.x);
29 float dy = dFdy(texCoord.y);
30 float w = fwidth(texCoord.x);
31 gl_FragColor = vec4(dx, dy, w, 1.0);
32 }
33 </script>
35 <!-- Shader to test macro definition -->
36 <script id="macroFragmentShader" type="x-shader/x-fragment">
37 precision mediump float;
38 void main() {
39 #ifdef GL_OES_standard_derivatives
40 gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
41 #else
42 // Error expected
43 #error no GL_OES_standard_derivatives;
44 #endif
45 }
46 </script>
48 <!-- Shader with required #extension pragma -->
49 <script id="testFragmentShader" type="x-shader/x-fragment">
50 #extension GL_OES_standard_derivatives : enable
51 precision mediump float;
52 varying vec2 texCoord;
53 void main() {
54 float dx = dFdx(texCoord.x);
55 float dy = dFdy(texCoord.y);
56 float w = fwidth(texCoord.x);
57 gl_FragColor = vec4(dx, dy, w, 1.0);
58 }
59 </script>
60 <!-- Shaders to link with test fragment shaders -->
61 <script id="goodVertexShader" type="x-shader/x-vertex">
62 attribute vec4 vPosition;
63 varying vec2 texCoord;
64 void main() {
65 texCoord = vPosition.xy;
66 gl_Position = vPosition;
67 }
68 </script>
69 <!-- Shaders to test output -->
70 <script id="outputVertexShader" type="x-shader/x-vertex">
71 attribute vec4 vPosition;
72 varying vec4 position;
73 void main() {
74 position = vPosition;
75 gl_Position = vPosition;
76 }
77 </script>
78 <script id="outputFragmentShader" type="x-shader/x-fragment">
79 #extension GL_OES_standard_derivatives : enable
80 precision mediump float;
81 varying vec4 position;
82 void main() {
83 float dzdx = dFdx(position.z);
84 float dzdy = dFdy(position.z);
85 float fw = fwidth(position.z);
86 gl_FragColor = vec4(abs(dzdx), abs(dzdy), fw, 1.0);
87 }
88 </script>
90 <script>
91 description("This test verifies the functionality of the OES_standard_derivatives extension, if it is available.");
93 debug("");
95 var wtu = WebGLTestUtils;
96 var canvas = document.getElementById("canvas");
97 var gl = create3DContext(canvas);
98 var ext = null;
100 if (!gl) {
101 testFailed("WebGL context does not exist");
102 } else {
103 testPassed("WebGL context exists");
105 // Run tests with extension disabled
106 runHintTestDisabled();
107 runShaderTests(false);
109 // Query the extension and store globally so shouldBe can access it
110 ext = gl.getExtension("OES_standard_derivatives");
111 if (!ext) {
112 testPassed("No OES_standard_derivatives support -- this is legal");
114 runSupportedTest(false);
115 } else {
116 testPassed("Successfully enabled OES_standard_derivatives extension");
118 runSupportedTest(true);
120 runHintTestEnabled();
121 runShaderTests(true);
122 runOutputTests();
123 runUniqueObjectTest();
124 runReferenceCycleTest();
125 }
126 }
128 function runSupportedTest(extensionEnabled) {
129 var supported = gl.getSupportedExtensions();
130 if (supported.indexOf("OES_standard_derivatives") >= 0) {
131 if (extensionEnabled) {
132 testPassed("OES_standard_derivatives listed as supported and getExtension succeeded");
133 } else {
134 testFailed("OES_standard_derivatives listed as supported but getExtension failed");
135 }
136 } else {
137 if (extensionEnabled) {
138 testFailed("OES_standard_derivatives not listed as supported but getExtension succeeded");
139 } else {
140 testPassed("OES_standard_derivatives not listed as supported and getExtension failed -- this is legal");
141 }
142 }
143 }
145 function runHintTestDisabled() {
146 debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension disabled");
148 // Use the constant directly as we don't have the extension
149 var FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
151 gl.getParameter(FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
152 glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES should not be queryable if extension is disabled");
154 gl.hint(FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
155 glErrorShouldBe(gl, gl.INVALID_ENUM, "hint should not accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES if extension is disabled");
156 }
158 function runHintTestEnabled() {
159 debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension enabled");
161 shouldBe("ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES", "0x8B8B");
163 gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
164 glErrorShouldBe(gl, gl.NO_ERROR, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES query should succeed if extension is enabled");
166 // Default value is DONT_CARE
167 if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) == gl.DONT_CARE) {
168 testPassed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is DONT_CARE");
169 } else {
170 testFailed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is not DONT_CARE");
171 }
173 // Ensure that we can set the target
174 gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
175 glErrorShouldBe(gl, gl.NO_ERROR, "hint should accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES");
177 // Test all the hint modes
178 var validModes = ["FASTEST", "NICEST", "DONT_CARE"];
179 var anyFailed = false;
180 for (var n = 0; n < validModes.length; n++) {
181 var mode = validModes[n];
182 gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl[mode]);
183 if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) != gl[mode]) {
184 testFailed("Round-trip of hint()/getParameter() failed on mode " + mode);
185 anyFailed = true;
186 }
187 }
188 if (!anyFailed) {
189 testPassed("Round-trip of hint()/getParameter() with all supported modes");
190 }
191 }
193 function runShaderTests(extensionEnabled) {
194 debug("");
195 debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
197 // Expect the macro shader to succeed ONLY if enabled
198 var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
199 if (extensionEnabled) {
200 if (macroFragmentProgram) {
201 // Expected result
202 testPassed("GL_OES_standard_derivatives defined in shaders when extension is enabled");
203 } else {
204 testFailed("GL_OES_standard_derivatives not defined in shaders when extension is enabled");
205 }
206 } else {
207 if (macroFragmentProgram) {
208 testFailed("GL_OES_standard_derivatives defined in shaders when extension is disabled");
209 } else {
210 testPassed("GL_OES_standard_derivatives not defined in shaders when extension disabled");
211 }
212 }
214 // Always expect the shader missing the #pragma to fail (whether enabled or not)
215 var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
216 if (missingPragmaFragmentProgram) {
217 testFailed("Shader built-ins allowed without #extension pragma");
218 } else {
219 testPassed("Shader built-ins disallowed without #extension pragma");
220 }
222 // Try to compile a shader using the built-ins that should only succeed if enabled
223 var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
224 if (extensionEnabled) {
225 if (testFragmentProgram) {
226 testPassed("Shader built-ins compiled successfully when extension enabled");
227 } else {
228 testFailed("Shader built-ins failed to compile when extension enabled");
229 }
230 } else {
231 if (testFragmentProgram) {
232 testFailed("Shader built-ins compiled successfully when extension disabled");
233 } else {
234 testPassed("Shader built-ins failed to compile when extension disabled");
235 }
236 }
237 }
239 function runOutputTests() {
240 // This tests does several draws with various values of z.
241 // The output of the fragment shader is:
242 // [dFdx(z), dFdy(z), fwidth(z), 1.0]
243 // The expected math: (note the conversion to uint8)
244 // canvas.width = canvas.height = 50
245 // dFdx = totalChange.x / canvas.width = 0.5 / 50.0 = 0.01
246 // dFdy = totalChange.y / canvas.height = 0.5 / 50.0 = 0.01
247 // fw = abs(dFdx + dFdy) = 0.01 + 0.01 = 0.02
248 // r = floor(dFdx * 255) = 3
249 // g = floor(dFdy * 255) = 3
250 // b = floor(fw * 255) = 5
252 var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
254 debug("Testing various draws for valid built-in function behavior");
256 canvas.width = 50; canvas.height = 50;
257 gl.viewport(0, 0, canvas.width, canvas.height);
258 gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST);
260 var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
261 var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
263 function readLocation(x, y) {
264 var pixels = new Uint8Array(1 * 1 * 4);
265 var px = Math.floor(x * canvas.width);
266 var py = Math.floor(y * canvas.height);
267 gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
268 return pixels;
269 };
270 function toString(arr) {
271 var s = "[";
272 for (var n = 0; n < arr.length; n++) {
273 s += arr[n];
274 if (n < arr.length - 1) {
275 s += ", ";
276 }
277 }
278 return s + "]";
279 };
280 function expectResult(target, successMessage, failureMessage) {
281 var locations = [
282 readLocation(0.1, 0.1),
283 readLocation(0.9, 0.1),
284 readLocation(0.1, 0.9),
285 readLocation(0.9, 0.9),
286 readLocation(0.5, 0.5)
287 ];
288 var anyDiffer = false;
289 for (var n = 0; n < locations.length; n++) {
290 var source = locations[n];
291 for (var m = 0; m < 4; m++) {
292 if (Math.abs(source[m] - target[m]) > e) {
293 anyDiffer = true;
294 testFailed(failureMessage + "; should be " + toString(target) + ", was " + toString(source));
295 break;
296 }
297 }
298 }
299 if (!anyDiffer) {
300 testPassed(successMessage);
301 }
302 };
304 function setupBuffers(tl, tr, bl, br) {
305 gl.bindBuffer(gl.ARRAY_BUFFER, quadParameters[0]);
306 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
307 1.0, 1.0, tr,
308 -1.0, 1.0, tl,
309 -1.0, -1.0, bl,
310 1.0, 1.0, tr,
311 -1.0, -1.0, bl,
312 1.0, -1.0, br]), gl.STATIC_DRAW);
313 };
315 // Draw 1: (no variation)
316 setupBuffers(0.0, 0.0, 0.0, 0.0);
317 wtu.drawQuad(gl);
318 expectResult([0, 0, 0, 255],
319 "Draw 1 (no variation) returned the correct data",
320 "Draw 1 (no variation) returned incorrect data");
322 // Draw 2: (variation in x)
323 setupBuffers(1.0, 0.0, 1.0, 0.0);
324 wtu.drawQuad(gl);
325 expectResult([5, 0, 5, 255],
326 "Draw 2 (variation in x) returned the correct data",
327 "Draw 2 (variation in x) returned incorrect data");
329 // Draw 3: (variation in y)
330 setupBuffers(1.0, 1.0, 0.0, 0.0);
331 wtu.drawQuad(gl);
332 expectResult([0, 5, 5, 255],
333 "Draw 3 (variation in y) returned the correct data",
334 "Draw 3 (variation in y) returned incorrect data");
336 // Draw 4: (variation in x & y)
337 setupBuffers(1.0, 0.5, 0.5, 0.0);
338 wtu.drawQuad(gl);
339 expectResult([3, 3, 5, 255],
340 "Draw 4 (variation in x & y) returned the correct data",
341 "Draw 4 (variation in x & y) returned incorrect data");
343 }
345 function runUniqueObjectTest()
346 {
347 debug("Testing that getExtension() returns the same object each time");
348 gl.getExtension("OES_standard_derivatives").myProperty = 2;
349 gc();
350 shouldBe('gl.getExtension("OES_standard_derivatives").myProperty', '2');
351 }
353 function runReferenceCycleTest()
354 {
355 // create some reference cycles. The goal is to see if they cause leaks. The point is that
356 // some browser test runners have instrumentation to detect leaked refcounted objects.
358 debug("Testing reference cycles between context and extension objects");
359 var ext = gl.getExtension("OES_standard_derivatives");
361 // create cycle between extension and context, since the context has to hold a reference to the extension
362 ext.context = gl;
364 // create a self-cycle on the extension object
365 ext.ext = ext;
366 }
368 debug("");
369 successfullyParsed = true;
370 </script>
371 <script>finishTest();</script>
373 </body>
374 </html>