tor-browser

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

multisampling-fragment-evaluation.html (5654B)


      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 multisampling fragment shader evaluation</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 
     16 <script id="vshader" type="x-shader/x-vertex">#version 300 es
     17 layout(location=0) in vec4 aPosition;
     18 out vec4 vPosition;
     19 void main()
     20 {
     21    gl_Position = vec4(aPosition);
     22    vPosition = aPosition;
     23 }
     24 </script>
     25 <script id="fshader" type="x-shader/x-fragment">#version 300 es
     26 precision highp float;
     27 in vec4 vPosition;
     28 layout(location=0) out vec4 oColor;
     29 void main()
     30 {
     31    if (vPosition.x < 0.0) {
     32        oColor = vec4(1, 0, 0, 1);
     33    } else if (vPosition.y < 0.0) {
     34        oColor = vec4(0, 1, 0, 1);
     35    } else {
     36        oColor = vec4(0, 0, 1, 1);
     37    }
     38 }
     39 </script>
     40 
     41 </head>
     42 <body>
     43 <div id="description"></div>
     44 <div id="console"></div>
     45 
     46 <script>
     47 "use strict";
     48 
     49 var wtu = WebGLTestUtils;
     50 description("Verify that fragment shader is evaluated only once per framebuffer pixel when multisampling is used.");
     51 
     52 // GLES 3.0.5 section 3.6.3. Polygon Multisample Rasterization:
     53 // "Polygon rasterization produces a fragment for each framebuffer pixel with one or more sample points that satisfy
     54 // the point sampling criteria described in section 3.6.1."
     55 
     56 debug("Regression test for <a href='http://crbug.com/682815'>http://crbug.com/682815</a>");
     57 
     58 function runTest(testParams) {
     59    let canvas = document.createElement('canvas');
     60    canvas.width = 1;
     61    canvas.height = 1;
     62    let gl = wtu.create3DContext(canvas, {antialias: false}, 2);
     63 
     64    // Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
     65    let samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
     66    if (!samples || !samples.length) {
     67        testFailed("Could not query supported sample counts for required multisampling format " + testParams.internalformat);
     68        return;
     69    }
     70 
     71    // Note that supported sample counts are required to be reported in descending order.
     72    debug('Testing with sample count ' + samples[0]);
     73    // Create a framebuffer with a multisampled renderbuffer with the maximum supported number of samples.
     74    let rb = gl.createRenderbuffer();
     75    gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
     76    gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[0], gl[testParams.internalformat], 1, 1);
     77    let fb = gl.createFramebuffer();
     78    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
     79    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
     80    if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
     81        testFailed("Rendering to a multisampled renderbuffer of format " + testParams.internalformat + " is required.");
     82        return;
     83    }
     84 
     85    // Create a program that will choose between one of different possible colors in the fragment shader.
     86    // It should be evaluated only once per framebuffer pixel, so only one of the colors will end up in the framebuffer.
     87    // However, if the multisampling mode is incorrectly implemented by supersampling, the samples may have different
     88    // colors.
     89    let program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"]);
     90 
     91    // Render one triangle using the program. The triangle needs to extend far outside the viewport on all sides, so
     92    // that we can safely assume all samples fall inside the triangle. GLES 3.0.5:
     93    // "The sample points associated with a pixel may be located inside or outside of the unit square that is considered to bound the pixel."
     94    // Here we assume that sample points are less than 9999 pixels away from the pixel they are associated with.
     95    let buffer = gl.createBuffer();
     96    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
     97    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 10000,  30000,
     98                                                     -30000, -10000,
     99                                                      10000, -10000]), gl.STATIC_DRAW);
    100    gl.enableVertexAttribArray(0);
    101    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
    102    gl.drawArrays(gl.TRIANGLES, 0, 3);
    103 
    104    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    105    gl.blitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, gl.COLOR_BUFFER_BIT, gl.NEAREST);
    106    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    107 
    108    let readBuffer = new Uint8Array(4);
    109    gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer);
    110 
    111    // Check that the canvas is one of the colors that the fragment shader may generate, and not a blend of them.
    112    let possibleColors = [
    113        [255, 0, 0, 255],
    114        [0, 255, 0, 255],
    115        [0, 0, 255, 255]
    116    ];
    117    let anyColorMatched = false;
    118    for (let i = 0; i < possibleColors.length; ++i) {
    119        let colorMatched = true;
    120        for (let j = 0; j < 4; ++j) {
    121            if (Math.abs(readBuffer[j] - possibleColors[i][j]) > 2) {
    122                colorMatched = false;
    123            }
    124        }
    125        if (colorMatched) {
    126            anyColorMatched = true;
    127        }
    128    }
    129    if (!anyColorMatched) {
    130        testFailed("Color in framebuffer was not one of the colors generated by the fragment shader: " + readBuffer);
    131    } else {
    132        testPassed("Color in framebuffer was one of the colors generated by the fragment shader: " + readBuffer);
    133    }
    134 }
    135 
    136 runTest({internalformat: 'RGBA8'});
    137 
    138 var successfullyParsed = true;
    139 </script>
    140 <script src="../../js/js-test-post.js"></script>
    141 
    142 </body>
    143 </html>