summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html268
1 files changed, 268 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html b/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html
new file mode 100644
index 0000000000..736c135b7a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html
@@ -0,0 +1,268 @@
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Buffer allocation test</title>
+<link rel="stylesheet" href="../resources/js-test-style.css"/>
+<script src="../js/js-test-pre.js"></script>
+<script src="../js/webgl-test-utils.js"> </script>
+</head>
+<body>
+<div id="canvasParent"></div>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec2 inPosition;
+attribute vec4 inColor0;
+attribute vec4 inColor1;
+attribute vec4 inColor2;
+attribute vec4 inColor3;
+attribute vec4 inColor4;
+attribute vec4 inColor5;
+attribute vec4 inColor6;
+attribute vec4 inColor7;
+
+varying vec4 color;
+
+void main()
+{
+ color = abs(inColor0) + abs(inColor1) + abs(inColor2) + abs(inColor3) +
+ abs(inColor4) + abs(inColor5) + abs(inColor6) + abs(inColor7);
+
+ color = clamp(color, vec4(0.0), vec4(1.0));
+
+ gl_Position = vec4(inPosition, 0.0, 1.0);
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+varying vec4 color;
+
+void main()
+{
+ if (color == vec4(0.0))
+ discard;
+
+ gl_FragColor = color;
+}
+</script>
+
+<script>
+description("Allocates a number of different sized buffers and checks that the buffers are cleared " +
+ "OR that the allocation results in gl.OUT_OF_MEMORY or context loss.");
+var wtu = WebGLTestUtils;
+
+// The shader processes eight vec4 attributes at once to reduce the amount of
+// draw calls.
+var numColorAttrs = 8;
+
+// Process 64 squares at once to also reduce the amount of draw calls.
+var vertices = [];
+var w = 0.25;
+for (var x = -1; x < 1; x += w) {
+ for (var y = -1; y < 1; y += w) {
+ vertices.push(x + w, y + w);
+ vertices.push(x, y + w);
+ vertices.push(x, y );
+
+ vertices.push(x + w, y + w);
+ vertices.push(x, y );
+ vertices.push(x + w, y );
+ }
+}
+var numVertices = (vertices.length / 2);
+
+var gl;
+var squareBuffer;
+var error = 0;
+var expectContextLost = false;
+
+function initGLForBufferSizesTest() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 40;
+ canvas.height = 40;
+ var parent = document.getElementById("canvasParent");
+ parent.innerHTML = '';
+ parent.appendChild(canvas);
+ gl = wtu.create3DContext(canvas);
+ var attribs = ["inPosition", "inColor0", "inColor1", "inColor2", "inColor3",
+ "inColor4", "inColor5", "inColor6", "inColor7"];
+ wtu.setupProgram(gl, ["vshader", "fshader"], attribs);
+ gl.enableVertexAttribArray(0);
+ for (var i = 0; i < numColorAttrs; i++) {
+ gl.enableVertexAttribArray(1 + i);
+ }
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ squareBuffer = gl.createBuffer();
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+}
+
+function createBuffer(size, allowedToFail) {
+ var msg = "Calling bufferData with size=" + size;
+ var buffer = gl.createBuffer();
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, size, gl.STATIC_DRAW);
+
+ error = gl.getError();
+ if (error !== gl.NO_ERROR) {
+ gl.deleteBuffer(buffer);
+ if (allowedToFail) {
+ if (error === gl.OUT_OF_MEMORY) {
+ testPassed(msg + " failed with gl.OUT_OF_MEMORY (this is allowed)");
+ return null;
+ } else if (error === gl.CONTEXT_LOST_WEBGL) {
+ testPassed(msg + " failed with gl.CONTEXT_LOST_WEBGL (this is allowed)");
+ return null;
+ }
+ }
+ testFailed(msg + " failed with error " + wtu.glEnumToString(gl, error));
+ return null;
+ }
+
+ testPassed(msg + " did not result in any errors");
+ var reportedSize = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE);
+ expectContextLost = false;
+ if (reportedSize === null) {
+ testPassed("Null size reported by gl, this should happen if the context is lost which is allowed.");
+ expectContextLost = true;
+ } else if (reportedSize !== size) {
+ if (size > Math.pow(2, 32)) {
+ testPassed("gl reported different size " + reportedSize + " for the buffer, but this is expected since " +
+ "the requested size was above what the return value of getBufferParameter can represent.");
+ } else {
+ testFailed("gl reported different size " + reportedSize + " for the buffer.");
+ }
+ } else {
+ testPassed("Size reported by gl was the same as the requested size.");
+ }
+
+ return buffer;
+}
+
+// Draw a square on the canvas using attributes from the clear buffer created with bufferData.
+function drawWithBuffer(buffer, allowedToFail) {
+ gl.clearColor(0, 1, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ var size = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE);
+ // Each vec4 is 16 bytes
+ var increment = numVertices * numColorAttrs * 16;
+ for (var offset = 0; offset + increment <= size; offset += increment) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, squareBuffer);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+
+ for (var i = 0; i < numColorAttrs; i++) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.vertexAttribPointer(1 + i, 4, gl.FLOAT, false, 0,
+ offset + increment * i / numColorAttrs);
+ }
+ gl.drawArrays(gl.TRIANGLES, 0, numVertices);
+ error = gl.getError();
+
+ if (error !== gl.NO_ERROR) {
+ if (allowedToFail) {
+ if (error === gl.OUT_OF_MEMORY) {
+ testPassed("drawArrays failed with gl.OUT_OF_MEMORY (this is allowed)");
+ return;
+ } else if (error === gl.CONTEXT_LOST_WEBGL) {
+ testPassed("drawArrays failed with gl.CONTEXT_LOST_WEBGL (this is allowed)");
+ return;
+ }
+ }
+ testFailed("drawArrays failed with error " + wtu.glEnumToString(gl, error));
+ return;
+ }
+ }
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+
+// To be able to confirm the whole buffer has been cleared, the size needs to
+// be divisible by the amount of vertices. Thus most sizes are multiples of 3.
+var tests = [
+ // Reasonable sized buffers.
+ { size: 3 * 1024, allowedToFail: false, tryDrawing: true },
+ { size: 3 * 1024 * 1024, allowedToFail: false, tryDrawing: true },
+ { size: 3 * 1024 * 1024 * 16, allowedToFail: false, tryDrawing: true },
+
+ // Huge buffers, which are meant to test out of memory handling.
+ // Allowed failures are gl.OUT_OF_MEMORY or context loss.
+ // Succeeding in the allocations is allowed as well for forward compatibility.
+
+ // 1.5 GB allocation for stressing lower-end 32-bit systems.
+ // Allocation is likely to succeed on higher-end hardware.
+ { size: 3 * 1024 * 1024 * 512, allowedToFail: true, tryDrawing: true },
+ // A buffer that no implementation will be able to allocate for some time
+ // to come. To do this, we use half of the lower 43-bit half of a 44-bit
+ // memory address space, so that the size is still valid on current common
+ // 64-bit implementations, and also below 52-bit limit for exact conversion
+ // from float to long long in WebIDL (though 2^n should be safe anyway).
+ // The 4 TB size is large enough that even extrapolating the historical
+ // exponential growth trend of memory sizes, hardware in 2020's should
+ // still have some trouble actually doing the allocation.
+ { size: (1 << 12) * (1 << 30), allowedToFail: true, tryDrawing: false }
+];
+
+function finishBufferSizesTest() {
+ gl.deleteBuffer(squareBuffer);
+ finishTest();
+}
+
+var testIndex = -1;
+function runNextTest() {
+ ++testIndex;
+ if (testIndex > 0 && tests[testIndex - 1].allowedToFail) {
+ if (gl.isContextLost() || error === gl.OUT_OF_MEMORY) {
+ initGLForBufferSizesTest();
+ } else if (expectContextLost) {
+ testFailed("Context was not lost after timeout even though gl.getBufferParameter returned null.");
+ }
+ }
+ var buffer = createBuffer(tests[testIndex].size, tests[testIndex].allowedToFail);
+ if (buffer) {
+ if (tests[testIndex].tryDrawing) {
+ drawWithBuffer(buffer, tests[testIndex].allowedToFail);
+ }
+ gl.deleteBuffer(buffer);
+ }
+
+ if (testIndex + 1 >= tests.length) {
+ finishBufferSizesTest();
+ } else {
+ if (tests[testIndex + 1].allowedToFail && !tests[testIndex].allowedToFail) {
+ if (!confirm("The following tests can cause unresponsiveness or instability. Press OK to continue.")) {
+ testFailed("Tests aborted");
+ return;
+ }
+ }
+ if (tests[testIndex].allowedToFail) {
+ // Give plenty of time for possible context loss
+ setTimeout(runNextTest(), 5000);
+ } else {
+ runNextTest();
+ }
+ }
+};
+
+initGLForBufferSizesTest();
+runNextTest();
+
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
+