tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

webgl-drawelements-validation.html (5454B)


      1 <!--
      2 Copyright (c) 2019 The Khronos Group Inc.
      3 Use of this source code is governed by an MIT-style license that can be
      4 found in the LICENSE.txt file.
      5 -->
      6 
      7 <!DOCTYPE html>
      8 <html>
      9 <head>
     10 <title>Micro-benchmark for WebGL drawElements index validation</title>
     11 <style>
     12 canvas {
     13    border: 1px solid #000;
     14 }
     15 </style>
     16 <script src="../js/webgl-test-utils.js"></script>
     17 <script type="application/javascript">
     18 "use strict";
     19 
     20 var wtu = WebGLTestUtils;
     21 
     22 var totalTimeTest1 = 0;
     23 var totalTimeTest2 = 0;
     24 var totalTimeTest3 = 0;
     25 var iterationsLeft = 10; // How many times to run the full test.
     26 var indexCount = 500001; // Divisible by 3.
     27 
     28 var indices = [];
     29 for (var i = 0; i < indexCount - 1; ++i) {
     30    indices.push(0);
     31    indices.push(1);
     32    indices.push(2);
     33    indices.push(3);
     34 }
     35 indices.push(4);
     36 
     37 var fullIndicesArray = new Uint16Array(indices);
     38 
     39 var drawIterations = 50;
     40 
     41 var errorsCorrect = true;
     42 
     43 var log = function(msg) {
     44    console.log(msg);
     45    var p = document.createElement('p');
     46    p.textContent = msg;
     47    document.body.appendChild(p);
     48 };
     49 
     50 var runTestIteration = function() {
     51    var canvas = document.createElement('canvas');
     52    canvas.width = 10;
     53    canvas.height = 10;
     54    var gl = wtu.create3DContext(canvas);
     55    document.body.appendChild(canvas);
     56 
     57    var location = 0;
     58    wtu.setupSimpleColorProgram(gl, location);
     59 
     60    var verts = gl.createBuffer();
     61    gl.bindBuffer(gl.ARRAY_BUFFER, verts);
     62    var vertData = new Float32Array([-1, -1,
     63                                     -1, 1,
     64                                     1, -1,
     65                                     1, 1]);
     66    gl.bufferData(gl.ARRAY_BUFFER, vertData, gl.STATIC_DRAW);
     67    gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);
     68    gl.enableVertexAttribArray(location);
     69 
     70    var indexBuffer = gl.createBuffer();
     71    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
     72    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, fullIndicesArray, gl.DYNAMIC_DRAW);
     73    gl.finish();
     74 
     75    var measureTime = function(f) {
     76        var startTime = new Date().getTime();
     77        f();
     78        var error = gl.getError();
     79        var endTime = new Date().getTime();
     80        errorsCorrect = errorsCorrect && error == gl.INVALID_OPERATION;
     81        return endTime - startTime;
     82    };
     83 
     84    // The buffer has at least one out-of-range index from the start,
     85    // so only validation will happen, not drawing.
     86 
     87    totalTimeTest1 += measureTime(function() {
     88        for (var i = 0; i < drawIterations; ++i) {
     89            // Change all data, which will cause complete revalidation of the index buffer.
     90            gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, fullIndicesArray);
     91            gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
     92        }
     93    });
     94 
     95    totalTimeTest2 += measureTime(function() {
     96        for (var i = 0; i < drawIterations; ++i) {
     97            // Change only one index and vary the amount of referenced indices.
     98            // These should not be a big problem to a smart implementation.
     99            gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, Math.floor(indices.length / 2), new Uint16Array([i + 5]));
    100            gl.drawElements(gl.TRIANGLES, indices.length - i * 3, gl.UNSIGNED_SHORT, 0);
    101        }
    102    });
    103 
    104    totalTimeTest3 += measureTime(function() {
    105        for (var i = 0; i < drawIterations; ++i) {
    106            // Change data at two indices to cause completely revalidating the index buffer in
    107            // current implementations in Chrome and Firefox (as of March 17th 2014).
    108            gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([i + 5]));
    109            gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, indices.length - 1, new Uint16Array([i + 5]));
    110            gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
    111        }
    112    });
    113 
    114    setTimeout(function() {
    115        var lose = gl.getExtension('WEBGL_lose_context');
    116        lose.loseContext();
    117    }, 40);
    118 };
    119 
    120 var runTest = function() {
    121    if (iterationsLeft > 0) {
    122        runTestIteration();
    123        --iterationsLeft;
    124        setTimeout(runTest, 500);
    125    } else {
    126        log("Validation returned correct results: " + errorsCorrect);
    127        log('1. Time spent on full buffer updates: ' + totalTimeTest1 + ' ms');
    128        log('Indices uploaded and referenced by draw calls processed: ' + Math.round(indices.length * drawIterations / totalTimeTest1) + ' / ms');
    129        log('2. Time spent on validating single index updates while range referenced also changes on every draw call: ' + totalTimeTest2 + ' ms');
    130        log('Indices referenced by draw calls handled: ' + Math.round(indices.length * drawIterations / totalTimeTest2) + ' / ms');
    131        log('3. Time spent on validating single index updates at each end of the buffer (worst case for Firefox implementation as of March 2014, not reflective of real world performance): ' + totalTimeTest3 + ' ms');
    132        log('Indices referenced by draw calls handled: ' + Math.round(indices.length * drawIterations / totalTimeTest3) + ' / ms');
    133    }
    134 };
    135 </script>
    136 </head>
    137 <body onload="setTimeout(runTest, 100)">
    138 <h1>Micro-benchmark for WebGL drawElements index validation</h1>
    139 <p>Note that these test cases are completely artificial, and their results only very rough indicators of the performance of a specific part of the system.</p>
    140 <p>The benchmark does not perform any drawing, but rather measures the time the browser takes to upload indices and to check if there are out-of-range indices.</p>
    141 </body>
    142 </html>