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
content / test / data / gpu / offscreencanvas_recovery_after_gpu_crash.html [blame]
<!DOCTYPE html>
<html>
<head>
<title>Recover OffscreenCanvas context after GPU crash</title>
<script id="worker" type="text/worker">
let restored = false;
let canvas, ctx;
function draw() {
ctx.reset();
if (restored) {
ctx.fillStyle = 'aqua';
} else {
ctx.fillStyle = 'fuchsia';
}
ctx.fillRect(0,0,300,300);
}
self.onmessage = msg => {
if (msg.data.operation === 'init') {
canvas = msg.data.canvas;
ctx = canvas.getContext('2d');
canvas.addEventListener('contextlost', evt => {
self.postMessage("context lost");
});
canvas.addEventListener('contextrestored', evt => {
restored = true;
self.postMessage('context restored');
});
draw();
self.postMessage('setup complete');
} else if(msg.data.operation === 'draw') {
draw();
} else {
self.postMessage("unexpected message");
}
}
</script>
<script>
// Test the recovery of an Offscreen Canvas from a GPU crash.
// Test will timeout if the context is not recovered.
function TestFailed(msg) {
console.log(msg);
window.domAutomationController.send('FAILED');
}
window.onload = () => {
const worker_blob = new Blob([document.getElementById('worker').textContent]);
const worker = new Worker(URL.createObjectURL(worker_blob));
let lost = false;
function drawInWorker(){
worker.postMessage({
operation: 'draw',
});
}
worker.onmessage = evt => {
if (evt.data == 'setup complete') {
// Send message repeatedly to worker to make simple draw calls.
var interval = window.setInterval(drawInWorker, 10);
// Send message that test is ready for GPU process crash.
window.domAutomationController.send('LOADED');
} else if (evt.data == 'context lost') {
lost = true;
} else if (evt.data == 'context restored') {
clearInterval(interval);
if (lost) {
window.domAutomationController.send('SUCCESS');
} else {
TestFailed('contextrestored event fired without contextlost.');
}
} else {
TestFailed('Unexpected message.');
}
}
let offscreen = document.getElementById("c").transferControlToOffscreen();
worker.postMessage({
operation: 'init',
canvas: offscreen,
}, [offscreen]);
}
</script>
</head>
<body>
<canvas id="c" width="300" height="300"></canvas>
</body>
</html>