diff options
Diffstat (limited to 'dom/canvas/test/test_accelerated_canvas_context_loss.html')
-rw-r--r-- | dom/canvas/test/test_accelerated_canvas_context_loss.html | 121 |
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> |