many-draw-calls.html (3964B)
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 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 12 <script src="../../js/js-test-pre.js"></script> 13 <script src="../../js/webgl-test-utils.js"></script> 14 </head> 15 <body> 16 <script id="vshader" type="x-shader/x-vertex"> 17 uniform mat4 transformMatrix; 18 uniform vec3 positionOffset; 19 attribute vec2 aPosition; 20 void main() { 21 gl_Position = transformMatrix * vec4(aPosition, 0.0, 1.0) + vec4(positionOffset, 0.0); 22 } 23 </script> 24 <script id="fshader" type="x-shader/x-fragment"> 25 void main() { 26 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 27 } 28 </script> 29 <div id="description"></div> 30 <canvas id="canvas" width="256" height="256"></canvas> 31 <div id="console"></div> 32 <script> 33 "use strict"; 34 enableJSTestPreVerboseLogging(); 35 description("Test many draw calls and uniform updates per frame"); 36 37 debug('Regression test for Chromium <a href="http://crbug.com/320724">Issue 320724</a> and <a href="http://crbug.com/322726">Issue 322726</a>'); 38 debug(''); 39 40 var contextWasLost = false; 41 42 var wtu = WebGLTestUtils; 43 var canvas = document.getElementById('canvas'); 44 var gl = wtu.create3DContext(canvas); 45 canvas.addEventListener('webglcontextlost', function(event) { contextWasLost = true; }, false); 46 var program = wtu.setupProgram(gl, ["vshader", "fshader"], [ "aPosition" ]); 47 if (!program) { 48 testFailed("failed to create test program"); 49 } 50 51 gl.useProgram(program); 52 var vertexObject = gl.createBuffer(); 53 gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); 54 gl.enableVertexAttribArray(0); 55 56 // Initialize vertices 57 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 58 -1.0, 1.0, 59 1.0, -1.0, 60 1.0, 1.0, 61 -1.0, 1.0, 62 -1.0, -1.0, 63 1.0, -1.0 ]), gl.STATIC_DRAW); 64 gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); 65 66 gl.clearColor(0.3, 0.3, 0.3, 1.0); 67 68 // Initialize uniforms 69 var transformLoc = gl.getUniformLocation(program, 'transformMatrix'); 70 var offsetLoc = gl.getUniformLocation(program, 'positionOffset'); 71 72 // This many draw calls appear to be necessary to trigger the original bug reliably. 73 var tilesPerSide = 100; 74 var numDrawsThisFrame = 0; 75 76 var doNextDraw = function() { 77 // Sometimes, the original bug can't be caught cooperatively, and it 78 // causes the entire tab to hang irrevocably. 79 if (contextWasLost) { 80 testFailed("WebGL context was lost while running the test"); 81 finishTest(); 82 return; 83 } 84 85 var totalDraws = tilesPerSide * tilesPerSide; 86 if (numDrawsThisFrame >= totalDraws) { 87 testPassed("All draw calls completed successfully"); 88 finishTest(); 89 return; 90 } 91 92 numDrawsThisFrame += tilesPerSide; 93 94 gl.clear(gl.COLOR_BUFFER_BIT); 95 96 var transformMatrix = new Float32Array(16); 97 transformMatrix[15] = 1.0; 98 var scaleFactor = 1.0 / tilesPerSide; 99 transformMatrix[0] = scaleFactor; 100 transformMatrix[5] = scaleFactor; 101 transformMatrix[10] = scaleFactor; 102 103 var offset = new Float32Array(3); 104 105 var drawsDoneThisFrame = 0; 106 for (var yy = 0; yy < tilesPerSide; ++yy) { 107 for (var xx = 0; xx < tilesPerSide; ++xx) { 108 if (drawsDoneThisFrame >= numDrawsThisFrame) 109 break; 110 111 gl.uniformMatrix4fv(transformLoc, false, transformMatrix); 112 113 offset[0] = 2.0 * ((0.5 + xx) / tilesPerSide) - 1.0; 114 offset[1] = 2.0 * ((0.5 + yy) / tilesPerSide) - 1.0; 115 gl.uniform3f(offsetLoc, offset[0], offset[1], offset[2]); 116 117 gl.drawArrays(gl.TRIANGLES, 0, 6); 118 ++drawsDoneThisFrame; 119 } 120 121 if (drawsDoneThisFrame >= numDrawsThisFrame) 122 break; 123 } 124 125 var iterations = numDrawsThisFrame / tilesPerSide; 126 if (iterations % 10 === 0) { 127 // Needed to avoid test timeout within the harness on some slower platforms 128 testPassed("Completed " + iterations + " iterations"); 129 } 130 131 wtu.requestAnimFrame(doNextDraw); 132 } 133 134 wtu.requestAnimFrame(doNextDraw); 135 var successfullyParsed = true; 136 </script> 137 </body> 138 </html>