Source code
Revision control
Copy as Markdown
Other Tools
<!--
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">
<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>
<script id="vshader" type="x-shader/x-vertex">
uniform mat4 transformMatrix;
uniform vec3 positionOffset;
attribute vec2 aPosition;
void main() {
gl_Position = transformMatrix * vec4(aPosition, 0.0, 1.0) + vec4(positionOffset, 0.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
</script>
<div id="description"></div>
<canvas id="canvas" width="256" height="256"></canvas>
<div id="console"></div>
<script>
"use strict";
enableJSTestPreVerboseLogging();
description("Test many draw calls and uniform updates per frame");
debug('Regression test for Chromium <a href="http://crbug.com/320724">Issue 320724</a> and <a href="http://crbug.com/322726">Issue 322726</a>');
debug('');
var contextWasLost = false;
var wtu = WebGLTestUtils;
var canvas = document.getElementById('canvas');
var gl = wtu.create3DContext(canvas);
canvas.addEventListener('webglcontextlost', function(event) { contextWasLost = true; }, false);
var program = wtu.setupProgram(gl, ["vshader", "fshader"], [ "aPosition" ]);
if (!program) {
testFailed("failed to create test program");
}
gl.useProgram(program);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.enableVertexAttribArray(0);
// Initialize vertices
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0,
-1.0, 1.0,
-1.0, -1.0,
1.0, -1.0 ]), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.clearColor(0.3, 0.3, 0.3, 1.0);
// Initialize uniforms
var transformLoc = gl.getUniformLocation(program, 'transformMatrix');
var offsetLoc = gl.getUniformLocation(program, 'positionOffset');
// This many draw calls appear to be necessary to trigger the original bug reliably.
var tilesPerSide = 100;
var numDrawsThisFrame = 0;
var doNextDraw = function() {
// Sometimes, the original bug can't be caught cooperatively, and it
// causes the entire tab to hang irrevocably.
if (contextWasLost) {
testFailed("WebGL context was lost while running the test");
finishTest();
return;
}
var totalDraws = tilesPerSide * tilesPerSide;
if (numDrawsThisFrame >= totalDraws) {
testPassed("All draw calls completed successfully");
finishTest();
return;
}
numDrawsThisFrame += tilesPerSide;
gl.clear(gl.COLOR_BUFFER_BIT);
var transformMatrix = new Float32Array(16);
transformMatrix[15] = 1.0;
var scaleFactor = 1.0 / tilesPerSide;
transformMatrix[0] = scaleFactor;
transformMatrix[5] = scaleFactor;
transformMatrix[10] = scaleFactor;
var offset = new Float32Array(3);
var drawsDoneThisFrame = 0;
for (var yy = 0; yy < tilesPerSide; ++yy) {
for (var xx = 0; xx < tilesPerSide; ++xx) {
if (drawsDoneThisFrame >= numDrawsThisFrame)
break;
gl.uniformMatrix4fv(transformLoc, false, transformMatrix);
offset[0] = 2.0 * ((0.5 + xx) / tilesPerSide) - 1.0;
offset[1] = 2.0 * ((0.5 + yy) / tilesPerSide) - 1.0;
gl.uniform3f(offsetLoc, offset[0], offset[1], offset[2]);
gl.drawArrays(gl.TRIANGLES, 0, 6);
++drawsDoneThisFrame;
}
if (drawsDoneThisFrame >= numDrawsThisFrame)
break;
}
var iterations = numDrawsThisFrame / tilesPerSide;
if (iterations % 10 === 0) {
// Needed to avoid test timeout within the harness on some slower platforms
testPassed("Completed " + iterations + " iterations");
}
wtu.requestAnimFrame(doNextDraw);
}
wtu.requestAnimFrame(doNextDraw);
var successfullyParsed = true;
</script>
</body>
</html>