tor-browser

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

line-rendering-quality.js (5614B)


      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 description("Verifies that lines, both aliased and antialiased, have acceptable quality.");
      9 
     10 let wtu = WebGLTestUtils;
     11 let gl;
     12 
     13 let aa_fbo;
     14 
     15 function setupWebGL1Test(canvasId, useAntialiasing) {
     16  gl = wtu.create3DContext(canvasId, { antialias: useAntialiasing }, contextVersion);
     17  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors during WebGL 1.0 setup");
     18 }
     19 
     20 function setupWebGL2Test(canvasId, useAntialiasing) {
     21  gl = wtu.create3DContext(canvasId, { antialias: false }, contextVersion);
     22  // In WebGL 2.0, we always allocate the back buffer without
     23  // antialiasing. The only question is whether we allocate a
     24  // framebuffer with a multisampled renderbuffer attachment.
     25  aa_fbo = null;
     26  if (useAntialiasing) {
     27    aa_fbo = gl.createFramebuffer();
     28    gl.bindFramebuffer(gl.FRAMEBUFFER, aa_fbo);
     29    let rb = gl.createRenderbuffer();
     30    gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
     31    let supported = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES);
     32    // Prefer 4, then 8, then max.
     33    let preferred = [4, 8];
     34    let allocated = false;
     35    for (let value of preferred) {
     36      if (supported.indexOf(value) >= 0) {
     37        gl.renderbufferStorageMultisample(gl.RENDERBUFFER, value, gl.RGBA8,
     38                                          gl.drawingBufferWidth, gl.drawingBufferHeight);
     39        allocated = true;
     40        break;
     41      }
     42    }
     43    if (!allocated) {
     44      gl.renderbufferStorageMultisample(gl.RENDERBUFFER, supported[supported.length - 1],
     45                                        gl.RGBA8, gl.drawingBufferWidth, gl.drawingBufferHeight);
     46    }
     47    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
     48  }
     49  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors during WebGL 2.0 setup");
     50 }
     51 
     52 function setupLines() {
     53  let prog = wtu.setupSimpleColorProgram(gl, 0);
     54  let loc = gl.getUniformLocation(prog, 'u_color');
     55  if (loc == null) {
     56    testFailed('Failed to fetch color uniform');
     57  }
     58  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of line program");
     59  gl.uniform4f(loc, 1.0, 1.0, 1.0, 1.0);
     60  let buffer = gl.createBuffer();
     61  let scale = 0.5;
     62  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
     63  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
     64    -scale, -scale, 0.0, 1.0,
     65    -scale, scale, 0.0, 1.0,
     66    scale, scale, 0.0, 1.0,
     67    scale, -scale, 0.0, 1.0,
     68    -scale, -scale, 0.0, 1.0,
     69  ]), gl.STATIC_DRAW);
     70  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of buffer");
     71  gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
     72  gl.enableVertexAttribArray(0);
     73  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of attribute array");
     74 }
     75 
     76 function renderLines(contextVersion, useAntialiasing) {
     77  gl.clearColor(0.0, 0.0, 0.5, 1.0);
     78  gl.clear(gl.COLOR_BUFFER_BIT);
     79  gl.drawArrays(gl.LINE_STRIP, 0, 5);
     80  if (contextVersion == 2 && useAntialiasing) {
     81    // Blit aa_fbo into the real back buffer.
     82    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, aa_fbo);
     83    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
     84    let w = gl.drawingBufferWidth;
     85    let h = gl.drawingBufferHeight;
     86    gl.blitFramebuffer(0, 0, w, h,
     87                       0, 0, w, h,
     88                       gl.COLOR_BUFFER_BIT, gl.NEAREST);
     89    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
     90  }
     91 }
     92 
     93 function pixelAboveThreshold(arr, pixelIndex, threshold) {
     94  return (arr[4 * pixelIndex + 0] >= threshold &&
     95          arr[4 * pixelIndex + 1] >= threshold &&
     96          arr[4 * pixelIndex + 2] >= threshold &&
     97          arr[4 * pixelIndex + 3] >= threshold);
     98 }
     99 
    100 function checkLine(arr, threshold, direction) {
    101  // Count number of crossings from below threshold to above (or equal
    102  // to) threshold. Must be equal to 2.
    103 
    104  let numPixels = arr.length / 4;
    105  let numUpCrossings = 0;
    106  let numDownCrossings = 0;
    107  for (let index = 0; index < numPixels - 1; ++index) {
    108    let curPixel = pixelAboveThreshold(arr, index, threshold);
    109    let nextPixel = pixelAboveThreshold(arr, index + 1, threshold);
    110    if (!curPixel && nextPixel) {
    111      ++numUpCrossings;
    112    } else if (curPixel && !nextPixel) {
    113      ++numDownCrossings;
    114    }
    115  }
    116  if (numUpCrossings != numDownCrossings) {
    117    testFailed('Found differing numbers of up->down and down->up transitions');
    118  }
    119  if (numUpCrossings == 2) {
    120    testPassed('Found 2 lines, looking in the ' + direction + ' direction');
    121  } else {
    122    testFailed('Found ' + numUpCrossings + ' lines, looking in the ' +
    123               direction + ' direction, expected 2');
    124  }
    125 }
    126 
    127 function checkResults() {
    128  // Check the middle horizontal and middle vertical line of the canvas.
    129  let w = gl.drawingBufferWidth;
    130  let h = gl.drawingBufferHeight;
    131  let t = 100;
    132  let arr = new Uint8Array(4 * w);
    133  gl.readPixels(0, Math.floor(h / 2),
    134                w, 1, gl.RGBA, gl.UNSIGNED_BYTE, arr);
    135  checkLine(arr, t, 'horizontal');
    136  arr = new Uint8Array(4 * h);
    137  gl.readPixels(Math.floor(w / 2), 0,
    138                1, h, gl.RGBA, gl.UNSIGNED_BYTE, arr);
    139  checkLine(arr, t, 'vertical');
    140 }
    141 
    142 function runTest(contextVersion, canvasId, useAntialiasing) {
    143  switch (contextVersion) {
    144    case 1: {
    145      setupWebGL1Test(canvasId, useAntialiasing);
    146      break;
    147    }
    148    case 2: {
    149      setupWebGL2Test(canvasId, useAntialiasing);
    150    }
    151  }
    152  setupLines();
    153  renderLines(contextVersion, useAntialiasing);
    154  checkResults();
    155 }
    156 
    157 function runTests() {
    158  runTest(contextVersion, 'testbed', false);
    159  runTest(contextVersion, 'testbed2', true);
    160 }
    161 
    162 runTests();
    163 let successfullyParsed = true;