8 ** Copyright (c) 2012 The Khronos Group Inc.
10 ** Permission is hereby granted, free of charge, to any person obtaining a
11 ** copy of this software and/or associated documentation files (the
12 ** "Materials"), to deal in the Materials without restriction, including
13 ** without limitation the rights to use, copy, modify, merge, publish,
14 ** distribute, sublicense, and/or sell copies of the Materials, and to
15 ** permit persons to whom the Materials are furnished to do so, subject to
16 ** the following conditions:
18 ** The above copyright notice and this permission notice shall be included
19 ** in all copies or substantial portions of the Materials.
21 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
31 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
32 <script src="../../resources/js-test-pre.js"></script>
33 <script src="../resources/webgl-test-utils.js"></script>
36 var wtu = WebGLTestUtils;
39 var shouldGenerateGLError;
40 var WEBGL_lose_context;
41 var new_WEBGL_lose_context;
45 var texColor = [255, 10, 20, 255];
47 var contextLostEventFired;
48 var contextRestoredEventFired;
49 var OES_vertex_array_object;
50 var old_OES_vertex_array_object;
51 var vertexArrayObject;
52 var OES_texture_float;
57 enableJSTestPreVerboseLogging();
58 description("Tests behavior under a restored context.");
60 shouldGenerateGLError = wtu.shouldGenerateGLError;
66 canvas = document.createElement("canvas");
69 gl = wtu.create3DContext(canvas);
70 WEBGL_lose_context = getExtensionAndAddProperty(gl, "WEBGL_lose_context");
71 if (!WEBGL_lose_context) {
72 debug("Could not find WEBGL_lose_context extension");
76 // Try to get a few extensions
77 OES_vertex_array_object = getExtensionAndAddProperty(gl, "OES_vertex_array_object");
78 OES_texture_float = getExtensionAndAddProperty(gl, "OES_texture_float");
83 function getExtensionAndAddProperty(gl, name) {
84 var ext = wtu.getExtensionWithKnownPrefixes(gl, name);
86 ext.webglTestProperty = true;
91 function reGetExtensionAndTestForProperty(gl, name, expectProperty) {
92 newExtension = wtu.getExtensionWithKnownPrefixes(gl, name);
93 // NOTE: while getting a extension after context lost/restored is allowed to fail
94 // for the purpose the conformance tests it is not.
96 // Hypothetically the user can switch GPUs live. For example on Windows, install 2 GPUs,
97 // then in the control panen enable 1, disable the others and visa versa. Since the GPUs
98 // have different capabilities one or the other may not support a particlar extension.
100 // But, for the purpose of the conformance tests the context is expected to restore
101 // on the same GPU and therefore the extensions that succeeded previously should
102 // succeed on restore.
103 shouldBeTrue("newExtension != null");
104 if (expectProperty) {
105 shouldBeTrue("newExtension.webglTestProperty === true");
107 shouldBeTrue("newExtension.webglTestProperty === undefined");
112 function testLosingContext()
119 debug("Test losing a context and inability to restore it.");
121 canvas.addEventListener("webglcontextlost", function(e) {
123 // restore the context after this event has exited.
124 setTimeout(function() {
125 // we didn't call prevent default so we should not be able to restore the context
126 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "WEBGL_lose_context.restoreContext()");
127 testLosingAndRestoringContext();
130 canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
131 allowRestore = false;
132 contextLostEventFired = false;
133 contextRestoredEventFired = false;
135 testOriginalContext();
136 WEBGL_lose_context.loseContext();
137 // The context should be lost immediately.
138 shouldBeTrue("gl.isContextLost()");
139 shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
140 shouldBe("gl.getError()", "gl.NO_ERROR");
141 // gl methods should be no-ops
142 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
143 // but the event should not have been fired.
144 shouldBeFalse("contextLostEventFired");
147 function testLosingAndRestoringContext()
153 debug("Test losing and restoring a context.");
155 canvas.addEventListener("webglcontextlost", function(e) {
157 // restore the context after this event has exited.
158 setTimeout(function() {
159 shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
160 // The context should still be lost. It will not get restored until the
161 // webglrestorecontext event is fired.
162 shouldBeTrue("gl.isContextLost()");
163 shouldBe("gl.getError()", "gl.NO_ERROR");
164 // gl methods should still be no-ops
165 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
168 canvas.addEventListener("webglcontextrestored", function() {
169 testRestoredContext();
173 contextLostEventFired = false;
174 contextRestoredEventFired = false;
176 testOriginalContext();
177 WEBGL_lose_context.loseContext();
178 // The context should be lost immediately.
179 shouldBeTrue("gl.isContextLost()");
180 shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
181 shouldBe("gl.getError()", "gl.NO_ERROR");
182 // gl methods should be no-ops
183 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
184 // but the event should not have been fired.
185 shouldBeFalse("contextLostEventFired");
188 function testRendering()
190 gl.clearColor(0, 0, 0, 255);
191 gl.colorMask(1, 1, 1, 0);
192 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
194 program = wtu.setupSimpleTextureProgram(gl);
195 bufferObjects = wtu.setupUnitQuad(gl);
196 texture = wtu.createColoredTexture(gl, canvas.width, canvas.height, texColor);
198 gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
199 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
201 var compare = texColor.slice(0, 3);
202 wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, compare, "shouldBe " + compare);
204 shouldBe("gl.getError()", "gl.NO_ERROR");
207 function testOriginalContext()
209 debug("Test valid context");
210 shouldBeFalse("gl.isContextLost()");
211 shouldBe("gl.getError()", "gl.NO_ERROR");
216 function testLostContext(e)
218 debug("Test lost context");
219 shouldBeFalse("contextLostEventFired");
220 contextLostEventFired = true;
221 shouldBeTrue("gl.isContextLost()");
222 shouldBe("gl.getError()", "gl.NO_ERROR");
228 function testShouldNotRestoreContext(e)
230 testFailed("Should not restore the context unless preventDefault is called on the context lost event");
234 function testResources(expected)
237 "gl.bindTexture(gl.TEXTURE_2D, texture)",
238 "gl.useProgram(program)",
239 "gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0])",
242 for (var i = 0; i < tests.length; ++i)
243 shouldGenerateGLError(gl, expected, tests[i]);
246 function testOESTextureFloat() {
247 if (OES_texture_float) {
248 // Extension must still be lost.
249 var tex = gl.createTexture();
250 gl.bindTexture(gl.TEXTURE_2D, tex);
251 shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
252 // Try re-enabling extension
253 OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false);
254 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
258 function testOESVertexArrayObject() {
259 if (OES_vertex_array_object) {
260 // Extension must still be lost.
261 shouldBeNull("OES_vertex_array_object.createVertexArrayOES()");
262 // Try re-enabling extension
264 old_OES_vertex_array_object = OES_vertex_array_object;
265 OES_vertex_array_object = reGetExtensionAndTestForProperty(gl, "OES_vertex_array_object", false);
266 shouldBeTrue("OES_vertex_array_object.createVertexArrayOES() != null");
267 shouldBeTrue("old_OES_vertex_array_object.createVertexArrayOES() == null");
271 function testExtensions() {
272 testOESTextureFloat();
273 testOESVertexArrayObject();
274 // Only the WEBGL_lose_context extension should be the same object after context lost.
275 new_WEBGL_lose_context = reGetExtensionAndTestForProperty(gl, "WEBGL_lose_context", true);
278 function testRestoredContext()
280 debug("Test restored context");
281 shouldBeFalse("contextRestoredEventFired");
282 contextRestoredEventFired = true;
283 shouldBeFalse("gl.isContextLost()");
284 shouldBe("gl.getError()", "gl.NO_ERROR");
286 // Validate that using old resources fails.
287 testResources(gl.INVALID_OPERATION);
291 // Validate new resources created in testRendering().
292 testResources(gl.NO_ERROR);
302 <body onload="init()">
303 <div id="description"></div>
304 <div id="console"></div>