tor-browser

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

oes-element-index-uint.html (16914B)


      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 <meta charset="utf-8">
     11 <title>WebGL OES_element_index_uint Conformance Tests</title>
     12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     13 <script src="../../js/js-test-pre.js"></script>
     14 <script src="../../js/webgl-test-utils.js"></script>
     15 
     16 <script id="vs" type="x-shader/x-vertex">
     17 attribute vec4 vPosition;
     18 attribute vec4 vColor;
     19 varying vec4 color;
     20 void main() {
     21    gl_Position = vPosition;
     22    color = vColor;
     23 }
     24 </script>
     25 <script id="fs" type="x-shader/x-fragment">
     26 precision mediump float;
     27 varying vec4 color;
     28 void main() {
     29  gl_FragColor = color;
     30 }
     31 </script>
     32 
     33 </head>
     34 <body>
     35 <div id="description"></div>
     36 <div id="console"></div>
     37 <script>
     38 "use strict";
     39 description("This test verifies the functionality of the OES_element_index_uint extension, if it is available.");
     40 
     41 debug("");
     42 
     43 var wtu = WebGLTestUtils;
     44 var gl = null;
     45 var ext = null;
     46 var canvas = null;
     47 
     48 // Test both STATIC_DRAW and DYNAMIC_DRAW as a regression test
     49 // for a bug in ANGLE which has since been fixed.
     50 for (var ii = 0; ii < 2; ++ii) {
     51    canvas = document.createElement("canvas");
     52    canvas.width = 50;
     53    canvas.height = 50;
     54 
     55    gl = wtu.create3DContext(canvas);
     56 
     57    if (!gl) {
     58        testFailed("WebGL context does not exist");
     59    } else {
     60        testPassed("WebGL context exists");
     61 
     62        var drawType = (ii == 0) ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW;
     63        debug("Testing " + ((ii == 0) ? "STATIC_DRAW" : "DYNAMIC_DRAW"));
     64 
     65 
     66        // Query the extension and store globally so shouldBe can access it
     67        ext = gl.getExtension("OES_element_index_uint");
     68        if (!ext) {
     69            testPassed("No OES_element_index_uint support -- this is legal");
     70 
     71            runSupportedTest(false);
     72        } else {
     73            testPassed("Successfully enabled OES_element_index_uint extension");
     74 
     75            runSupportedTest(true);
     76 
     77            runDrawTests(drawType);
     78 
     79            // These tests are tweaked duplicates of the buffers/index-validation* tests
     80            // using unsigned int indices to ensure that behavior remains consistent
     81            runIndexValidationTests(drawType);
     82            runCopiesIndicesTests(drawType);
     83            runResizedBufferTests(drawType);
     84            runVerifiesTooManyIndicesTests(drawType);
     85            runCrashWithBufferSubDataTests(drawType);
     86 
     87            wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
     88        }
     89    }
     90 }
     91 
     92 function runSupportedTest(extensionEnabled) {
     93    var supported = gl.getSupportedExtensions();
     94    if (supported.indexOf("OES_element_index_uint") >= 0) {
     95        if (extensionEnabled) {
     96            testPassed("OES_element_index_uint listed as supported and getExtension succeeded");
     97        } else {
     98            testFailed("OES_element_index_uint listed as supported but getExtension failed");
     99        }
    100    } else {
    101        if (extensionEnabled) {
    102            testFailed("OES_element_index_uint not listed as supported but getExtension succeeded");
    103        } else {
    104            testPassed("OES_element_index_uint not listed as supported and getExtension failed -- this is legal");
    105        }
    106    }
    107 }
    108 
    109 function runDrawTests(drawType) {
    110    debug("Test that draws with unsigned integer indices produce the expected results");
    111 
    112    canvas.width = 50; canvas.height = 50;
    113    gl.viewport(0, 0, canvas.width, canvas.height);
    114 
    115    var program = wtu.setupSimpleColorProgram(gl);
    116 
    117    function setupDraw(s) {
    118        // Create a vertex buffer that cannot be fully indexed via shorts
    119        var quadArrayLen = 65537 * 3;
    120        var quadArray = new Float32Array(quadArrayLen);
    121 
    122        // Leave all but the last 4 values zero-ed out
    123        var idx = quadArrayLen - 12;
    124 
    125        // Initialized the last 4 values to a quad
    126        quadArray[idx++] = 1.0 * s;
    127        quadArray[idx++] = 1.0 * s;
    128        quadArray[idx++] = 0.0;
    129 
    130        quadArray[idx++] = -1.0 * s;
    131        quadArray[idx++] = 1.0 * s;
    132        quadArray[idx++] = 0.0;
    133 
    134        quadArray[idx++] = -1.0 * s;
    135        quadArray[idx++] = -1.0 * s;
    136        quadArray[idx++] = 0.0;
    137 
    138        quadArray[idx++] = 1.0 * s;
    139        quadArray[idx++] = -1.0 * s;
    140        quadArray[idx++] = 0.0;
    141 
    142        var vertexObject = gl.createBuffer();
    143        gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    144        gl.bufferData(gl.ARRAY_BUFFER, quadArray, drawType);
    145 
    146        // Create an unsigned int index buffer that indexes the last 4 vertices
    147        var baseIndex = (quadArrayLen / 3) - 4;
    148 
    149        var indexObject = gl.createBuffer();
    150        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
    151        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([
    152            baseIndex + 0,
    153            baseIndex + 1,
    154            baseIndex + 2,
    155            baseIndex + 2,
    156            baseIndex + 3,
    157            baseIndex + 0]), drawType);
    158 
    159        var opt_positionLocation = 0;
    160        gl.enableVertexAttribArray(opt_positionLocation);
    161        gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
    162    };
    163    function testPixel(blockList, allowList) {
    164        function testList(list, expected) {
    165            for (var n = 0; n < list.length; n++) {
    166                var l = list[n];
    167                var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
    168                var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
    169                wtu.checkCanvasRect(gl, x, y, 1, 1, [expected, expected, expected],
    170                    "Draw should pass", 2);
    171            }
    172        }
    173        testList(blockList, 0);
    174        testList(allowList, 255);
    175    };
    176    function verifyDraw(s) {
    177        gl.clearColor(1.0, 1.0, 1.0, 1.0);
    178        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    179        wtu.setFloatDrawColor(gl, [0.0, 0.0, 0.0, 1.0]);
    180        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
    181 
    182        var blockList = [];
    183        var allowList = [];
    184        var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
    185        for (var n = 0; n < points.length; n++) {
    186            if (points[n] <= s) {
    187                blockList.push(points[n]);
    188            } else {
    189                allowList.push(points[n]);
    190            }
    191        }
    192        testPixel(blockList, allowList);
    193    };
    194 
    195    setupDraw(0.5);
    196    verifyDraw(0.5);
    197 }
    198 
    199 function runIndexValidationTests(drawType) {
    200    description("Tests that index validation verifies the correct number of indices");
    201 
    202    function sizeInBytes(type) {
    203      switch (type) {
    204      case gl.BYTE:
    205      case gl.UNSIGNED_BYTE:
    206        return 1;
    207      case gl.SHORT:
    208      case gl.UNSIGNED_SHORT:
    209        return 2;
    210      case gl.INT:
    211      case gl.UNSIGNED_INT:
    212      case gl.FLOAT:
    213        return 4;
    214      default:
    215        throw "unknown type";
    216      }
    217    }
    218 
    219    var program = wtu.loadStandardProgram(gl);
    220 
    221    // 3 vertices => 1 triangle, interleaved data
    222    var dataComplete = new Float32Array([0, 0, 0, 1,
    223                                         0, 0, 1,
    224                                         1, 0, 0, 1,
    225                                         0, 0, 1,
    226                                         1, 1, 1, 1,
    227                                         0, 0, 1]);
    228    var dataIncomplete = new Float32Array([0, 0, 0, 1,
    229                                           0, 0, 1,
    230                                           1, 0, 0, 1,
    231                                           0, 0, 1,
    232                                           1, 1, 1, 1]);
    233    var indices = new Uint32Array([0, 1, 2]);
    234 
    235    debug("Testing with valid indices");
    236 
    237    var bufferComplete = gl.createBuffer();
    238    gl.bindBuffer(gl.ARRAY_BUFFER, bufferComplete);
    239    gl.bufferData(gl.ARRAY_BUFFER, dataComplete, drawType);
    240    var elements = gl.createBuffer();
    241    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
    242    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
    243    gl.useProgram(program);
    244    var vertexLoc = gl.getAttribLocation(program, "a_vertex");
    245    var normalLoc = gl.getAttribLocation(program, "a_normal");
    246    gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
    247    gl.enableVertexAttribArray(vertexLoc);
    248    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
    249    gl.enableVertexAttribArray(normalLoc);
    250    shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
    251    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    252    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    253    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    254 
    255    debug("Testing with out-of-range indices");
    256 
    257    var bufferIncomplete = gl.createBuffer();
    258    gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
    259    gl.bufferData(gl.ARRAY_BUFFER, dataIncomplete, drawType);
    260    gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
    261    gl.enableVertexAttribArray(vertexLoc);
    262    gl.disableVertexAttribArray(normalLoc);
    263    debug("Enable vertices, valid");
    264    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    265    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    266    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    267    debug("Enable normals, out-of-range");
    268    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
    269    gl.enableVertexAttribArray(normalLoc);
    270    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    271    wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
    272                              'gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    273 
    274    debug("Test with enabled attribute that does not belong to current program");
    275 
    276    gl.disableVertexAttribArray(normalLoc);
    277    var extraLoc = Math.max(vertexLoc, normalLoc) + 1;
    278    gl.enableVertexAttribArray(extraLoc);
    279    debug("Enable an extra attribute with null");
    280    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    281    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    282    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
    283    debug("Enable an extra attribute with insufficient data buffer");
    284    gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
    285    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    286    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    287    debug("Pass large negative index to vertexAttribPointer");
    288    gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
    289    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
    290    shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
    291 }
    292 
    293 function runCopiesIndicesTests(drawType) {
    294    debug("Test that client data is always copied during bufferData and bufferSubData calls");
    295 
    296    var program = wtu.loadStandardProgram(gl);
    297 
    298    gl.useProgram(program);
    299    var vertexObject = gl.createBuffer();
    300    gl.enableVertexAttribArray(0);
    301    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    302    // 4 vertices -> 2 triangles
    303    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), drawType);
    304    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
    305 
    306    var indexObject = gl.createBuffer();
    307 
    308    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
    309    var indices = new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]);
    310    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
    311    wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
    312    var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
    313                                                         "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
    314    wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
    315    indices[0] = 2;
    316    indices[5] = 1;
    317    wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
    318    wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
    319    wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
    320 }
    321 
    322 function runResizedBufferTests(drawType) {
    323    debug("Test that updating the size of a vertex buffer is properly noticed by the WebGL implementation.");
    324 
    325    var program = wtu.setupProgram(gl, ["vs", "fs"], ["vPosition", "vColor"]);
    326    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after initialization");
    327 
    328    var vertexObject = gl.createBuffer();
    329    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    330    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
    331        [-1,1,0, 1,1,0, -1,-1,0,
    332         -1,-1,0, 1,1,0, 1,-1,0]), drawType);
    333    gl.enableVertexAttribArray(0);
    334    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
    335    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex setup");
    336 
    337    var texCoordObject = gl.createBuffer();
    338    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
    339    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
    340        [0,0, 1,0, 0,1,
    341         0,1, 1,0, 1,1]), drawType);
    342    gl.enableVertexAttribArray(1);
    343    gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
    344    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coord setup");
    345 
    346    // Now resize these buffers because we want to change what we're drawing.
    347    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    348    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    349        -1,1,0, 1,1,0, -1,-1,0, 1,-1,0,
    350        -1,1,0, 1,1,0, -1,-1,0, 1,-1,0]), drawType);
    351    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex redefinition");
    352    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
    353    gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
    354        255, 0, 0, 255,
    355        255, 0, 0, 255,
    356        255, 0, 0, 255,
    357        255, 0, 0, 255,
    358        0, 255, 0, 255,
    359        0, 255, 0, 255,
    360        0, 255, 0, 255,
    361        0, 255, 0, 255]), drawType);
    362    gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
    363    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coordinate / color redefinition");
    364 
    365    var numQuads = 2;
    366    var indices = new Uint32Array(numQuads * 6);
    367    for (var ii = 0; ii < numQuads; ++ii) {
    368        var offset = ii * 6;
    369        var quad = (ii == (numQuads - 1)) ? 4 : 0;
    370        indices[offset + 0] = quad + 0;
    371        indices[offset + 1] = quad + 1;
    372        indices[offset + 2] = quad + 2;
    373        indices[offset + 3] = quad + 2;
    374        indices[offset + 4] = quad + 1;
    375        indices[offset + 5] = quad + 3;
    376    }
    377    var indexObject = gl.createBuffer();
    378    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
    379    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
    380    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
    381    gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_INT, 0);
    382    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
    383 }
    384 
    385 function runVerifiesTooManyIndicesTests(drawType) {
    386    description("Tests that index validation for drawElements does not examine too many indices");
    387 
    388    var program = wtu.loadStandardProgram(gl);
    389 
    390    gl.useProgram(program);
    391    var vertexObject = gl.createBuffer();
    392    gl.enableVertexAttribArray(0);
    393    gl.disableVertexAttribArray(1);
    394    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    395    // 4 vertices -> 2 triangles
    396    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), drawType);
    397    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
    398 
    399    var indexObject = gl.createBuffer();
    400 
    401    debug("Test out of range indices")
    402    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
    403    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]), drawType);
    404    wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
    405    var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
    406                                                         "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
    407    wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
    408 }
    409 
    410 function runCrashWithBufferSubDataTests(drawType) {
    411    debug('Verifies that the index validation code which is within bufferSubData does not crash.')
    412 
    413    var elementBuffer = gl.createBuffer();
    414    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
    415    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 256, drawType);
    416    var data = new Uint32Array(127);
    417    gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 64, data);
    418    wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "after attempting to update a buffer outside of the allocated bounds");
    419    testPassed("bufferSubData, when buffer object was initialized with null, did not crash");
    420 }
    421 
    422 debug("");
    423 var successfullyParsed = true;
    424 </script>
    425 <script src="../../js/js-test-post.js"></script>
    426 
    427 </body>
    428 </html>