summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html287
1 files changed, 287 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html
new file mode 100644
index 0000000000..6942e3d1ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html
@@ -0,0 +1,287 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<!--
+Copyright (c) 2019 The Khronos Group Inc.
+Use of this source code is governed by an MIT-style license that can be
+found in the LICENSE.txt file.
+-->
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../js/js-test-pre.js"></script>
+<script src="../../js/webgl-test-utils.js"></script>
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var canvas;
+var gl;
+var shouldGenerateGLError;
+var WEBGL_lose_context;
+var new_WEBGL_lose_context;
+var bufferObjects;
+var program;
+var texture;
+var texColor = [255, 10, 20, 255];
+var allowRestore;
+var contextLostEventFired;
+var contextRestoredEventFired;
+var OES_vertex_array_object;
+var old_OES_vertex_array_object;
+var vertexArrayObject;
+var OES_texture_float;
+var newExtension;
+
+function init()
+{
+ enableJSTestPreVerboseLogging();
+ description("Tests behavior under a restored context.");
+
+ shouldGenerateGLError = wtu.shouldGenerateGLError;
+ testLosingContext();
+}
+
+function setupTest()
+{
+ canvas = document.createElement("canvas");
+ canvas.width = 1;
+ canvas.height = 1;
+ gl = wtu.create3DContext(canvas);
+ WEBGL_lose_context = getExtensionAndAddProperty(gl, "WEBGL_lose_context");
+ if (!WEBGL_lose_context) {
+ debug("Could not find WEBGL_lose_context extension");
+ return false;
+ }
+
+ // Try to get a few extensions
+ OES_vertex_array_object = getExtensionAndAddProperty(gl, "OES_vertex_array_object");
+ OES_texture_float = getExtensionAndAddProperty(gl, "OES_texture_float");
+
+ return true;
+}
+
+function getExtensionAndAddProperty(gl, name) {
+ var ext = wtu.getExtensionWithKnownPrefixes(gl, name);
+ if (ext) {
+ ext.webglTestProperty = true;
+ }
+ return ext;
+}
+
+function reGetExtensionAndTestForProperty(gl, name, expectProperty) {
+ newExtension = wtu.getExtensionWithKnownPrefixes(gl, name);
+ // NOTE: while getting a extension after context lost/restored is allowed to fail
+ // for the purpose the conformance tests it is not.
+ //
+ // Hypothetically the user can switch GPUs live. For example on Windows, install 2 GPUs,
+ // then in the control panen enable 1, disable the others and visa versa. Since the GPUs
+ // have different capabilities one or the other may not support a particlar extension.
+ //
+ // But, for the purpose of the conformance tests the context is expected to restore
+ // on the same GPU and therefore the extensions that succeeded previously should
+ // succeed on restore.
+ shouldBeTrue("newExtension != null");
+ if (expectProperty) {
+ shouldBeTrue("newExtension.webglTestProperty === true");
+ } else {
+ shouldBeTrue("newExtension.webglTestProperty === undefined");
+ }
+ return newExtension;
+}
+
+function testLosingContext()
+{
+ if (!setupTest()) {
+ finishTest();
+ return;
+ }
+
+ debug("Test losing a context and inability to restore it.");
+
+ canvas.addEventListener("webglcontextlost", function(e) {
+ testLostContext(e);
+ // restore the context after this event has exited.
+ setTimeout(function() {
+ // we didn't call prevent default so we should not be able to restore the context
+ shouldGenerateGLError(gl, gl.INVALID_OPERATION, "WEBGL_lose_context.restoreContext()");
+ testLosingAndRestoringContext();
+ }, 0);
+ });
+ canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
+ allowRestore = false;
+ contextLostEventFired = false;
+ contextRestoredEventFired = false;
+
+ testOriginalContext();
+ WEBGL_lose_context.loseContext();
+ // The context should be lost immediately.
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ // gl methods should be no-ops
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+ // but the event should not have been fired.
+ shouldBeFalse("contextLostEventFired");
+}
+
+function testLosingAndRestoringContext()
+{
+ if (!setupTest())
+ finishTest();
+
+ debug("");
+ debug("Test losing and restoring a context.");
+
+ canvas.addEventListener("webglcontextlost", function(e) {
+ testLostContext(e);
+ // restore the context after this event has exited.
+ setTimeout(function() {
+ shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
+ // Calling restoreContext() twice should not cause error or crash
+ shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
+ // The context should still be lost. It will not get restored until the
+ // webglrestorecontext event is fired.
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ // gl methods should still be no-ops
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+ }, 0);
+ });
+ canvas.addEventListener("webglcontextrestored", function() {
+ testRestoredContext();
+ finishTest();
+ });
+ allowRestore = true;
+ contextLostEventFired = false;
+ contextRestoredEventFired = false;
+
+ testOriginalContext();
+ WEBGL_lose_context.loseContext();
+ // The context should be lost immediately.
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ // gl methods should be no-ops
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
+ // but the event should not have been fired.
+ shouldBeFalse("contextLostEventFired");
+}
+
+function testRendering()
+{
+ gl.clearColor(0, 0, 0, 255);
+ gl.colorMask(1, 1, 1, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ program = wtu.setupSimpleTextureProgram(gl);
+ bufferObjects = wtu.setupUnitQuad(gl);
+ texture = wtu.createColoredTexture(gl, canvas.width, canvas.height, texColor);
+
+ gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+
+ var compare = texColor.slice(0, 3);
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, compare, "shouldBe " + compare);
+
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+}
+
+function testOriginalContext()
+{
+ debug("Test valid context");
+ shouldBeFalse("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ testRendering();
+ debug("");
+}
+
+function testLostContext(e)
+{
+ debug("Test lost context");
+ shouldBeFalse("contextLostEventFired");
+ contextLostEventFired = true;
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ debug("");
+ if (allowRestore)
+ e.preventDefault();
+}
+
+function testShouldNotRestoreContext(e)
+{
+ testFailed("Should not restore the context unless preventDefault is called on the context lost event");
+ debug("");
+}
+
+function testResources(expected)
+{
+ var tests = [
+ "gl.bindTexture(gl.TEXTURE_2D, texture)",
+ "gl.useProgram(program)",
+ "gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0])",
+ ];
+
+ for (var i = 0; i < tests.length; ++i)
+ shouldGenerateGLError(gl, expected, tests[i]);
+}
+
+function testOESTextureFloat() {
+ if (OES_texture_float) {
+ // Extension must still be lost.
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
+ // Try re-enabling extension
+ OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false);
+ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
+ }
+}
+
+function testOESVertexArrayObject() {
+ if (OES_vertex_array_object) {
+ // Extension must still be lost.
+ shouldBeNull("OES_vertex_array_object.createVertexArrayOES()");
+ // Try re-enabling extension
+
+ old_OES_vertex_array_object = OES_vertex_array_object;
+ OES_vertex_array_object = reGetExtensionAndTestForProperty(gl, "OES_vertex_array_object", false);
+ shouldBeTrue("OES_vertex_array_object.createVertexArrayOES() != null");
+ shouldBeTrue("old_OES_vertex_array_object.createVertexArrayOES() == null");
+ }
+}
+
+function testExtensions() {
+ testOESTextureFloat();
+ testOESVertexArrayObject();
+ // Only the WEBGL_lose_context extension should be the same object after context lost.
+ new_WEBGL_lose_context = reGetExtensionAndTestForProperty(gl, "WEBGL_lose_context", true);
+}
+
+function testRestoredContext()
+{
+ debug("Test restored context");
+ shouldBeFalse("contextRestoredEventFired");
+ contextRestoredEventFired = true;
+ shouldBeFalse("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+
+ // Validate that using old resources fails.
+ testResources(gl.INVALID_OPERATION);
+
+ testRendering();
+
+ // Validate new resources created in testRendering().
+ testResources(gl.NO_ERROR);
+
+ testExtensions();
+
+ debug("");
+}
+
+
+</script>
+</head>
+<body onload="init()">
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>