1 <html> 2 <head> 3 <script type="text/javascript"> 4 var canvas; 5 var w, h; 6 var gl; 7 var extension; 8 9 var alreadySetAutomationId = false; 10 11 function testHorizontalBands() { 12 gl.enable(gl.SCISSOR_TEST); 13 14 gl.clearColor(1, 0, 0, 1); 15 gl.scissor(0, 0, w, h/2); 16 gl.clear(gl.COLOR_BUFFER_BIT); 17 18 gl.clearColor(0, 1, 0, 1); 19 gl.scissor(0, h/2, w, h/2); 20 gl.clear(gl.COLOR_BUFFER_BIT); 21 22 gl.disable(gl.SCISSOR_TEST); 23 24 var size = w * h * 4; 25 var array = new Uint8Array(size); 26 gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, array); 27 28 return array[0] == 255 && array[1] == 0 && 29 array[size - 4] == 0 && array[size - 3] == 255; 30 } 31 32 function testContextLost(e) { 33 e.preventDefault(); 34 if (extension) { 35 setTimeout(function() { 36 extension.restoreContext(); 37 extension = null; 38 }, 0); 39 } 40 } 41 42 function testContextRestored() { 43 gl = canvas.getContext("experimental-webgl"); 44 if (!gl || gl.isContextLost()) { 45 // Might just be blocked because of infobar. 46 return; 47 } 48 gl.clearColor(0, 0, 1, 1); 49 gl.clear(gl.COLOR_BUFFER_BIT); 50 51 var a = new Uint8Array(w * h * 4); 52 gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, a); 53 54 if (!alreadySetAutomationId) 55 window.domAutomationController.setAutomationId(1); 56 if (a[0] == 0 && a[1] == 0 && a[2] == 255) 57 window.domAutomationController.send("SUCCESS"); 58 else 59 window.domAutomationController.send("FAILED"); 60 } 61 62 function testQuantityLoss() { 63 var count = 0; 64 var iterations = 128; 65 var garbageCanvases = []; 66 67 function createAndDiscardContext() { 68 count++; 69 70 var c = document.createElement("canvas"); 71 c.width = 1; 72 c.height = 1; 73 garbageCanvases.push(c); 74 75 var ctx = c.getContext("experimental-webgl"); 76 if (!ctx) { 77 return false; 78 } 79 ctx.clear(gl.COLOR_BUFFER_BIT); 80 81 if (count < iterations) { 82 window.requestAnimationFrame(createAndDiscardContext); 83 } else { 84 // Remove the references to the garbage canvases, then attempt to trigger 85 // a garbage collect. 86 garbageCanvases = null; 87 88 window.domAutomationController.setAutomationId(1); 89 alreadySetAutomationId = true; 90 window.domAutomationController.send("LOADED"); 91 92 // Trying to provoke garbage collection through excessive allocations. 93 setInterval(function() { 94 var garbageArray = new Uint8Array(1024 * 1024); 95 garbageArray[0] = 255; 96 }, 10); 97 } 98 }; 99 100 createAndDiscardContext(); 101 } 102 103 function getLoseContextExtension() 104 { 105 return gl.getExtension("WEBKIT_WEBGL_lose_context") || 106 gl.getExtension("WEBGL_lose_context"); 107 } 108 109 function loseContextUsingExtension() 110 { 111 getLoseContextExtension().loseContext(); 112 // Report success at the next frame to give the compositor a chance to draw 113 // using the lost context. 114 window.requestAnimationFrame(function() { 115 window.domAutomationController.send("SUCCESS"); 116 }); 117 } 118 119 function contextLostTest(kind) 120 { 121 switch (kind) { 122 case "WEBGL_lose_context": { 123 extension = getLoseContextExtension(); 124 extension.loseContext(); 125 break; 126 } 127 case "kill": 128 // nothing -- the browser test navigates to about:gpucrash and kills 129 // the GPU process. 130 break; 131 case "kill_after_notification": 132 // The browser test waits for notification from the page that it 133 // has been loaded before navigating to about:gpucrash. 134 window.domAutomationController.setAutomationId(1); 135 alreadySetAutomationId = true; 136 window.domAutomationController.send("LOADED"); 137 break; 138 case "forced_quantity_loss": 139 // Test creates many new contexts, forcing the original context to be 140 // lost. Then a garbage collect is triggered and the original context is 141 // watched to ensure it restores properly. 142 testQuantityLoss(); 143 break; 144 } 145 } 146 147 function onLoad() { 148 canvas = document.getElementById("canvas1"); 149 w = canvas.width; 150 h = canvas.height; 151 if (!canvas) 152 return; 153 canvas.addEventListener("webglcontextlost", testContextLost, false); 154 canvas.addEventListener("webglcontextrestored", testContextRestored, false); 155 156 gl = canvas.getContext("experimental-webgl"); 157 if (!gl) 158 return; 159 160 if (!testHorizontalBands()) 161 return; 162 163 var query = /query=(.*)/.exec(window.location.href); 164 if (query) 165 contextLostTest(query[1]); 166 } 167 </script> 168 </head> 169 <body onload="onLoad()"> 170 <canvas id="canvas1" width="16px" height="32px"> 171 </canvas> 172 </body> 173 </html> 174