/*
** Copyright (c) 2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/

'use strict';
description("Verifies that lines, both aliased and antialiased, have acceptable quality.");

let wtu = WebGLTestUtils;
let gl;

let aa_fbo;

function setupWebGL1Test(canvasId, useAntialiasing) {
  gl = wtu.create3DContext(canvasId, { antialias: useAntialiasing }, contextVersion);
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors during WebGL 1.0 setup");
}

function setupWebGL2Test(canvasId, useAntialiasing) {
  gl = wtu.create3DContext(canvasId, { antialias: false }, contextVersion);
  // In WebGL 2.0, we always allocate the back buffer without
  // antialiasing. The only question is whether we allocate a
  // framebuffer with a multisampled renderbuffer attachment.
  aa_fbo = null;
  if (useAntialiasing) {
    aa_fbo = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, aa_fbo);
    let rb = gl.createRenderbuffer();
    gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
    let supported = gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES);
    // Prefer 4, then 8, then max.
    let preferred = [4, 8];
    let allocated = false;
    for (let value of preferred) {
      if (supported.indexOf(value) >= 0) {
        gl.renderbufferStorageMultisample(gl.RENDERBUFFER, value, gl.RGBA8,
                                          gl.drawingBufferWidth, gl.drawingBufferHeight);
        allocated = true;
        break;
      }
    }
    if (!allocated) {
      gl.renderbufferStorageMultisample(gl.RENDERBUFFER, supported[supported.length - 1],
                                        gl.RGBA8, gl.drawingBufferWidth, gl.drawingBufferHeight);
    }
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
  }
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors during WebGL 2.0 setup");
}

function setupLines() {
  let prog = wtu.setupSimpleColorProgram(gl, 0);
  let loc = gl.getUniformLocation(prog, 'u_color');
  if (loc == null) {
    testFailed('Failed to fetch color uniform');
  }
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of line program");
  gl.uniform4f(loc, 1.0, 1.0, 1.0, 1.0);
  let buffer = gl.createBuffer();
  let scale = 0.5;
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    -scale, -scale, 0.0, 1.0,
    -scale, scale, 0.0, 1.0,
    scale, scale, 0.0, 1.0,
    scale, -scale, 0.0, 1.0,
    -scale, -scale, 0.0, 1.0,
  ]), gl.STATIC_DRAW);
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of buffer");
  gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(0);
  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "After setup of attribute array");
}

function renderLines(contextVersion, useAntialiasing) {
  gl.clearColor(0.0, 0.0, 0.5, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.LINE_STRIP, 0, 5);
  if (contextVersion == 2 && useAntialiasing) {
    // Blit aa_fbo into the real back buffer.
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, aa_fbo);
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    let w = gl.drawingBufferWidth;
    let h = gl.drawingBufferHeight;
    gl.blitFramebuffer(0, 0, w, h,
                       0, 0, w, h,
                       gl.COLOR_BUFFER_BIT, gl.NEAREST);
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  }
}

function pixelAboveThreshold(arr, pixelIndex, threshold) {
  return (arr[4 * pixelIndex + 0] >= threshold &&
          arr[4 * pixelIndex + 1] >= threshold &&
          arr[4 * pixelIndex + 2] >= threshold &&
          arr[4 * pixelIndex + 3] >= threshold);
}

function checkLine(arr, threshold, direction) {
  // Count number of crossings from below threshold to above (or equal
  // to) threshold. Must be equal to 2.

  let numPixels = arr.length / 4;
  let numUpCrossings = 0;
  let numDownCrossings = 0;
  for (let index = 0; index < numPixels - 1; ++index) {
    let curPixel = pixelAboveThreshold(arr, index, threshold);
    let nextPixel = pixelAboveThreshold(arr, index + 1, threshold);
    if (!curPixel && nextPixel) {
      ++numUpCrossings;
    } else if (curPixel && !nextPixel) {
      ++numDownCrossings;
    }
  }
  if (numUpCrossings != numDownCrossings) {
    testFailed('Found differing numbers of up->down and down->up transitions');
  }
  if (numUpCrossings == 2) {
    testPassed('Found 2 lines, looking in the ' + direction + ' direction');
  } else {
    testFailed('Found ' + numUpCrossings + ' lines, looking in the ' +
               direction + ' direction, expected 2');
  }
}

function checkResults() {
  // Check the middle horizontal and middle vertical line of the canvas.
  let w = gl.drawingBufferWidth;
  let h = gl.drawingBufferHeight;
  let t = 100;
  let arr = new Uint8Array(4 * w);
  gl.readPixels(0, Math.floor(h / 2),
                w, 1, gl.RGBA, gl.UNSIGNED_BYTE, arr);
  checkLine(arr, t, 'horizontal');
  arr = new Uint8Array(4 * h);
  gl.readPixels(Math.floor(w / 2), 0,
                1, h, gl.RGBA, gl.UNSIGNED_BYTE, arr);
  checkLine(arr, t, 'vertical');
}

function runTest(contextVersion, canvasId, useAntialiasing) {
  switch (contextVersion) {
    case 1: {
      setupWebGL1Test(canvasId, useAntialiasing);
      break;
    }
    case 2: {
      setupWebGL2Test(canvasId, useAntialiasing);
    }
  }
  setupLines();
  renderLines(contextVersion, useAntialiasing);
  checkResults();
}

function runTests() {
  runTest(contextVersion, 'testbed', false);
  runTest(contextVersion, 'testbed2', true);
}

runTests();
let successfullyParsed = true;
