tor-browser

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

blitframebuffer-srgb-and-linear-drawbuffers.html (9445B)


      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="canvas" 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 with multiple draw buffers (srgb image and linear image).");
     26 
     27 var gl = wtu.create3DContext("canvas", undefined, 2);
     28 var linearMask = 1;
     29 var srgbMask = 2;
     30 
     31 if (!gl) {
     32    testFailed("WebGL context does not exist");
     33 } else {
     34    testPassed("WebGL context exists");
     35 
     36    var filters = [gl.LINEAR, gl.NEAREST];
     37    var drawbuffersFormats = [linearMask, srgbMask, linearMask | srgbMask];
     38    for (var ii = 0; ii < filters.length; ++ii) {
     39        for (var jj = 0; jj < drawbuffersFormats.length; ++jj) {
     40            blitframebuffer_srgb_and_linear_drawbuffers(gl.SRGB8_ALPHA8, drawbuffersFormats[jj], filters[ii]);
     41            blitframebuffer_srgb_and_linear_drawbuffers(gl.RGBA8, drawbuffersFormats[jj], filters[ii]);
     42        }
     43    }
     44 }
     45 
     46 function blitframebuffer_srgb_and_linear_drawbuffers(readbufferFormat, drawbuffersFormatMask, filter) {
     47    debug("");
     48    debug("The filter is: " + wtu.glEnumToString(gl, filter));
     49    debug("Read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat));
     50    var drawbuffersFormat = "\0";
     51    if (drawbuffersFormatMask & linearMask) {
     52        drawbuffersFormat += " linear ";
     53    }
     54    if (drawbuffersFormatMask & srgbMask) {
     55        drawbuffersFormat += " srgb ";
     56    }
     57    debug("The test have multiple draw buffers, the images are: " + drawbuffersFormat);
     58 
     59    var tex_srgb0 = gl.createTexture();
     60    var tex_srgb1 = gl.createTexture();
     61    var tex_linear0 = gl.createTexture();
     62    var tex_linear1 = gl.createTexture();
     63    var tex_read = gl.createTexture();
     64    var fbo_read = gl.createFramebuffer();
     65    var fbo_draw = gl.createFramebuffer();
     66 
     67    // Create read buffer and feed data to the read buffer
     68    var size = 8;
     69    var data = new Uint8Array(size * size * 4);
     70    var color = [250, 100, 15, 255];
     71    for (var ii = 0; ii < size * size * 4; ii += 4) {
     72        for (var jj = 0; jj < 4; ++jj) {
     73          data[ii + jj] = color[jj];
     74        }
     75    }
     76    gl.bindTexture(gl.TEXTURE_2D, tex_read);
     77    gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
     78    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
     79    gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
     80    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup read framebuffer should succeed");
     81 
     82    // Create multiple textures. Attach them as fbo's draw buffers.
     83    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
     84 
     85    var drawbuffers = [gl.NONE, gl.NONE, gl.NONE, gl.NONE];
     86    if (drawbuffersFormatMask & srgbMask) {
     87        gl.bindTexture(gl.TEXTURE_2D, tex_srgb0);
     88        gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     89        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_srgb0, 0);
     90        gl.bindTexture(gl.TEXTURE_2D, tex_srgb1);
     91        gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
     92        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, tex_srgb1, 0);
     93        drawbuffers[0] = gl.COLOR_ATTACHMENT0;
     94        drawbuffers[2] = gl.COLOR_ATTACHMENT2;
     95    }
     96 
     97    if (drawbuffersFormatMask & linearMask) {
     98        gl.bindTexture(gl.TEXTURE_2D, tex_linear0);
     99        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    100        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex_linear0, 0);
    101        gl.bindTexture(gl.TEXTURE_2D, tex_linear1);
    102        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    103        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.TEXTURE_2D, tex_linear1, 0);
    104        drawbuffers[1] = gl.COLOR_ATTACHMENT1;
    105        drawbuffers[3] = gl.COLOR_ATTACHMENT3;
    106    }
    107 
    108    gl.drawBuffers(drawbuffers);
    109    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup draw framebuffer should succeed");
    110 
    111    if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
    112        gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
    113        testFailed("Framebuffer incomplete when setup draw framebuffer.");
    114        return;
    115    }
    116 
    117    // Blit to multiple draw buffers with srgb images and linear images
    118    var dstSize = size - 1;
    119    gl.blitFramebuffer(0, 0, size, size, 0, 0, dstSize, dstSize, gl.COLOR_BUFFER_BIT, filter);
    120    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitframebuffer should succeed");
    121 
    122    // Read pixels from srgb images and linear images
    123    var srgbPixels0 = new Uint8Array(dstSize * dstSize * 4);
    124    var srgbPixels1 = new Uint8Array(dstSize * dstSize * 4);
    125    var linearPixels0 = new Uint8Array(dstSize * dstSize * 4);
    126    var linearPixels1 = new Uint8Array(dstSize * dstSize * 4);
    127    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
    128    if (drawbuffersFormatMask & srgbMask) {
    129        gl.readBuffer(gl.COLOR_ATTACHMENT0);
    130        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels0);
    131        gl.readBuffer(gl.COLOR_ATTACHMENT2);
    132        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels1);
    133    }
    134 
    135    if (drawbuffersFormatMask & linearMask) {
    136        gl.readBuffer(gl.COLOR_ATTACHMENT1);
    137        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels0);
    138        gl.readBuffer(gl.COLOR_ATTACHMENT3);
    139        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels1);
    140    }
    141    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixels should succeed");
    142 
    143    // Compare
    144    var expectedSRGBColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? color : wtu.linearToSRGB(color);
    145    var expectedLinearColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? wtu.sRGBToLinear(color) : color;
    146    var failed = false;
    147    for (var ii = 0; ii < dstSize; ++ii) {
    148        for (var jj = 0; jj < dstSize; ++jj) {
    149            var index = (ii * dstSize + jj) * 4;
    150            if (drawbuffersFormatMask & srgbMask) {
    151                var srgbColor0 = [srgbPixels0[index], srgbPixels0[index + 1], srgbPixels0[index + 2], srgbPixels0[index + 3]];
    152                if (checkPixel(srgbColor0, expectedSRGBColor) == false) {
    153                    failed = true;
    154                    debug("Pixels comparison failed for the 1st sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor0 + ")");
    155                }
    156                var srgbColor1 = [srgbPixels1[index], srgbPixels1[index + 1], srgbPixels1[index + 2], srgbPixels1[index + 3]];
    157                if (checkPixel(srgbColor1, expectedSRGBColor) == false) {
    158                    failed = true;
    159                    debug("Pixels comparison failed for the 2nd sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor1 + ")");
    160                }
    161            }
    162 
    163            if (drawbuffersFormatMask & linearMask) {
    164                var linearColor0 = [linearPixels0[index], linearPixels0[index + 1], linearPixels0[index + 2], linearPixels0[index + 3]];
    165                if (checkPixel(linearColor0, expectedLinearColor) == false) {
    166                    failed = true;
    167                    debug("Pixel comparison failed for the 1st linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor0 + ")");
    168                }
    169                var linearColor1 = [linearPixels1[index], linearPixels1[index + 1], linearPixels1[index + 2], linearPixels1[index + 3]];
    170                if (checkPixel(linearColor1, expectedLinearColor) == false) {
    171                    failed = true;
    172                    debug("Pixel comparison failed for the 2nd linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor1 + ")");
    173                }
    174            }
    175        }
    176    }
    177    if (failed == false) {
    178        testPassed("All pixels comparision passed!");
    179    }
    180 
    181    // deinit
    182    gl.bindTexture(gl.TEXTURE_2D, null);
    183    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    184    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    185    gl.deleteTexture(tex_srgb0);
    186    gl.deleteTexture(tex_linear0);
    187    gl.deleteTexture(tex_srgb1);
    188    gl.deleteTexture(tex_linear1);
    189    gl.deleteTexture(tex_read);
    190    gl.deleteFramebuffer(fbo_read);
    191    gl.deleteFramebuffer(fbo_draw);
    192 }
    193 
    194 function checkPixel(color, expectedColor) {
    195  var tolerance = 3;
    196  return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
    197          Math.abs(color[1] - expectedColor[1]) <= tolerance &&
    198          Math.abs(color[2] - expectedColor[2]) <= tolerance &&
    199          Math.abs(color[3] - expectedColor[3]) <= tolerance);
    200 }
    201 
    202 var successfullyParsed = true;
    203 </script>
    204 <script src="../../js/js-test-post.js"></script>
    205 
    206 </body>
    207 </html>