tor-browser

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

blitframebuffer-outside-readbuffer.html (13100B)


      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 BlitFramebuffer 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 </head>
     16 <body>
     17 <canvas id="example" width="8" height="8"></canvas>
     18 <div id="description"></div>
     19 <div id="console"></div>
     20 
     21 <script>
     22 "use strict";
     23 
     24 var wtu = WebGLTestUtils;
     25 description("This test verifies the functionality of blitFramebuffer.");
     26 
     27 var gl = wtu.create3DContext("example", undefined, 2);
     28 
     29 function checkPixel(color, expectedColor) {
     30  var tolerance = 3;
     31  return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
     32          Math.abs(color[1] - expectedColor[1]) <= tolerance &&
     33          Math.abs(color[2] - expectedColor[2]) <= tolerance &&
     34          Math.abs(color[3] - expectedColor[3]) <= tolerance);
     35 }
     36 
     37 function blitframebuffer_outside_readbuffer(readbufferFormat, drawbufferFormat) {
     38    debug("");
     39    debug("blitting outside of read framebuffer, read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat) + ", draw buffer format is: " + wtu.glEnumToString(gl, drawbufferFormat));
     40 
     41    // Initiate data to read framebuffer
     42    var size_read = 3;
     43    var uint_read = new Uint8Array(size_read * size_read * 4);
     44    var start = 0x20;
     45    for (var ii = 0; ii < size_read * size_read * 4; ii += 4) {
     46        for (var jj = 0; jj < 3; ++jj) {
     47          uint_read[ii + jj] = start;
     48        }
     49        uint_read[ii + 3] = 0xff;
     50        start += 0x10;
     51    }
     52 
     53    // Create read framebuffer and feed data to read buffer
     54    // Read buffer may has srgb image
     55    var tex_read = gl.createTexture();
     56    gl.bindTexture(gl.TEXTURE_2D, tex_read);
     57    gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size_read, size_read, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint_read);
     58 
     59    var fbo_read = gl.createFramebuffer();
     60    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
     61    gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
     62 
     63    // Initiate data to draw framebuffer
     64    var size_draw = 7;
     65    var uint_draw = new Uint8Array(size_draw * size_draw * 4);
     66    for (var ii = 0; ii < size_draw * size_draw * 4; ii += 4) {
     67        for (var jj = 0; jj < 3; ++jj) {
     68            uint_draw[ii + jj] = 0x10;
     69        }
     70        uint_draw[ii + 3] = 0xff;
     71    }
     72 
     73    // Create draw framebuffer and feed data to draw buffer
     74    // Draw buffer may has srgb image
     75    var tex_draw = gl.createTexture();
     76    gl.bindTexture(gl.TEXTURE_2D, tex_draw);
     77    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
     78    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
     79    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
     80    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
     81 
     82    gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size_draw, size_draw, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint_draw);
     83 
     84    var fbo_draw = gl.createFramebuffer();
     85    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
     86    gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_draw, 0);
     87 
     88    if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
     89        var ref = [
     90            // The reference pixels of the 1st line: (0, 0) ~ (6, 0)
     91            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
     92            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
     93 
     94            // The reference pixels of the 2nd line: (0, 1) ~ (6, 1)
     95            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
     96            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
     97 
     98            // The reference pixels of the 3rd line: (0, 2) ~ (6, 2)
     99            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x20, 0x20, 0x20, 0xff], [0x30, 0x30, 0x30, 0xff],
    100            [0x40, 0x40, 0x40, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    101 
    102            // The reference pixels of the 4th line: (0, 3) ~ (6, 3)
    103            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x50, 0x50, 0x50, 0xff], [0x60, 0x60, 0x60, 0xff],
    104            [0x70, 0x70, 0x70, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    105 
    106            // The reference pixels of the 5th line: (0, 4) ~ (6, 4)
    107            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x80, 0x80, 0x80, 0xff], [0x90, 0x90, 0x90, 0xff],
    108            [0xa0, 0xa0, 0xa0, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    109 
    110            // The reference pixels of the 6th line: (0, 5) ~ (6, 5)
    111            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    112            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    113 
    114            // The reference pixels of the 7th line: (0, 6) ~ (6, 6)
    115            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    116            [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff], [0x10, 0x10, 0x10, 0xff],
    117        ];
    118 
    119        // The 1st round test: blit read framebuffer to the image in draw framebuffer
    120        // All directions of the read region have pixels outside of the read buffer
    121        // The src region and/or dst region may be reversed during blitting.
    122        var test1 = [
    123             [-1, 4, 1, 6], // reverse neither src nor dst
    124             [4, -1, 1, 6], // reverse src only
    125             [-1, 4, 6, 1], // reverse dst only
    126             [4, -1, 6, 1]  // reverse both src and dst
    127        ];
    128 
    129        var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8);
    130        var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8);
    131 
    132        for (var i = 0; i < 4; ++i) {
    133            debug("");
    134            switch (i) {
    135                case 0: debug("reverse neither src region nor dst region"); break;
    136                case 1: debug("reverse src region only"); break;
    137                case 2: debug("reverse dst region only"); break;
    138                case 3: debug("reverse both src region and dst region"); break;
    139            }
    140            var srcStart = test1[i][0];
    141            var srcEnd = test1[i][1];
    142            var dstStart = test1[i][2];
    143            var dstEnd = test1[i][3];
    144            var realBlittedDstStart = 2;
    145            var realBlittedDstEnd = 5;
    146            gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
    147            gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
    148            gl.blitFramebuffer(srcStart, srcStart, srcEnd, srcEnd, dstStart, dstStart, dstEnd, dstEnd, gl.COLOR_BUFFER_BIT, gl.LINEAR);
    149 
    150            // Read pixels and check the correctness.
    151            var pixels = new Uint8Array(size_draw * size_draw * 4);
    152            gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
    153            gl.readPixels(0, 0, size_draw, size_draw, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    154 
    155            for (var ii = 0; ii < size_draw; ++ii) {
    156                for (var jj = 0; jj < size_draw; ++jj) {
    157                    var loc = ii * size_draw + jj;
    158                    var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
    159 
    160                    // We may need to reverse the reference loc if necessary
    161                    var ref_loc = loc;
    162                    var reverse_src = (srcStart < srcEnd);
    163                    var reverse_dst = (dstStart < dstEnd);
    164                    var reversed = reverse_src ^ reverse_dst;
    165                    if (reversed) {
    166                        ref_loc = (size_draw - ii - 1) * size_draw + (size_draw - jj -1);
    167                    }
    168                    var expectedColor = ref[ref_loc];
    169 
    170                    // We may need to covert the color space for pixels in blit region
    171                    if ((readbufferHasSRGBImage ^ drawbufferHasSRGBImage) &&
    172                        (ii >= realBlittedDstStart && ii < realBlittedDstEnd && jj >= realBlittedDstStart && jj < realBlittedDstEnd)) {
    173                        if (drawbufferHasSRGBImage) {
    174                            expectedColor = wtu.linearToSRGB(expectedColor);
    175                        } else {
    176                            expectedColor = wtu.sRGBToLinear(expectedColor);
    177                        }
    178                    }
    179                    if (checkPixel(color, expectedColor) == true) {
    180                        testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
    181                    } else {
    182                        testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
    183                    }
    184                }
    185            }
    186        }
    187 
    188        // The 2nd round test: blit read framebuffer to the image in draw framebuffer
    189        // Only one direction of the read region have pixels outside of the read buffer
    190        var tests = [
    191             [-1, 0], // pixels are outside the left edge of the read buffer
    192             [0, -1], // pixels are outside the bottom edge of the read buffer
    193             [1, 0],  // pixels are outside the right edge of the read buffer
    194             [0, 1]   // pixels are outside the top edge of the read buffer
    195        ];
    196        for (var i = 0; i < 4; ++i) {
    197            debug("");
    198            switch (i) {
    199                case 0: debug("verify that pixels lying outside the left edge of the read buffer should remain untouched"); break;
    200                case 1: debug("verify that pixels lying outside the bottom edge of the read buffer should remain untouched"); break;
    201                case 2: debug("verify that pixels lying outside the right edge of the read buffer should remain untouched"); break;
    202                case 3: debug("verify that pixels lying outside the top edge of the read buffer should remain untouched"); break;
    203            }
    204            gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
    205            gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
    206            var srcX = tests[i][0];
    207            var srcY = tests[i][1];
    208            var offset = dstStart - srcStart;
    209            gl.blitFramebuffer(srcX, srcY, srcX + size_read, srcY + size_read,
    210                               srcX + offset, srcY + offset, srcX + offset + size_read, srcY + offset + size_read,
    211                               gl.COLOR_BUFFER_BIT, gl.LINEAR);
    212 
    213            // Read pixels and check the correctness.
    214            var pixels = new Uint8Array(size_draw * size_draw * 4);
    215            gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
    216            gl.readPixels(0, 0, size_draw, size_draw, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    217            for (var ii = srcY + offset; ii < srcY + offset + size_read; ++ii) {
    218                for (var jj = srcX + offset; jj < srcX + offset + size_read; ++jj) {
    219                    var loc = ii * size_draw + jj;
    220                    var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
    221                    var expectedColor = ref[loc];
    222                    // We may need to covert the color space for pixels in blit region
    223                    if ((readbufferHasSRGBImage ^ drawbufferHasSRGBImage) &&
    224                        (ii >= realBlittedDstStart && ii < realBlittedDstEnd && jj >= realBlittedDstStart && jj < realBlittedDstEnd)) {
    225                        if (drawbufferHasSRGBImage) {
    226                            expectedColor = wtu.linearToSRGB(expectedColor);
    227                        } else {
    228                            expectedColor = wtu.sRGBToLinear(expectedColor);
    229                        }
    230                    }
    231                    if (checkPixel(color, expectedColor) == true) {
    232                        testPassed("pixel at [" + jj + ", " + ii + "] is (" + color + "). It is correct!");
    233                    } else {
    234                        testFailed("pixel at [" + jj + ", " + ii + "] should be (" + expectedColor + "), but the actual color is (" + color + ")");
    235                    }
    236                }
    237            }
    238        }
    239    } else {
    240        testFailed("framebuffer not complete");
    241    }
    242 
    243    gl.bindTexture(gl.TEXTURE_2D, null);
    244    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    245    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    246    gl.deleteFramebuffer(fbo_read);
    247    gl.deleteFramebuffer(fbo_draw);
    248    gl.deleteTexture(tex_read);
    249    gl.deleteTexture(tex_draw);
    250 };
    251 
    252 if (!gl) {
    253    testFailed("WebGL context does not exist");
    254 } else {
    255    testPassed("WebGL context exists");
    256    blitframebuffer_outside_readbuffer(gl.RGBA8, gl.RGBA8);
    257    blitframebuffer_outside_readbuffer(gl.RGBA8, gl.SRGB8_ALPHA8);
    258    blitframebuffer_outside_readbuffer(gl.SRGB8_ALPHA8, gl.RGBA8);
    259    blitframebuffer_outside_readbuffer(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8);
    260 }
    261 
    262 var successfullyParsed = true;
    263 </script>
    264 <script src="../../js/js-test-post.js"></script>
    265 
    266 </body>
    267 </html>