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-video.js (10592B)


      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 // This block needs to be outside the onload handler in order for this
      8 // test to run reliably in WebKit's test harness (at least the
      9 // Chromium port). https://bugs.webkit.org/show_bug.cgi?id=87448
     10 initTestingHarness();
     11 
     12 var old = debug;
     13 var debug = function(msg) {
     14  bufferedLogToConsole(msg);
     15  old(msg);
     16 };
     17 
     18 function generateTest(internalFormat, pixelFormat, pixelType, prologue, resourcePath, defaultContextVersion) {
     19    var wtu = WebGLTestUtils;
     20    var tiu = TexImageUtils;
     21    var gl = null;
     22    var successfullyParsed = false;
     23    var redColor = [255, 0, 0];
     24    var greenColor = [0, 255, 0];
     25 
     26    // Test each format separately because many browsers implement each
     27    // differently. Some might be GPU accelerated, some might not. Etc...
     28    var videos = [
     29      { src: resourcePath + "red-green.mp4"         , type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', },
     30      { src: resourcePath + "red-green.bt601.vp9.webm", type: 'video/webm; codecs="vp9"',                   },
     31      { src: resourcePath + "red-green.webmvp8.webm", type: 'video/webm; codecs="vp8, vorbis"',           },
     32    ];
     33 
     34    function init()
     35    {
     36        description('Verify texImage3D and texSubImage3D code paths taking video elements (' + internalFormat + '/' + pixelFormat + '/' + pixelType + ')');
     37 
     38        // Set the default context version while still allowing the webglVersion URL query string to override it.
     39        wtu.setDefault3DContextVersion(defaultContextVersion);
     40        gl = wtu.create3DContext("example");
     41 
     42        if (!prologue(gl)) {
     43            finishTest();
     44            return;
     45        }
     46 
     47        switch (gl[pixelFormat]) {
     48          case gl.RED:
     49          case gl.RED_INTEGER:
     50            greenColor = [0, 0, 0];
     51            break;
     52          default:
     53            break;
     54        }
     55 
     56        gl.clearColor(0,0,0,1);
     57        gl.clearDepth(1);
     58 
     59        runTest();
     60    }
     61 
     62    function runOneIteration(videoElement, flipY, useTexSubImage3D, topColor, bottomColor, program, bindingTarget,
     63                             depth, sourceSubRectangle, unpackImageHeight, rTextureCoord)
     64    {
     65        debug('Testing ' +
     66              (useTexSubImage3D ? "texSubImage3D" : "texImage3D") +
     67              ' with flipY=' + flipY + ' bindingTarget=' +
     68              (bindingTarget == gl.TEXTURE_3D ? 'TEXTURE_3D' : 'TEXTURE_2D_ARRAY') +
     69              (sourceSubRectangle ? ', sourceSubRectangle=' + sourceSubRectangle : '') +
     70              (unpackImageHeight ? ', unpackImageHeight=' + unpackImageHeight : '') +
     71              ', depth=' + depth +
     72              ', rTextureCoord=' + rTextureCoord);
     73        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
     74        // Disable any writes to the alpha channel
     75        gl.colorMask(1, 1, 1, 0);
     76        var texture = gl.createTexture();
     77        // Bind the texture to texture unit 0
     78        gl.bindTexture(bindingTarget, texture);
     79        // Set up texture parameters
     80        gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
     81        gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
     82        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
     83        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
     84        gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
     85        // Set up pixel store parameters
     86        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
     87        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
     88        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
     89        var uploadWidth = videoElement.width;
     90        var uploadHeight = videoElement.height;
     91        if (sourceSubRectangle) {
     92            gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, sourceSubRectangle[0]);
     93            gl.pixelStorei(gl.UNPACK_SKIP_ROWS, sourceSubRectangle[1]);
     94            uploadWidth = sourceSubRectangle[2];
     95            uploadHeight = sourceSubRectangle[3];
     96        }
     97        if (unpackImageHeight) {
     98            gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight);
     99        }
    100        // Upload the videoElement into the texture
    101        if (useTexSubImage3D) {
    102            // Initialize the texture to black first
    103            gl.texImage3D(bindingTarget, 0, gl[internalFormat],
    104                          uploadWidth, uploadHeight, depth, 0,
    105                          gl[pixelFormat], gl[pixelType], null);
    106            gl.texSubImage3D(bindingTarget, 0, 0, 0, 0,
    107                             uploadWidth, uploadHeight, depth,
    108                             gl[pixelFormat], gl[pixelType], videoElement);
    109        } else {
    110            gl.texImage3D(bindingTarget, 0, gl[internalFormat],
    111                          uploadWidth, uploadHeight, depth, 0,
    112                          gl[pixelFormat], gl[pixelType], videoElement);
    113        }
    114        gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
    115        gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
    116        gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);
    117 
    118        var c = document.createElement("canvas");
    119        c.width = 16;
    120        c.height = 16;
    121        c.style.border = "1px solid black";
    122        var ctx = c.getContext("2d");
    123        ctx.drawImage(videoElement, 0, 0, 16, 16);
    124        document.body.appendChild(c);
    125 
    126        var rCoordLocation = gl.getUniformLocation(program, 'uRCoord');
    127        if (!rCoordLocation) {
    128            testFailed('Shader incorrectly set up; couldn\'t find uRCoord uniform');
    129            return;
    130        }
    131        gl.uniform1f(rCoordLocation, rTextureCoord);
    132 
    133        // Draw the triangles
    134        wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
    135        // Check a few pixels near the top and bottom and make sure they have
    136        // the right color.
    137        const tolerance = 6;
    138        debug("Checking lower left corner");
    139        wtu.checkCanvasRect(gl, 4, 4, 2, 2, bottomColor,
    140                            "shouldBe " + bottomColor, tolerance);
    141        debug("Checking upper left corner");
    142        wtu.checkCanvasRect(gl, 4, gl.canvas.height - 8, 2, 2, topColor,
    143                            "shouldBe " + topColor, tolerance);
    144    }
    145 
    146    function runTest(videoElement)
    147    {
    148        var cases = [
    149            // No UNPACK_IMAGE_HEIGHT specified.
    150            { flipY: false, sourceSubRectangle: [32, 16, 16, 16], depth: 5, rTextureCoord: 0,
    151              topColor: redColor, bottomColor: redColor },
    152            // Note that an rTextureCoord of 4.0 satisfies the need to
    153            // have it be >= 1.0 for the TEXTURE_3D case, and also its
    154            // use as an index in the TEXTURE_2D_ARRAY case.
    155            { flipY: false, sourceSubRectangle: [32, 16, 16, 16], depth: 5, rTextureCoord: 4,
    156              topColor: greenColor, bottomColor: greenColor },
    157            { flipY: false, sourceSubRectangle: [24, 48, 32, 32], depth: 1, rTextureCoord: 0,
    158              topColor: greenColor, bottomColor: redColor },
    159            { flipY: true, sourceSubRectangle: [24, 48, 32, 32], depth: 1, rTextureCoord: 0,
    160              topColor: redColor, bottomColor: greenColor },
    161 
    162            // Use UNPACK_IMAGE_HEIGHT to skip some pixels.
    163            { flipY: false, sourceSubRectangle: [32, 16, 16, 16], depth: 2, unpackImageHeight: 64, rTextureCoord: 0,
    164              topColor: redColor, bottomColor: redColor },
    165            { flipY: false, sourceSubRectangle: [32, 16, 16, 16], depth: 2, unpackImageHeight: 64, rTextureCoord: 1,
    166              topColor: greenColor, bottomColor: greenColor },
    167        ];
    168 
    169        function runTexImageTest(bindingTarget) {
    170            var program;
    171            if (bindingTarget == gl.TEXTURE_3D) {
    172                program = tiu.setupTexturedQuadWith3D(gl, internalFormat);
    173            } else {
    174                program = tiu.setupTexturedQuadWith2DArray(gl, internalFormat);
    175            }
    176 
    177            return new Promise(function(resolve, reject) {
    178                var videoNdx = 0;
    179                var video;
    180                function runNextVideo() {
    181                    if (video) {
    182                        video.pause();
    183                    }
    184 
    185                    if (videoNdx == videos.length) {
    186                        resolve("SUCCESS");
    187                        return;
    188                    }
    189 
    190                    var info = videos[videoNdx++];
    191                    debug("");
    192                    debug("testing: " + info.type);
    193                    video = document.createElement("video");
    194                    video.muted = true;
    195                    var canPlay = true;
    196                    if (!video.canPlayType) {
    197                      testFailed("video.canPlayType required method missing");
    198                      runNextVideo();
    199                      return;
    200                    }
    201 
    202                    if(!video.canPlayType(info.type).replace(/no/, '')) {
    203                      debug(info.type + " unsupported");
    204                      runNextVideo();
    205                      return;
    206                    };
    207 
    208                    document.body.appendChild(video);
    209                    video.type = info.type;
    210                    video.src = info.src;
    211                    wtu.startPlayingAndWaitForVideo(video, runTest);
    212                }
    213                function runTest() {
    214                    for (var i in cases) {
    215                        runOneIteration(video, cases[i].flipY, false,
    216                                        cases[i].topColor, cases[i].bottomColor,
    217                                        program, bindingTarget, cases[i].depth,
    218                                        cases[i].sourceSubRectangle,
    219                                        cases[i].unpackImageHeight,
    220                                        cases[i].rTextureCoord);
    221                        runOneIteration(video, cases[i].flipY, true,
    222                                        cases[i].topColor, cases[i].bottomColor,
    223                                        program, bindingTarget, cases[i].depth,
    224                                        cases[i].sourceSubRectangle,
    225                                        cases[i].unpackImageHeight,
    226                                        cases[i].rTextureCoord);
    227                    }
    228                    runNextVideo();
    229                }
    230                runNextVideo();
    231            });
    232        }
    233 
    234        runTexImageTest(gl.TEXTURE_3D).then(function(val) {
    235            runTexImageTest(gl.TEXTURE_2D_ARRAY).then(function(val) {
    236                wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
    237                finishTest();
    238            });
    239        });
    240    }
    241 
    242    return init;
    243 }