Backed out changeset 8fc3326bce7f (bug 1943032) for causing failures at browser_tab_g...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / extra / buffer-sizes.html
blob736c135b7a7e034eb9541008cbf69562d4dbc389
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>Buffer allocation test</title>
12 <link rel="stylesheet" href="../resources/js-test-style.css"/>
13 <script src="../js/js-test-pre.js"></script>
14 <script src="../js/webgl-test-utils.js"> </script>
15 </head>
16 <body>
17 <div id="canvasParent"></div>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script id="vshader" type="x-shader/x-vertex">
21 attribute vec2 inPosition;
22 attribute vec4 inColor0;
23 attribute vec4 inColor1;
24 attribute vec4 inColor2;
25 attribute vec4 inColor3;
26 attribute vec4 inColor4;
27 attribute vec4 inColor5;
28 attribute vec4 inColor6;
29 attribute vec4 inColor7;
31 varying vec4 color;
33 void main()
35 color = abs(inColor0) + abs(inColor1) + abs(inColor2) + abs(inColor3) +
36 abs(inColor4) + abs(inColor5) + abs(inColor6) + abs(inColor7);
38 color = clamp(color, vec4(0.0), vec4(1.0));
40 gl_Position = vec4(inPosition, 0.0, 1.0);
42 </script>
43 <script id="fshader" type="x-shader/x-fragment">
44 precision mediump float;
46 varying vec4 color;
48 void main()
50 if (color == vec4(0.0))
51 discard;
53 gl_FragColor = color;
55 </script>
57 <script>
58 description("Allocates a number of different sized buffers and checks that the buffers are cleared " +
59 "OR that the allocation results in gl.OUT_OF_MEMORY or context loss.");
60 var wtu = WebGLTestUtils;
62 // The shader processes eight vec4 attributes at once to reduce the amount of
63 // draw calls.
64 var numColorAttrs = 8;
66 // Process 64 squares at once to also reduce the amount of draw calls.
67 var vertices = [];
68 var w = 0.25;
69 for (var x = -1; x < 1; x += w) {
70 for (var y = -1; y < 1; y += w) {
71 vertices.push(x + w, y + w);
72 vertices.push(x, y + w);
73 vertices.push(x, y );
75 vertices.push(x + w, y + w);
76 vertices.push(x, y );
77 vertices.push(x + w, y );
80 var numVertices = (vertices.length / 2);
82 var gl;
83 var squareBuffer;
84 var error = 0;
85 var expectContextLost = false;
87 function initGLForBufferSizesTest() {
88 var canvas = document.createElement("canvas");
89 canvas.width = 40;
90 canvas.height = 40;
91 var parent = document.getElementById("canvasParent");
92 parent.innerHTML = '';
93 parent.appendChild(canvas);
94 gl = wtu.create3DContext(canvas);
95 var attribs = ["inPosition", "inColor0", "inColor1", "inColor2", "inColor3",
96 "inColor4", "inColor5", "inColor6", "inColor7"];
97 wtu.setupProgram(gl, ["vshader", "fshader"], attribs);
98 gl.enableVertexAttribArray(0);
99 for (var i = 0; i < numColorAttrs; i++) {
100 gl.enableVertexAttribArray(1 + i);
102 gl.disable(gl.DEPTH_TEST);
103 gl.disable(gl.BLEND);
105 squareBuffer = gl.createBuffer();
107 gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
108 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
111 function createBuffer(size, allowedToFail) {
112 var msg = "Calling bufferData with size=" + size;
113 var buffer = gl.createBuffer();
115 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
116 gl.bufferData(gl.ARRAY_BUFFER, size, gl.STATIC_DRAW);
118 error = gl.getError();
119 if (error !== gl.NO_ERROR) {
120 gl.deleteBuffer(buffer);
121 if (allowedToFail) {
122 if (error === gl.OUT_OF_MEMORY) {
123 testPassed(msg + " failed with gl.OUT_OF_MEMORY (this is allowed)");
124 return null;
125 } else if (error === gl.CONTEXT_LOST_WEBGL) {
126 testPassed(msg + " failed with gl.CONTEXT_LOST_WEBGL (this is allowed)");
127 return null;
130 testFailed(msg + " failed with error " + wtu.glEnumToString(gl, error));
131 return null;
134 testPassed(msg + " did not result in any errors");
135 var reportedSize = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE);
136 expectContextLost = false;
137 if (reportedSize === null) {
138 testPassed("Null size reported by gl, this should happen if the context is lost which is allowed.");
139 expectContextLost = true;
140 } else if (reportedSize !== size) {
141 if (size > Math.pow(2, 32)) {
142 testPassed("gl reported different size " + reportedSize + " for the buffer, but this is expected since " +
143 "the requested size was above what the return value of getBufferParameter can represent.");
144 } else {
145 testFailed("gl reported different size " + reportedSize + " for the buffer.");
147 } else {
148 testPassed("Size reported by gl was the same as the requested size.");
151 return buffer;
154 // Draw a square on the canvas using attributes from the clear buffer created with bufferData.
155 function drawWithBuffer(buffer, allowedToFail) {
156 gl.clearColor(0, 1, 0, 1);
157 gl.clear(gl.COLOR_BUFFER_BIT);
159 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
160 var size = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE);
161 // Each vec4 is 16 bytes
162 var increment = numVertices * numColorAttrs * 16;
163 for (var offset = 0; offset + increment <= size; offset += increment) {
164 gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
165 gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
167 for (var i = 0; i < numColorAttrs; i++) {
168 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
169 gl.vertexAttribPointer(1 + i, 4, gl.FLOAT, false, 0,
170 offset + increment * i / numColorAttrs);
172 gl.drawArrays(gl.TRIANGLES, 0, numVertices);
173 error = gl.getError();
175 if (error !== gl.NO_ERROR) {
176 if (allowedToFail) {
177 if (error === gl.OUT_OF_MEMORY) {
178 testPassed("drawArrays failed with gl.OUT_OF_MEMORY (this is allowed)");
179 return;
180 } else if (error === gl.CONTEXT_LOST_WEBGL) {
181 testPassed("drawArrays failed with gl.CONTEXT_LOST_WEBGL (this is allowed)");
182 return;
185 testFailed("drawArrays failed with error " + wtu.glEnumToString(gl, error));
186 return;
189 wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
193 // To be able to confirm the whole buffer has been cleared, the size needs to
194 // be divisible by the amount of vertices. Thus most sizes are multiples of 3.
195 var tests = [
196 // Reasonable sized buffers.
197 { size: 3 * 1024, allowedToFail: false, tryDrawing: true },
198 { size: 3 * 1024 * 1024, allowedToFail: false, tryDrawing: true },
199 { size: 3 * 1024 * 1024 * 16, allowedToFail: false, tryDrawing: true },
201 // Huge buffers, which are meant to test out of memory handling.
202 // Allowed failures are gl.OUT_OF_MEMORY or context loss.
203 // Succeeding in the allocations is allowed as well for forward compatibility.
205 // 1.5 GB allocation for stressing lower-end 32-bit systems.
206 // Allocation is likely to succeed on higher-end hardware.
207 { size: 3 * 1024 * 1024 * 512, allowedToFail: true, tryDrawing: true },
208 // A buffer that no implementation will be able to allocate for some time
209 // to come. To do this, we use half of the lower 43-bit half of a 44-bit
210 // memory address space, so that the size is still valid on current common
211 // 64-bit implementations, and also below 52-bit limit for exact conversion
212 // from float to long long in WebIDL (though 2^n should be safe anyway).
213 // The 4 TB size is large enough that even extrapolating the historical
214 // exponential growth trend of memory sizes, hardware in 2020's should
215 // still have some trouble actually doing the allocation.
216 { size: (1 << 12) * (1 << 30), allowedToFail: true, tryDrawing: false }
219 function finishBufferSizesTest() {
220 gl.deleteBuffer(squareBuffer);
221 finishTest();
224 var testIndex = -1;
225 function runNextTest() {
226 ++testIndex;
227 if (testIndex > 0 && tests[testIndex - 1].allowedToFail) {
228 if (gl.isContextLost() || error === gl.OUT_OF_MEMORY) {
229 initGLForBufferSizesTest();
230 } else if (expectContextLost) {
231 testFailed("Context was not lost after timeout even though gl.getBufferParameter returned null.");
234 var buffer = createBuffer(tests[testIndex].size, tests[testIndex].allowedToFail);
235 if (buffer) {
236 if (tests[testIndex].tryDrawing) {
237 drawWithBuffer(buffer, tests[testIndex].allowedToFail);
239 gl.deleteBuffer(buffer);
242 if (testIndex + 1 >= tests.length) {
243 finishBufferSizesTest();
244 } else {
245 if (tests[testIndex + 1].allowedToFail && !tests[testIndex].allowedToFail) {
246 if (!confirm("The following tests can cause unresponsiveness or instability. Press OK to continue.")) {
247 testFailed("Tests aborted");
248 return;
251 if (tests[testIndex].allowedToFail) {
252 // Give plenty of time for possible context loss
253 setTimeout(runNextTest(), 5000);
254 } else {
255 runNextTest();
260 initGLForBufferSizesTest();
261 runNextTest();
263 var successfullyParsed = true;
264 </script>
266 </body>
267 </html>