|
1 <!DOCTYPE html> |
|
2 <html> |
|
3 <head> |
|
4 <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
|
5 <script src="../../resources/js-test-pre.js"></script> |
|
6 <script src="../resources/webgl-test.js"></script> |
|
7 <script src="../resources/webgl-test-utils.js"></script> |
|
8 <script> |
|
9 var wtu = WebGLTestUtils; |
|
10 var canvas; |
|
11 var gl; |
|
12 var shouldGenerateGLError; |
|
13 var extensionNames = [ |
|
14 "WEBKIT_WEBGL_lose_context", |
|
15 "MOZ_WEBGL_lose_context", |
|
16 ]; |
|
17 var extension; |
|
18 var bufferObjects; |
|
19 var program; |
|
20 var texture; |
|
21 var texColor = [255, 10, 20, 255]; |
|
22 var allowRestore; |
|
23 var contextLostEventFired; |
|
24 var contextRestoredEventFired; |
|
25 |
|
26 function init() |
|
27 { |
|
28 if (window.initNonKhronosFramework) { |
|
29 window.initNonKhronosFramework(true); |
|
30 } |
|
31 |
|
32 description("Tests behavior under a restored context."); |
|
33 |
|
34 shouldGenerateGLError = wtu.shouldGenerateGLError; |
|
35 testLosingContext(); |
|
36 } |
|
37 |
|
38 function setupTest() |
|
39 { |
|
40 canvas = document.createElement("canvas"); |
|
41 canvas.width = 1; |
|
42 canvas.height = 1; |
|
43 gl = wtu.create3DContext(canvas); |
|
44 for (var ii = 0; ii < extensionNames.length; ++ii) { |
|
45 extension = gl.getExtension(extensionNames[ii]); |
|
46 if (extension) |
|
47 break; |
|
48 } |
|
49 if (!extension) { |
|
50 debug("Could not find lose_context extension under the following names: " + extensionNames.join(" ")); |
|
51 return false; |
|
52 } |
|
53 return true; |
|
54 } |
|
55 |
|
56 function testLosingContext() |
|
57 { |
|
58 if (!setupTest()) |
|
59 finishTest(); |
|
60 |
|
61 debug("Test losing a context and inability to restore it."); |
|
62 |
|
63 canvas.addEventListener("webglcontextlost", function(e) { |
|
64 testLostContext(e); |
|
65 // restore the context after this event has exited. |
|
66 setTimeout(function() { |
|
67 // we didn't call prevent default so we should not be able to restore the context |
|
68 shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()"); |
|
69 testLosingAndRestoringContext(); |
|
70 }, 0); |
|
71 }); |
|
72 canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext); |
|
73 allowRestore = false; |
|
74 contextLostEventFired = false; |
|
75 contextRestoredEventFired = false; |
|
76 |
|
77 testOriginalContext(); |
|
78 extension.loseContext(); |
|
79 // The context should be lost immediately. |
|
80 shouldBeTrue("gl.isContextLost()"); |
|
81 shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL"); |
|
82 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
83 // gl methods should be no-ops |
|
84 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); |
|
85 // but the event should not have been fired. |
|
86 shouldBeFalse("contextLostEventFired"); |
|
87 } |
|
88 |
|
89 function testLosingAndRestoringContext() |
|
90 { |
|
91 if (!setupTest()) |
|
92 finishTest(); |
|
93 |
|
94 debug(""); |
|
95 debug("Test losing and restoring a context."); |
|
96 |
|
97 canvas.addEventListener("webglcontextlost", function(e) { |
|
98 testLostContext(e); |
|
99 // restore the context after this event has exited. |
|
100 setTimeout(function() { |
|
101 shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()"); |
|
102 // The context should still be lost. It will not get restored until the |
|
103 // webglrestorecontext event is fired. |
|
104 shouldBeTrue("gl.isContextLost()"); |
|
105 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
106 // gl methods should still be no-ops |
|
107 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); |
|
108 }, 0); |
|
109 }); |
|
110 canvas.addEventListener("webglcontextrestored", function() { |
|
111 testRestoredContext(); |
|
112 finishTest(); |
|
113 }); |
|
114 allowRestore = true; |
|
115 contextLostEventFired = false; |
|
116 contextRestoredEventFired = false; |
|
117 |
|
118 testOriginalContext(); |
|
119 extension.loseContext(); |
|
120 // The context should be lost immediately. |
|
121 shouldBeTrue("gl.isContextLost()"); |
|
122 shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL"); |
|
123 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
124 // gl methods should be no-ops |
|
125 shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)"); |
|
126 // but the event should not have been fired. |
|
127 shouldBeFalse("contextLostEventFired"); |
|
128 } |
|
129 |
|
130 function testRendering() |
|
131 { |
|
132 gl.clearColor(0, 0, 0, 255); |
|
133 gl.colorMask(1, 1, 1, 0); |
|
134 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
|
135 |
|
136 program = wtu.setupSimpleTextureProgram(gl); |
|
137 bufferObjects = wtu.setupUnitQuad(gl); |
|
138 texture = wtu.createColoredTexture(gl, canvas.width, canvas.height, texColor); |
|
139 |
|
140 gl.uniform1i(gl.getUniformLocation(program, "tex"), 0); |
|
141 wtu.drawQuad(gl, [0, 0, 0, 255]); |
|
142 |
|
143 var compare = texColor.slice(0, 3); |
|
144 wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, compare, "shouldBe " + compare); |
|
145 |
|
146 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
147 } |
|
148 |
|
149 function testOriginalContext() |
|
150 { |
|
151 debug("Test valid context"); |
|
152 shouldBeFalse("gl.isContextLost()"); |
|
153 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
154 testRendering(); |
|
155 debug(""); |
|
156 } |
|
157 |
|
158 function testLostContext(e) |
|
159 { |
|
160 debug("Test lost context"); |
|
161 shouldBeFalse("contextLostEventFired"); |
|
162 contextLostEventFired = true; |
|
163 shouldBeTrue("gl.isContextLost()"); |
|
164 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
165 debug(""); |
|
166 if (allowRestore) |
|
167 e.preventDefault(); |
|
168 } |
|
169 |
|
170 function testShouldNotRestoreContext(e) |
|
171 { |
|
172 testFailed("Should not restore the context unless preventDefault is called on the context lost event"); |
|
173 debug(""); |
|
174 } |
|
175 |
|
176 function testResources(expected) |
|
177 { |
|
178 var tests = [ |
|
179 "gl.bindTexture(gl.TEXTURE_2D, texture)", |
|
180 "gl.useProgram(program)", |
|
181 "gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0])", |
|
182 ]; |
|
183 |
|
184 for (var i = 0; i < tests.length; ++i) |
|
185 shouldGenerateGLError(gl, expected, tests[i]); |
|
186 } |
|
187 |
|
188 function testRestoredContext() |
|
189 { |
|
190 debug("Test restored context"); |
|
191 shouldBeFalse("contextRestoredEventFired"); |
|
192 contextRestoredEventFired = true; |
|
193 shouldBeFalse("gl.isContextLost()"); |
|
194 shouldBe("gl.getError()", "gl.NO_ERROR"); |
|
195 |
|
196 // Validate that using old resources fails. |
|
197 testResources(gl.INVALID_OPERATION); |
|
198 |
|
199 testRendering(); |
|
200 |
|
201 // Validate new resources created in testRendering(). |
|
202 testResources(gl.NO_ERROR); |
|
203 debug(""); |
|
204 } |
|
205 |
|
206 |
|
207 </script> |
|
208 </head> |
|
209 <body onload="init()"> |
|
210 <div id="description"></div> |
|
211 <div id="console"></div> |
|
212 </body> |
|
213 </html> |