tor-browser

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

ovr_multiview2_util.js (9584B)


      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 "use strict";
      8 
      9 function createTextureWithNearestFiltering(target)
     10 {
     11    let texture = gl.createTexture();
     12    gl.bindTexture(target, texture);
     13    gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
     14    gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
     15    gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
     16    gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
     17    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed");
     18    return texture;
     19 }
     20 
     21 // Write a transformation matrix to elements of floatArray starting from index.
     22 // The matrix transforms a unit square (-1 to 1) to a rectangle with the width scaleX and the left edge at offsetX.
     23 function setupTranslateAndScaleXMatrix(floatArray, index, scaleX, offsetX)
     24 {
     25    // x position is transformed according to this equation: scaleX * x0 + translateX = offsetX
     26    // By substituting x0 with -1 (unit square x value for the left edge), we get the following:
     27    let translateX = offsetX + scaleX;
     28 
     29    floatArray[index] = scaleX;
     30    floatArray[index + 1] = 0.0;
     31    floatArray[index + 2] = 0.0;
     32    floatArray[index + 3] = 0.0;
     33 
     34    floatArray[index + 4] = 0.0;
     35    floatArray[index + 5] = 1.0;
     36    floatArray[index + 6] = 0.0;
     37    floatArray[index + 7] = 0.0;
     38 
     39    floatArray[index + 8] = 0.0;
     40    floatArray[index + 9] = 0.0;
     41    floatArray[index + 10] = 1.0;
     42    floatArray[index + 11] = 0.0;
     43 
     44    floatArray[index + 12] = translateX;
     45    floatArray[index + 13] = 0.0;
     46    floatArray[index + 14] = 0.0;
     47    floatArray[index + 15] = 1.0;
     48 }
     49 
     50 // Check the currently bound read framebuffer with dimensions <width> x <height>.
     51 // The framebuffer should be divided into <strips> equally wide vertical strips, with the one indicated by
     52 // <coloredStripIndex> colored with <expectedStripColor>. The rest of the framebuffer should be colored transparent black.
     53 // A two pixel wide region at each edge of the colored region is left unchecked to allow for some tolerance for rasterization.
     54 function checkVerticalStrip(width, height, strips, coloredStripIndex, expectedStripColor, framebufferDescription)
     55 {
     56    let colorRegionLeftEdge = (width / strips) * coloredStripIndex;
     57    let colorRegionRightEdge = (width / strips) * (coloredStripIndex + 1);
     58    if (coloredStripIndex > 0) {
     59        wtu.checkCanvasRect(gl, 0, 0, colorRegionLeftEdge - 1, height, [0, 0, 0, 0], 'the left edge of ' + framebufferDescription + ' should be untouched');
     60    }
     61    if (coloredStripIndex < strips - 1) {
     62        wtu.checkCanvasRect(gl, colorRegionRightEdge + 1, 0, width - colorRegionRightEdge - 1, height, [0, 0, 0, 0], 'the right edge of ' + framebufferDescription + ' should be untouched');
     63    }
     64    wtu.checkCanvasRect(gl, colorRegionLeftEdge + 1, 0, colorRegionRightEdge - colorRegionLeftEdge - 2, height, expectedStripColor, 'a thin strip in ' + framebufferDescription + ' should be colored ' + expectedStripColor);
     65 }
     66 
     67 function getMultiviewPassthroughVertexShader(views) {
     68    let shaderCode = ['#version 300 es',
     69    '#extension GL_OVR_multiview2 : require',
     70 
     71    'layout(num_views = $(num_views)) in;',
     72 
     73    'in vec4 a_position;',
     74 
     75    'void main() {',
     76    '    gl_Position = a_position;',
     77    '}'].join('\n');
     78    return wtu.replaceParams(shaderCode, {'num_views': views});
     79 }
     80 
     81 // This shader splits the viewport into <views> equally sized vertical strips.
     82 // The input quad defined by "a_position" is transformed to fill a different
     83 // strip in each view.
     84 function getMultiviewOffsetVertexShader(views) {
     85    let shaderCode = ['#version 300 es',
     86    '#extension GL_OVR_multiview2 : require',
     87 
     88    'layout(num_views = $(num_views)) in;',
     89 
     90    'in vec4 a_position;',
     91 
     92    'void main() {',
     93    '    vec4 pos = a_position;',
     94    "    // Transform the quad to a thin vertical strip that's offset along the x axis according to the view id.",
     95    '    pos.x = (pos.x * 0.5 + 0.5 + float(gl_ViewID_OVR)) * 2.0 / $(num_views).0 - 1.0;',
     96    '    gl_Position = pos;',
     97    '}'].join('\n');
     98    return wtu.replaceParams(shaderCode, {'num_views': views});
     99 }
    100 
    101 // This shader transforms the incoming "a_position" with transforms for each
    102 // view given in the uniform array "transform".
    103 function getMultiviewRealisticUseCaseVertexShader(views) {
    104    let shaderCode = ['#version 300 es',
    105    '#extension GL_OVR_multiview2 : require',
    106 
    107    'layout(num_views = $(num_views)) in;',
    108 
    109    'uniform mat4 transform[$(num_views)];',
    110    'in vec4 a_position;',
    111 
    112    'void main() {',
    113    "    // Transform the quad with the transformation matrix chosen according to gl_ViewID_OVR.",
    114    '    vec4 pos = transform[gl_ViewID_OVR] * a_position;',
    115    '    gl_Position = pos;',
    116    '}'].join('\n');
    117    return wtu.replaceParams(shaderCode, {'num_views': views});
    118 }
    119 
    120 function getMultiviewColorFragmentShader() {
    121    return ['#version 300 es',
    122    '#extension GL_OVR_multiview2 : require',
    123    'precision highp float;',
    124 
    125    'out vec4 my_FragColor;',
    126 
    127    'void main() {',
    128    '    uint mask = gl_ViewID_OVR + 1u;',
    129    '    my_FragColor = vec4(((mask & 4u) != 0u) ? 1.0 : 0.0,',
    130    '                        ((mask & 2u) != 0u) ? 1.0 : 0.0,',
    131    '                        ((mask & 1u) != 0u) ? 1.0 : 0.0,',
    132    '                        1.0);',
    133    '}'].join('\n');
    134 }
    135 
    136 function getMultiviewColorFragmentShaderForDrawBuffers(drawBuffers) {
    137    let shaderCode = ['#version 300 es',
    138    '#extension GL_OVR_multiview2 : require',
    139    'precision highp float;',
    140 
    141    'out vec4 my_FragColor[$(drawBuffers)];',
    142 
    143    'void main() {',
    144    '    uint mask;'];
    145 
    146    for (let i = 0; i < drawBuffers; ++i) {
    147        shaderCode.push(wtu.replaceParams('    mask = gl_ViewID_OVR + $(i)u;', {'i': i + 1}));
    148        shaderCode.push(wtu.replaceParams('    my_FragColor[$(i)] = vec4(((mask & 4u) != 0u) ? 1.0 : 0.0,', {'i': i}));
    149        shaderCode.push('                           ((mask & 2u) != 0u) ? 1.0 : 0.0,');
    150        shaderCode.push('                           ((mask & 1u) != 0u) ? 1.0 : 0.0,');
    151        shaderCode.push('                           1.0);');
    152    }
    153    shaderCode.push('}');
    154    shaderCode = shaderCode.join('\n');
    155    return wtu.replaceParams(shaderCode, {'drawBuffers' : drawBuffers});
    156 }
    157 
    158 function getMultiviewVaryingVertexShader(views) {
    159    let shaderCode = ['#version 300 es',
    160    '#extension GL_OVR_multiview2 : require',
    161 
    162    'layout(num_views = $(num_views)) in;',
    163 
    164    'in vec4 a_position;',
    165    'out float testVarying;',
    166 
    167    'void main() {',
    168    '    gl_Position = a_position;',
    169    '    testVarying = float(gl_ViewID_OVR);',
    170    '}'].join('\n');
    171    return wtu.replaceParams(shaderCode, {'num_views': views});
    172 }
    173 
    174 function getMultiviewVaryingFragmentShader() {
    175    return ['#version 300 es',
    176    '#extension GL_OVR_multiview2 : require',
    177    'precision highp float;',
    178 
    179    'in float testVarying;',
    180    'out vec4 my_FragColor;',
    181 
    182    'void main() {',
    183    '    int mask = int(testVarying + 0.1) + 1;',
    184    '    my_FragColor = vec4(((mask & 4) != 0) ? 1.0 : 0.0,',
    185    '                        ((mask & 2) != 0) ? 1.0 : 0.0,',
    186    '                        ((mask & 1) != 0) ? 1.0 : 0.0,',
    187    '                        1.0);',
    188    '}'].join('\n');
    189 }
    190 
    191 function getMultiviewFlatVaryingVertexShader(views) {
    192    let shaderCode = ['#version 300 es',
    193    '#extension GL_OVR_multiview2 : require',
    194 
    195    'layout(num_views = $(num_views)) in;',
    196 
    197    'in vec4 a_position;',
    198    'flat out int testVarying;',
    199 
    200    'void main() {',
    201    '    gl_Position = a_position;',
    202    '    testVarying = int(gl_ViewID_OVR);',
    203    '}'].join('\n');
    204    return wtu.replaceParams(shaderCode, {'num_views': views});
    205 }
    206 
    207 function getMultiviewFlatVaryingFragmentShader() {
    208    return ['#version 300 es',
    209    '#extension GL_OVR_multiview2 : require',
    210    'precision highp float;',
    211 
    212    'flat in int testVarying;',
    213    'out vec4 my_FragColor;',
    214 
    215    'void main() {',
    216    '    int mask = testVarying + 1;',
    217    '    my_FragColor = vec4(((mask & 4) != 0) ? 1.0 : 0.0,',
    218    '                        ((mask & 2) != 0) ? 1.0 : 0.0,',
    219    '                        ((mask & 1) != 0) ? 1.0 : 0.0,',
    220    '                        1.0);',
    221    '}'].join('\n');
    222 }
    223 
    224 function getMultiviewInstancedVertexShader(views) {
    225    let shaderCode = ['#version 300 es',
    226    '#extension GL_OVR_multiview2 : require',
    227 
    228    'layout(num_views = $(num_views)) in;',
    229 
    230    'in vec4 a_position;',
    231    'out vec4 color;',
    232 
    233    'void main() {',
    234    '    vec4 pos = a_position;',
    235    "    // Transform the quad to a thin vertical strip that's offset along the x axis according to the view id and instance id.",
    236    '    pos.x = (pos.x * 0.5 + 0.5 + float(gl_ViewID_OVR) + float(gl_InstanceID)) * 2.0 / ($(num_views).0 * 2.0) - 1.0;',
    237    '    int mask = gl_InstanceID + 1;',
    238    '    color = vec4(((mask & 4) != 0) ? 1.0 : 0.0,',
    239    '                 ((mask & 2) != 0) ? 1.0 : 0.0,',
    240    '                 ((mask & 1) != 0) ? 1.0 : 0.0,',
    241    '                 1.0);',
    242    '    gl_Position = pos;',
    243    '}'].join('\n');
    244    return wtu.replaceParams(shaderCode, {'num_views': views});
    245 }
    246 
    247 function getInstanceColorFragmentShader() {
    248    return ['#version 300 es',
    249    '#extension GL_OVR_multiview2 : require',
    250    'precision highp float;',
    251 
    252    'in vec4 color;',
    253    'out vec4 my_FragColor;',
    254 
    255    'void main() {',
    256    '    my_FragColor = color;',
    257    '}'].join('\n');
    258 }
    259 
    260 function getExpectedColor(view) {
    261    var mask = (view + 1);
    262    return [(mask & 4) ? 255 : 0, (mask & 2) ? 255 : 0, (mask & 1) ? 255 : 0, 255];
    263 }