OLD | NEW |
1 description("Test the behavior of canvas recovery after a gpu context loss"); | 1 description("Test the behavior of canvas recovery after a gpu context loss"); |
2 | 2 |
3 var recoveryLoopPeriod = 5; | |
4 var ctx; | 3 var ctx; |
5 var imageData; | 4 var lostEventHasFired = false; |
6 var imgdata; | 5 var contextLostTest; |
7 | 6 |
8 if (window.internals && window.testRunner) { | 7 if (window.internals && window.testRunner) { |
9 testRunner.dumpAsText(); | 8 testRunner.dumpAsText(); |
10 ctx = document.createElement('canvas').getContext('2d'); | 9 var canvas = document.createElement('canvas'); |
| 10 canvas.addEventListener('contextlost', contextLost); |
| 11 canvas.addEventListener('contextrestored', contextRestored); |
| 12 ctx = canvas.getContext('2d'); |
11 document.body.appendChild(ctx.canvas); | 13 document.body.appendChild(ctx.canvas); |
12 ctx.fillStyle = '#f00'; | 14 verifyContextLost(false); |
13 ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); | |
14 imageData = ctx.getImageData(0, 0, 1, 1); | |
15 imgdata = imageData.data; | |
16 shouldBe("imgdata[0]", "255"); | |
17 shouldBe("imgdata[1]", "0"); | |
18 shouldBe("imgdata[2]", "0"); | |
19 shouldBe("imgdata[3]", "255"); | |
20 | |
21 window.internals.loseSharedGraphicsContext3D(); | 15 window.internals.loseSharedGraphicsContext3D(); |
22 // Verify whether canvas contents are lost with the graphics context. | 16 // for the canvas to realize it Graphics context was lost we must try to use
the canvas |
23 imageData = ctx.getImageData(0, 0, 1, 1); | 17 ctx.fillRect(0, 0, 1, 1); |
24 if (imageData.data[0] == 255) { | 18 if (!ctx.isContextLost()) { |
25 debug('<span>Aborting test: Graphics context loss did not destroy canvas
contents. This is expected if canvas is not accelerated.</span>'); | 19 debug('<span>Aborting test: Graphics context loss did not destroy canvas
contents. This is expected if canvas is not accelerated.</span>'); |
26 } else { | 20 } else { |
27 // Redrawing immediately will fail because we are working with an | 21 verifyContextLost(true); |
28 // unrecovered context here. The context recovery is asynchronous | |
29 // because it requires the context loss notification task to be | |
30 // processed on the renderer main thread, which triggers the | |
31 // re-creation of the SharedGC3D. | |
32 ctx.fillStyle = '#0f0'; | |
33 ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); | |
34 imageData = ctx.getImageData(0, 0, 1, 1); | |
35 imgdata = imageData.data; | |
36 shouldBe("imgdata[0]", "0"); | |
37 shouldBe("imgdata[1]", "0"); | |
38 shouldBe("imgdata[2]", "0"); | |
39 shouldBe("imgdata[3]", "0"); | |
40 | |
41 testRunner.waitUntilDone(); | 22 testRunner.waitUntilDone(); |
42 setTimeout(recoveryLoop, recoveryLoopPeriod); | |
43 } | 23 } |
44 } else { | 24 } else { |
45 testFailed('This test requires window.internals and window.testRunner.'); | 25 testFailed('This test requires window.internals and window.testRunner.'); |
46 } | 26 } |
47 | 27 |
48 // Graphics context recovery happens asynchronously. To test for recovery, we k
eep | 28 |
49 // retrying to use the canvas until it succeeds, which should hapen long before
the test | 29 function verifyContextLost(shouldBeLost) { |
50 // times-out. | 30 // Verify context loss experimentally as well as isContextLost() |
51 function recoveryLoop() { | 31 ctx.fillStyle = '#0f0'; |
52 ctx.fillStyle = '#00f'; | 32 ctx.fillRect(0, 0, 1, 1); |
53 ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); | 33 contextLostTest = ctx.getImageData(0, 0, 1, 1).data[1] == 0; |
54 imageData = ctx.getImageData(0, 0, 1, 1); | 34 if (shouldBeLost) { |
55 if (imageData.data[2] == 255) { | 35 shouldBeTrue('contextLostTest'); |
56 testPassed('Graphics context recovered.'); | 36 shouldBeTrue('ctx.isContextLost()'); |
57 testRunner.notifyDone(); | |
58 } else { | 37 } else { |
59 // Context not yet recovered. Try again. | 38 shouldBeFalse('contextLostTest'); |
60 setTimeout(recoveryLoop, recoveryLoopPeriod); | 39 shouldBeFalse('ctx.isContextLost()'); |
61 } | 40 } |
62 } | 41 } |
| 42 |
| 43 function contextLost() { |
| 44 if (lostEventHasFired) { |
| 45 testFailed('Context lost event was dispatched more than once.'); |
| 46 } else { |
| 47 testPassed('Graphics context lost event dispatched.'); |
| 48 } |
| 49 lostEventHasFired = true; |
| 50 verifyContextLost(true); |
| 51 } |
| 52 |
| 53 function contextRestored() { |
| 54 if (lostEventHasFired) { |
| 55 testPassed('Context restored event dispatched after context lost.'); |
| 56 } else { |
| 57 testFailed('Context restored event was dispatched before a context lost
event.'); |
| 58 } |
| 59 verifyContextLost(false); |
| 60 testRunner.notifyDone(); |
| 61 } |
OLD | NEW |