Home | History | Annotate | Download | only in gpu
      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