blob: 410db377aaf1ed4dac3100e102824fa689517c7e [file] [edit]
<!DOCTYPE html>
<head>
<script src="../resources/js-test.js"></script>
<script src="../fast/canvas/webgl/resources/webgl-test.js"> </script>
<script src="../fast/canvas/webgl/resources/webgl-test-utils.js"> </script>
<script>
var wtu = WebGLTestUtils;
var gl;
var canvas;
window.jsTestIsAsync = true;
if (window.initNonKhronosFramework)
window.initNonKhronosFramework(false);
debug("Checks that failing to allocate the default framebuffer storage during a resize loses the context.");
debug("NOTE: This only passes in the test harness because it requires Internals.");
debug("");
function makeCanvas() {
let canvas = document.createElement("canvas");
canvas.width = 20;
canvas.height = 20;
return canvas;
}
async function webGLContextLostOrTimeout(canvas)
{
return new Promise(resolve => {
canvas.addEventListener("webglcontextlost", () => resolve(true));
setTimeout(() => resolve(false), 2000);
});
}
function releaseContext() {
canvas = null;
gl = null;
gc();
}
async function testAllocationFailure(contextType, event, attributes) {
debug("");
debug(`Test ${contextType} ${event} ${JSON.stringify(attributes)}.`);
releaseContext();
canvas = makeCanvas();
gl = canvas.getContext(contextType, attributes);
shouldBeTrue("!!gl");
shouldBe("gl.getError()", "gl.NO_ERROR");
let lost = webGLContextLostOrTimeout(canvas);
window.internals.simulateEventForWebGLContext(event, gl);
canvas.width = 30;
if (!await lost)
testFailed("webglcontextlost was not dispatched.");
shouldBeTrue("gl.isContextLost()");
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
shouldBe("gl.getError()", "gl.NO_ERROR");
}
async function testPendingErrorPreservedOverResize(contextType, attributes) {
debug("");
debug(`Test ${contextType} pending error is preserved over a successful resize ${JSON.stringify(attributes)}.`);
releaseContext();
canvas = makeCanvas();
gl = canvas.getContext(contextType, attributes);
shouldBeTrue("!!gl");
gl.bindBuffer(0x1234, null);
canvas.width = 30;
shouldBeFalse("gl.isContextLost()");
shouldBe("gl.getError()", "gl.INVALID_ENUM");
shouldBe("gl.getError()", "gl.NO_ERROR");
shouldBe("gl.drawingBufferWidth", "30");
gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
shouldBe("gl.getError()", "gl.NO_ERROR");
wtu.checkCanvasRect(gl, 0, 0, 30, 20, [0, 255, 0, 255]);
}
// Each entry selects which default framebuffer storage allocation is the first renderbuffer allocation
// done in the resize, i.e. the one RenderbufferAllocationFailure fails.
const renderbufferAllocationCases = [
{ antialias: true, depth: false, stencil: false }, // Multisampled color.
{ antialias: false, preserveDrawingBuffer: true, depth: false, stencil: false }, // Single-sampled color.
{ antialias: false, depth: true, stencil: false }, // Depth.
{ antialias: false, depth: false, stencil: true }, // Stencil.
{ antialias: false, depth: true, stencil: true }, // Depth-stencil.
];
async function runTest() {
if (!window.internals) {
testFailed("Test requires Internals.");
finishTest();
return;
}
for (const contextType of ["webgl", "webgl2"]) {
await testAllocationFailure(contextType, "DisplayBufferAllocationFailure", { antialias: false });
await testAllocationFailure(contextType, "DisplayBufferAllocationFailure", { antialias: true, depth: true, stencil: true });
for (const attributes of renderbufferAllocationCases)
await testAllocationFailure(contextType, "RenderbufferAllocationFailure", attributes);
await testPendingErrorPreservedOverResize(contextType, { antialias: false, depth: false, stencil: false });
await testPendingErrorPreservedOverResize(contextType, { antialias: true, depth: true, stencil: true });
}
releaseContext();
finishTest();
}
runTest();
var successfullyParsed = true;
</script>
<body>
</body>