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
139
140
content / test / data / gpu / webgl-overly-large-uniform.html [blame]
<html>
<head>
<script type="x-shader/x-vertex" id="vertex">
#version 100
uniform mat4 overflow;
void main() {
gl_Position = overflow * vec4(0.11, 0.22, 0.33, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fragment">
#version 100
void main() {
gl_FragColor = vec4(0.11, 0.22, 0.33, 1.0);
}
</script>
<script type="text/javascript">
let canvas;
let w, h;
let gl;
let timeout;
function send(result, message) {
if (window.domAutomationController)
window.domAutomationController.send(result);
if (message)
console.log(message);
}
function onContextLost(e) {
e.preventDefault();
clearTimeout(timeout);
// This is the last test in this file.
send("SUCCESS");
}
function onContextRestored() {
// Could extend this test to cover context restoration, but ignore
// this for now.
}
function timedOut() {
send("FAILURE", "Timed out waiting for context lost event");
}
function onLoad() {
send("LOADED");
canvas = document.getElementById("canvas1");
w = canvas.width;
h = canvas.height;
if (!canvas)
return;
canvas.addEventListener("webglcontextlost", onContextLost, false);
canvas.addEventListener("webglcontextrestored", onContextRestored, false);
gl = canvas.getContext("webgl");
if (!gl) {
send("FAILURE", "Couldn't get WebGL context");
return;
}
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.querySelector("#vertex").innerHTML);
gl.compileShader(vertexShader);
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.querySelector("#fragment").innerHTML);
gl.compileShader(fragmentShader);
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
overflow = gl.getUniformLocation(program, "overflow");
gl.useProgram(program);
// Make the memory pool, if possible:
// ::partition_alloc::internal::MaxDirectMapped.
// = 2 GB - 2 MB.
// 64KB Wasm page size)
//
// If allocation fails (for example, on 32-bit Android), fall back
// to 128 MB, and skip the portion of the test which tests the
// generation of INVALID_VALUE.
let gotLargeAllocation = false;
let memory;
try {
memory = new WebAssembly.Memory({initial: 32736});
gotLargeAllocation = true;
} catch (e) {
// Must be on a system that can't allocate that much memory. Try
// again with a smaller reservation.
try {
memory = new WebAssembly.Memory({initial: 2048});
} catch (e) {
// Unexpected. Fail verbosely.
send("FAILURE", "Failed to allocate even the smaller Wasm memory");
return;
}
}
if (gotLargeAllocation) {
// Feeding in all but a few bytes of that memory pool should cause
// GL_INVALID_VALUE to be generated as an implementation detail; this can not
// be guaranteed by the WebGL conformance tests. Note: this behavior could be
// changed to instead force a lost context if desired, per below.
const fewBytes = 8;
let array = new Int32Array(memory.buffer, fewBytes);
gl.uniform1iv(overflow, array);
let err = gl.getError();
console.log("GL error after very large uniform1iv call: " + err);
if (err != gl.INVALID_VALUE) {
send("FAILURE", "Expected gl.INVALID_VALUE, got " + err);
return;
}
}
// Feeding in significantly less of that memory pool (in this case, 64K less)
// should cause a lost context as an implementation detail; this can not be
// guaranteed by the WebGL conformance tests.
const moreBytes = 64 * 1024;
array = new Int32Array(memory.buffer, moreBytes);
gl.uniform1iv(overflow, array);
err = gl.getError();
console.log("GL error after slightly less large uniform1iv call: " + err);
// Delivery of context loss will race with execution here.
// If it hasn't been delivered within 5 seconds, fail the test.
timeout = setTimeout(timedOut, 5000);
}
</script>
</head>
<body onload="onLoad()">
<canvas id="canvas1" width="64px" height="64px">
</canvas>
</body>
</html>