summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/rendering/many-draw-calls.html
blob: 2c0a2232cea28a943556dfdeaabe98cc3f9693b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<!--
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>