blob: 9cbd42d853308b9fefb9fded3a5eff23522990ba [file] [edit]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="resources/webgl_test_files/resources/js-test-style.css"/>
<script src="resources/webgl_test_files/js/js-test-pre.js"></script>
<script src="resources/webgl_test_files/js/webgl-test-utils.js"></script>
</head>
<body onload="test()">
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("Test that WEBGL_lose_context functions do not crash after context has been lost.");
var wtu = WebGLTestUtils;
var gl;
var canvas;
async function waitForWebGLContextLost(canvas)
{
return new Promise((resolve, reject) => {
setTimeout(reject, 2000);
canvas.addEventListener("webglcontextlost", resolve, { once: true });
});
}
function testDescription(subcase) {
return Object.keys(subcase).map((k) => `${k}: ${typeof subcase[k] === "function" ? subcase[k].name : subcase[k]}`).join(", ");
}
function createCanvas(subcase)
{
if (subcase.canvasType == "OffscreenCanvas")
return new OffscreenCanvas(1, 1);
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
return canvas;
}
async function runTest(subcase)
{
debug(`Running test: ${testDescription(subcase)}`);
canvas = createCanvas(subcase);
gl = canvas.getContext(subcase.contextType);
const WEBGL_lose_context = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_lose_context");
if (!WEBGL_lose_context) {
debug("Could not find WEBGL_lose_context extension");
return false;
}
const webglcontextlost = waitForWebGLContextLost(canvas);
if (subcase.loseMethod == "loseContext")
WEBGL_lose_context.loseContext();
else if (subcase.loseMethod == "gpuStatusFailure") {
internals.simulateEventForWebGLContext("GPUStatusFailure", gl);
gl.clear(gl.COLOR_BUFFER_BIT);
} else if (subcase.loseMethod == "manyContexts") {
// This causes the older contexts to be lost, including the first one we created
// for testing.
let contexts = [];
for (let i = 0; i < 50; ++i)
contexts.push(createCanvas(subcase).getContext(subcase.contextType));
}
try {
await webglcontextlost;
testPassed("Got webglcontextlost.");
} catch (e) {
testFailed("Timed out waiting webglcontextlost.");
}
shouldBeTrue("gl.isContextLost()");
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
shouldBe("gl.getError()", "gl.NO_ERROR");
if (subcase.testedMethod == "loseContext")
WEBGL_lose_context.loseContext();
else if (subcase.testedMethod == "restoreContext")
WEBGL_lose_context.restoreContext();
else if (subcase.testedMethod == "resize")
canvas.width = canvas.width + 7;
else if (subcase.testedMethod == "transferToImageBitmap") {
shouldThrow("canvas.transferToImageBitmap()");
}
testPassed(`Did not crash on tested method ${subcase.testedMethod}.`);
}
const canvasTypes = ["OffscreenCanvas", "Canvas"];
const contextTypes = ["webgl", "webgl2"];
const loseMethods = ["loseContext", "manyContexts"];
if (window.internals)
loseMethods.push("gpuStatusFailure");
const testedMethods = ["loseContext", "restoreContext", "resize", "transferToImageBitmap"];
const subcases = [];
for (const canvasType of canvasTypes) {
for (const contextType of contextTypes) {
for (const loseMethod of loseMethods) {
for (const testedMethod of testedMethods) {
if (testedMethod == "transferToImageBitmap" && canvasType != "OffscreenCanvas")
continue;
subcases.push({canvasType, contextType, loseMethod, testedMethod});
}
}
}
}
async function test()
{
for (let subcase of subcases)
await runTest(subcase);
finishTest();
}
</script>
</body>
</html>