summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/test_accelerated_canvas_context_loss.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/test_accelerated_canvas_context_loss.html')
-rw-r--r--dom/canvas/test/test_accelerated_canvas_context_loss.html121
1 files changed, 121 insertions, 0 deletions
diff --git a/dom/canvas/test/test_accelerated_canvas_context_loss.html b/dom/canvas/test/test_accelerated_canvas_context_loss.html
new file mode 100644
index 0000000000..6172420bcb
--- /dev/null
+++ b/dom/canvas/test/test_accelerated_canvas_context_loss.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Check for contextlost/restored events after GPU process restart</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<canvas id="c" width="512" height="512"></canvas>
+
+<script type="application/javascript">
+
+function waitRAF() {
+ return new Promise((resolve, reject) => {
+ window.requestAnimationFrame(resolve);
+ });
+}
+
+async function restartGPUProcess() {
+ return await SpecialPowers.spawnChrome([], async () => {
+ const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
+
+ if (gfxInfo.usingGPUProcess) {
+ const { TestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TestUtils.sys.mjs"
+ );
+ let promise = TestUtils.topicObserved("compositor-reinitialized");
+
+ const remoteCanvas = gfxInfo.usingRemoteCanvas;
+ const acceleratedCanvas = gfxInfo.usingAcceleratedCanvas;
+ ok(true, "Restarting GPU process, remote canvas " + remoteCanvas + ", accelerated canvas " + acceleratedCanvas);
+
+ gfxInfo.killGPUProcessForTests();
+ await promise;
+
+ return remoteCanvas || acceleratedCanvas;
+ }
+
+ ok(true, "Not using GPU process");
+ return false;
+ });
+}
+
+const canvas = document.getElementById("c");
+const context = canvas.getContext("2d");
+
+let restoredPromiseResolve;
+let restoredPromiseReject;
+
+const restoredPromise = new Promise((resolve, reject) => {
+ restoredPromiseResolve = resolve;
+ restoredPromiseReject = reject;
+});
+
+let countLostEvents = 0;
+let countRestoredEvents = 0;
+
+function onContextLost() {
+ ok(context.isContextLost(), "Canvas context should be lost during contextlost event");
+ countLostEvents += 1;
+}
+
+function onContextRestored() {
+ ok(!context.isContextLost(), "Canvas context should not be lost during contextrestored event");
+ countRestoredEvents += 1;
+
+ restoredPromiseResolve(true);
+}
+
+function waitContextRestored() {
+ let timeoutId = window.setTimeout(restoredPromiseReject, 5000);
+ return restoredPromise.then(() => {
+ window.clearTimeout(timeoutId);
+ });
+}
+
+async function start() {
+ try {
+ canvas.addEventListener("contextlost", onContextLost);
+ canvas.addEventListener("contextrestored", onContextRestored);
+
+ ok(!context.isContextLost(), "Canvas context should not be lost before initial fill");
+
+ context.fillStyle = 'red';
+ context.fill();
+ await waitRAF();
+
+ ok(!context.isContextLost(), "Canvas context should not be lost after initial fill");
+
+ const restarted = await restartGPUProcess();
+ const expectedEvents = restarted ? 1 : 0;
+
+ if (expectedEvents) {
+ await waitContextRestored();
+ }
+ await waitRAF();
+
+ is(countLostEvents, expectedEvents, "Should have fired " + expectedEvents + " contextlost events");
+ is(countRestoredEvents, expectedEvents, "Should have fired " + expectedEvents + " contextrestored events");
+ ok(!context.isContextLost(), "Canvas context should not be lost after restoration");
+
+ context.fillStyle = 'green';
+ context.fill();
+ await waitRAF();
+
+ ok(!context.isContextLost(), "Canvas context should not be lost at completion");
+ } catch (err) {
+ ok(false, "Caught exception " + err);
+ } finally {
+ SimpleTest.finish();
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("Wait for failure condition");
+start();
+
+</script>
+</body>
+</html>