tor-browser

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

tex-image-and-sub-image-3d-with-image-data.js (10681B)


      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 function generateTest(internalFormat, pixelFormat, pixelType, prologue, resourcePath, defaultContextVersion) {
      8    var wtu = WebGLTestUtils;
      9    var tiu = TexImageUtils;
     10    var gl = null;
     11    var successfullyParsed = false;
     12    var imageData = null;
     13    var blackColor = [0, 0, 0];
     14    var originalPixels = (function() {
     15        // (red|green|blue|cyan)(opaque|transparent)
     16        var ro = [255, 0, 0, 255]; var rt = [255, 0, 0, 0];
     17        var go = [0, 255, 0, 255]; var gt = [0, 255, 0, 0];
     18        var bo = [0, 0, 255, 255]; var bt = [0, 0, 255, 0];
     19        var co = [0, 255, 255, 255]; var ct = [0, 255, 255, 0];
     20        return [ro, rt, go, gt,
     21                ro, rt, go, gt,
     22                bo, bt, co, ct,
     23                bo, bt, co, ct];
     24    })();
     25 
     26    function init()
     27    {
     28        description('Verify texImage3D and texSubImage3D code paths taking ImageData (' + internalFormat + '/' + pixelFormat + '/' + pixelType + ')');
     29 
     30        // Set the default context version while still allowing the webglVersion URL query string to override it.
     31        wtu.setDefault3DContextVersion(defaultContextVersion);
     32        gl = wtu.create3DContext("example");
     33 
     34        if (!prologue(gl)) {
     35            finishTest();
     36            return;
     37        }
     38 
     39        gl.clearColor(0,0,0,1);
     40        gl.clearDepth(1);
     41        gl.disable(gl.BLEND);
     42 
     43        var canvas2d = document.getElementById("texcanvas");
     44        var context2d = canvas2d.getContext("2d");
     45        imageData = context2d.createImageData(4, 4);
     46        var data = imageData.data;
     47        for (var i = 0; i < originalPixels.length; i++) {
     48            data.set(originalPixels[i], 4 * i);
     49        }
     50 
     51        runTest();
     52    }
     53 
     54    function runOneIteration(useTexSubImage3D, flipY, premultiplyAlpha, bindingTarget,
     55                             depth, sourceSubRectangle, rTexCoord, program)
     56    {
     57        var expected = simulate(flipY, premultiplyAlpha, depth, sourceSubRectangle, rTexCoord);
     58        var sourceSubRectangleString = '';
     59        if (sourceSubRectangle) {
     60            sourceSubRectangleString = ', sourceSubRectangle=' + sourceSubRectangle;
     61            sourceSubRectangleString += ', rTexCoord=' + rTexCoord;
     62        }
     63        debug('');
     64        debug('Testing ' + (useTexSubImage3D ? 'texSubImage3D' : 'texImage3D') +
     65              ' with flipY=' + flipY + ', premultiplyAlpha=' + premultiplyAlpha +
     66              ', bindingTarget=' + (bindingTarget == gl.TEXTURE_3D ? 'TEXTURE_3D' : 'TEXTURE_2D_ARRAY') +
     67              sourceSubRectangleString);
     68        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
     69        // Enable writes to the RGBA channels
     70        gl.colorMask(1, 1, 1, 0);
     71        var texture = gl.createTexture();
     72        // Bind the texture to texture unit 0
     73        gl.bindTexture(bindingTarget, texture);
     74        // Set up texture parameters
     75        gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
     76        gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
     77        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
     78        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
     79        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
     80        // Set up pixel store parameters
     81        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
     82        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha);
     83        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
     84        var uploadWidth = imageData.width;
     85        var uploadHeight = imageData.height;
     86        if (sourceSubRectangle) {
     87            gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, sourceSubRectangle[0]);
     88            gl.pixelStorei(gl.UNPACK_SKIP_ROWS, sourceSubRectangle[1]);
     89            uploadWidth = sourceSubRectangle[2];
     90            uploadHeight = sourceSubRectangle[3];
     91        }
     92        // Upload the image into the texture
     93        if (useTexSubImage3D) {
     94            // Initialize the texture to black first
     95            gl.texImage3D(bindingTarget, 0, gl[internalFormat], uploadWidth, uploadHeight, depth, 0,
     96                          gl[pixelFormat], gl[pixelType], null);
     97            gl.texSubImage3D(bindingTarget, 0, 0, 0, 0, uploadWidth, uploadHeight, depth,
     98                             gl[pixelFormat], gl[pixelType], imageData);
     99        } else {
    100            gl.texImage3D(bindingTarget, 0, gl[internalFormat], uploadWidth, uploadHeight, depth, 0,
    101                          gl[pixelFormat], gl[pixelType], imageData);
    102        }
    103        gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
    104        gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
    105        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from texture upload");
    106 
    107        var tl = expected[0][0];
    108        var tr = expected[0][1];
    109        var bl = expected[1][0];
    110        var br = expected[1][1];
    111 
    112        var rCoordLocation = gl.getUniformLocation(program, 'uRCoord');
    113        if (!rCoordLocation) {
    114            testFailed("Shader incorrectly set up; couldn't find uRCoord uniform");
    115            return;
    116        }
    117        gl.uniform1f(rCoordLocation, rTexCoord);
    118        // Draw the triangles
    119        wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
    120 
    121        var width = gl.canvas.width;
    122        var halfWidth = Math.floor(width / 2);
    123        var height = gl.canvas.height;
    124        var halfHeight = Math.floor(height / 2);
    125 
    126        var top = 0;
    127        var bottom = height - halfHeight;
    128        var left = 0;
    129        var right = width - halfWidth;
    130 
    131        debug("Checking pixel values");
    132        debug("Expecting: " + expected);
    133        var expectedH = expected.length;
    134        var expectedW = expected[0].length;
    135        var texelH = Math.floor(gl.canvas.height / expectedH);
    136        var texelW = Math.floor(gl.canvas.width / expectedW);
    137        // For each entry of the expected[][] array, check the appropriate
    138        // canvas rectangle for correctness.
    139        for (var row = 0; row < expectedH; row++) {
    140            var y = row * texelH;
    141            for (var col = 0; col < expectedW; col++) {
    142                var x = col * texelW;
    143                var val = expected[row][col];
    144                wtu.checkCanvasRect(gl, x, y, texelW, texelH, val, "should be " + val);
    145            }
    146        }
    147    }
    148 
    149    function runTest()
    150    {
    151        var program = tiu.setupTexturedQuadWith3D(gl, internalFormat);
    152        runTestOnBindingTarget(gl.TEXTURE_3D, program);
    153        program = tiu.setupTexturedQuadWith2DArray(gl, internalFormat);
    154        runTestOnBindingTarget(gl.TEXTURE_2D_ARRAY, program);
    155 
    156        debug("");
    157        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    158        finishTest();
    159    }
    160 
    161    function simulate(flipY, premultiplyAlpha, depth, sourceSubRectangle, rTexCoord) {
    162        var ro = [255, 0, 0];   var rt = premultiplyAlpha ? [0, 0, 0] : [255, 0, 0];
    163        var go = [0, 255, 0];   var gt = premultiplyAlpha ? [0, 0, 0] : [0, 255, 0];
    164        var bo = [0, 0, 255];   var bt = premultiplyAlpha ? [0, 0, 0] : [0, 0, 255];
    165        var co = [0, 255, 255]; var ct = premultiplyAlpha ? [0, 0, 0] : [0, 255, 255];
    166        var expected = [[ro, rt, go, gt],
    167                        [ro, rt, go, gt],
    168                        [bo, bt, co, ct],
    169                        [bo, bt, co, ct]];
    170        switch (gl[pixelFormat]) {
    171          case gl.RED:
    172          case gl.RED_INTEGER:
    173            for (var row = 0; row < 4; row++) {
    174                for (var col = 0; col < 4; col++) {
    175                    expected[row][col][1] = 0; // zero the green channel
    176                }
    177            }
    178            // fall-through
    179          case gl.RG:
    180          case gl.RG_INTEGER:
    181            for (var row = 0; row < 4; row++) {
    182                for (var col = 0; col < 4; col++) {
    183                    expected[row][col][2] = 0; // zero the blue channel
    184                }
    185            }
    186            break;
    187          default:
    188            break;
    189        }
    190 
    191        if (flipY) {
    192            expected.reverse();
    193        }
    194 
    195        if (sourceSubRectangle) {
    196            let expected2 = [];
    197            for (var row = 0; row < sourceSubRectangle[3]; row++) {
    198                expected2[row] = [];
    199                for (var col = 0; col < sourceSubRectangle[2]; col++) {
    200                    expected2[row][col] =
    201                        expected[sourceSubRectangle[1] + row + rTexCoord * sourceSubRectangle[3]][sourceSubRectangle[0] + col];
    202                }
    203            }
    204            expected = expected2;
    205        }
    206 
    207        return expected;
    208    }
    209 
    210    function runTestOnBindingTarget(bindingTarget, program) {
    211        var rects = [
    212            undefined,
    213            [0, 0, 2, 2],
    214            [2, 0, 2, 2],
    215        ];
    216        var dbg = false;  // Set to true for debug output images
    217        if (dbg) {
    218            (function() {
    219                debug("");
    220                debug("Original ImageData (transparent pixels appear black):");
    221                var cvs = document.createElement("canvas");
    222                cvs.width = 4;
    223                cvs.height = 4;
    224                cvs.style.width = "32px";
    225                cvs.style.height = "32px";
    226                cvs.style.imageRendering = "pixelated";
    227                cvs.style.background = "#000";
    228                var ctx = cvs.getContext("2d");
    229                ctx.putImageData(imageData, 0, 0);
    230                var output = document.getElementById("console");
    231                output.appendChild(cvs);
    232            })();
    233        }
    234        for (const sub of [false, true]) {
    235            for (const flipY of [false, true]) {
    236                for (const premul of [false, true]) {
    237                    for (let irect = 0; irect < rects.length; irect++) {
    238                        var rect = rects[irect];
    239                        let depth = rect ? 2 : 1;
    240                        for (let rTexCoord = 0; rTexCoord < depth; rTexCoord++) {
    241                            // TODO: add tests for UNPACK_IMAGE_HEIGHT.
    242                            runOneIteration(sub, flipY, premul, bindingTarget,
    243                                    depth, rect, rTexCoord, program);
    244                            if (dbg) {
    245                                debug("Actual:");
    246                                var img = document.createElement("img");
    247                                img.src = gl.canvas.toDataURL("image/png");
    248                                var output = document.getElementById("console");
    249                                output.appendChild(img);
    250                            }
    251                        }
    252                    }
    253                }
    254            }
    255        }
    256    }
    257 
    258    return init;
    259 }