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 contextLostTest(kind) 104 { 105 switch (kind) { 106 case "WEBGL_lose_context": { 107 extension = gl.getExtension("WEBKIT_WEBGL_lose_context") || 108 gl.getExtension("WEBGL_lose_context"); 109 extension.loseContext(); 110 break; 111 } 112 case "kill": 113 // nothing -- the browser test navigates to about:gpucrash and kills 114 // the GPU process. 115 break; 116 case "kill_after_notification": 117 // The browser test waits for notification from the page that it 118 // has been loaded before navigating to about:gpucrash. 119 window.domAutomationController.setAutomationId(1); 120 alreadySetAutomationId = true; 121 window.domAutomationController.send("LOADED"); 122 break; 123 case "forced_quantity_loss": 124 // Test creates many new contexts, forcing the original context to be 125 // lost. Then a garbage collect is triggered and the original context is 126 // watched to ensure it restores properly. 127 testQuantityLoss(); 128 break; 129 } 130 } 131 132 function onLoad() { 133 canvas = document.getElementById("canvas1"); 134 w = canvas.width; 135 h = canvas.height; 136 if (!canvas) 137 return; 138 canvas.addEventListener("webglcontextlost", testContextLost, false); 139 canvas.addEventListener("webglcontextrestored", testContextRestored, false); 140 141 gl = canvas.getContext("experimental-webgl"); 142 if (!gl) 143 return; 144 145 if (!testHorizontalBands()) 146 return; 147 148 var query = /query=(.*)/.exec(window.location.href); 149 if (query) 150 contextLostTest(query[1]); 151 } 152 </script> 153 </head> 154 <body onload="onLoad()"> 155 <canvas id="canvas1" width="16px" height="32px"> 156 </canvas> 157 </body> 158 </html> 159