tor-browser

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

webgl-render-shared-exponent.html (8745B)


      1 <!--
      2 Copyright (c) 2023 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 WEBGL_render_shared_exponent 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 </head>
     16 <body>
     17 <div id="description"></div>
     18 <div id="console"></div>
     19 <script>
     20 "use strict";
     21 description("This test verifies the functionality of the WEBGL_render_shared_exponent extension, if it is available.");
     22 
     23 debug("");
     24 
     25 var wtu = WebGLTestUtils;
     26 var gl = wtu.create3DContext(null, null, 2);
     27 var ext;
     28 const color = [64.0, 32.0, 16.0, 1.0];
     29 
     30 function drawTest() {
     31    wtu.clearAndDrawUnitQuad(gl);
     32 
     33    wtu.checkCanvasRect(gl, 0, 0, 1, 1, color,
     34                        "reading with the RGBA format and FLOAT type", 1,
     35                        new Float32Array(4), gl.FLOAT, gl.RGBA);
     36 
     37    const implementationType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
     38    const implementationFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
     39    if (implementationFormat == gl.RGB && implementationType == gl.UNSIGNED_INT_5_9_9_9_REV) {
     40        // Shared exponent value may be implementation
     41        // specific, so compare decoded values.
     42        const value = new Uint32Array(1);
     43        gl.readPixels(0, 0, 1, 1, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, value);
     44        wtu.glErrorShouldBe(gl, gl.NO_ERROR);
     45 
     46        let r = (value >>  0) & 0x1FF;
     47        let g = (value >>  9) & 0x1FF;
     48        let b = (value >> 18) & 0x1FF;
     49        let e = (value >> 27) & 0x01F;
     50        debug(`Raw value: 0x${value[0].toString(16).toUpperCase()}, ` +
     51              `Raw components: R = ${r}, G = ${g}, B = ${b}, E = ${e}`);
     52 
     53        e = Math.pow(2, e - 24);
     54        r *= e;
     55        g *= e;
     56        b *= e;
     57        debug(`Decoded color: (${r}, ${g}, ${b})`);
     58 
     59        if (r == color[0] && g == color[1] && b == color[2]) {
     60            testPassed("reading with the exact format/type");
     61        } else {
     62            testFailed("reading with the exact format/type");
     63        }
     64    }
     65 }
     66 
     67 function renderbufferTest(isSupported) {
     68    debug("");
     69    debug(`RGB9_E5 renderbuffer: ` +
     70          `${!isSupported ? "NOT " : ""}supported`);
     71 
     72    const rbo = gl.createRenderbuffer();
     73    gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
     74    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 1, 1);
     75    if (!isSupported) {
     76        wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "renderbuffer allocation failed");
     77        return;
     78    }
     79    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "renderbuffer allocation succeeded");
     80 
     81    const fbo = gl.createFramebuffer();
     82    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
     83    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
     84 
     85    wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
     86 
     87    drawTest();
     88 }
     89 
     90 function textureTest(isRenderable) {
     91    debug("");
     92    debug(`RGB9_E5 texture: ` +
     93          `${!isRenderable ? "NOT " : ""}renderable`);
     94 
     95    const tex = gl.createTexture();
     96    gl.bindTexture(gl.TEXTURE_2D, tex);
     97    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB9_E5, 1, 1, 0, gl.RGB, gl.UNSIGNED_INT_5_9_9_9_REV, null);
     98    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture allocation succeeded");
     99 
    100    const fbo = gl.createFramebuffer();
    101    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    102    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
    103 
    104    if (!isRenderable) {
    105        wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
    106        return;
    107    }
    108    wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
    109 
    110    drawTest();
    111 }
    112 
    113 function formatTest(isEnabled) {
    114    const program = wtu.setupProgram(gl, [wtu.simpleVertexShader,
    115                                          wtu.simpleColorFragmentShader]);
    116    gl.useProgram(program);
    117    gl.uniform4fv(gl.getUniformLocation(program, "u_color"), color);
    118 
    119    wtu.setupUnitQuad(gl);
    120 
    121    renderbufferTest(isEnabled);
    122    textureTest(isEnabled);
    123 }
    124 
    125 function colorMaskTest() {
    126    debug("");
    127    debug("Test color write masks with shared exponent color buffers");
    128 
    129    const fs = `#version 300 es
    130        precision highp float;
    131        layout(location = 0) out vec4 color0;
    132        layout(location = 1) out vec4 color1;
    133        void main() {
    134            color0 = vec4(1.0, 0.0, 0.0, 1.0);
    135            color1 = vec4(0.0, 1.0, 0.0, 1.0);
    136        }`;
    137    const program = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, fs]);
    138    gl.useProgram(program);
    139 
    140    const fbo = gl.createFramebuffer();
    141    gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
    142 
    143    const rb0 = gl.createRenderbuffer();
    144    gl.bindRenderbuffer(gl.RENDERBUFFER, rb0);
    145    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB9_E5, 4, 4);
    146    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb0);
    147 
    148    const rb1 = gl.createRenderbuffer();
    149    gl.bindRenderbuffer(gl.RENDERBUFFER, rb1);
    150    gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 4, 4);
    151    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, rb1);
    152 
    153    wtu.glErrorShouldBe(gl, gl.NO_ERROR);
    154    wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE);
    155 
    156    const clearValue = new Float32Array(4);
    157    const dbiExt = gl.getExtension("OES_draw_buffers_indexed");
    158 
    159    function expectError(enabled, effectiveMask, operation) {
    160        if (!enabled ||
    161            effectiveMask == 0x0 /* 0000 */ ||
    162            effectiveMask == 0x8 /* 000A */ ||
    163            effectiveMask == 0x7 /* RGB0 */ ||
    164            effectiveMask == 0xF /* RGBA */ ) {
    165            wtu.glErrorShouldBe(gl, gl.NO_ERROR, operation);
    166        } else {
    167            wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, operation);
    168        }
    169    }
    170 
    171    function runOps(enabled, mask0) {
    172        wtu.drawUnitQuad(gl);
    173        expectError(enabled, mask0, "draw");
    174 
    175        gl.clear(gl.COLOR_BUFFER_BIT);
    176        expectError(enabled, mask0, "clear");
    177 
    178        gl.clearBufferfv(gl.COLOR, 0, clearValue);
    179        expectError(enabled, mask0, "clearBufferfv(RGB9_E5)");
    180        gl.clearBufferfv(gl.COLOR, 1, clearValue);
    181        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearBufferfv(RGBA8)");
    182    }
    183 
    184    for (let mask = 0; mask < 16; mask++) {
    185        for (const enabled of [false, true]) {
    186            debug("");
    187            debug(`Setting common color mask ` +
    188                  `${mask & 1 ? "R" : "0"}` +
    189                  `${mask & 2 ? "G" : "0"}` +
    190                  `${mask & 4 ? "B" : "0"}` +
    191                  `${mask & 8 ? "A" : "0"}` +
    192                  " with RGB9_E5 attachment " +
    193                  (enabled ? "enabled" : "disabled"));
    194            gl.colorMask(mask & 1, mask & 2, mask & 4, mask & 8);
    195            gl.drawBuffers([enabled ? gl.COLOR_ATTACHMENT0 : gl.NONE,
    196                            gl.COLOR_ATTACHMENT1]);
    197 
    198            runOps(enabled, mask);
    199 
    200            if (dbiExt) {
    201                debug("Setting incompatible color mask on unused draw buffer")
    202                dbiExt.colorMaskiOES(2, true, false, false, false);
    203                runOps(enabled, mask); // common mask remains on draw buffer 0
    204 
    205                debug("Setting incompatible color mask on RGBA8 draw buffer")
    206                dbiExt.colorMaskiOES(1, true, false, false, false);
    207                runOps(enabled, mask); // common mask remains on draw buffer 0
    208 
    209                debug("Setting incompatible color mask on RGB9_E5 draw buffer")
    210                dbiExt.colorMaskiOES(0, true, false, false, false);
    211                runOps(enabled, 1); // overridden
    212 
    213                debug("Setting compatible color mask on RGB9_E5 draw buffer")
    214                dbiExt.colorMaskiOES(0, true, true, true, false);
    215                runOps(enabled, 7); // overridden
    216            }
    217        }
    218    }
    219 }
    220 
    221 function runTest() {
    222    if (!gl) {
    223        testFailed("context does not exist");
    224        return;
    225    }
    226    testPassed("context exists");
    227 
    228    debug("");
    229    debug("Testing shared exponent rendering with extension disabled");
    230    formatTest(false);
    231 
    232    ext = gl.getExtension("WEBGL_render_shared_exponent");
    233    wtu.runExtensionSupportedTest(gl, "WEBGL_render_shared_exponent", ext !== null);
    234 
    235    if (ext !== null) {
    236        debug("");
    237        debug("Testing shared exponent rendering with extension enabled");
    238        formatTest(true);
    239        colorMaskTest();
    240    } else {
    241        testPassed("No WEBGL_render_shared_exponent support -- this is legal");
    242    }
    243 }
    244 
    245 runTest();
    246 
    247 var successfullyParsed = true;
    248 </script>
    249 <script src="../../js/js-test-post.js"></script>
    250 </body>
    251 </html>