<!--

/*
** Copyright (c) 2012 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.
*/

-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL DrawingBuffer dimensions on HD-DPI machines test</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vshaderGrid" type="x-shader/x-vertex">
attribute vec4 a_position;
void main()
{
  gl_Position = a_position;
}
</script>

<script id="fshaderGrid" type="x-shader/x-fragment">
precision mediump float;
void main()
{
  float r = mod(gl_FragCoord.x, 2.0) < 1.0 ? 0.0 : 1.0;
  float g = mod(gl_FragCoord.y, 2.0) < 1.0 ? 0.0 : 1.0;
  gl_FragColor = vec4(r, g, 0, 1);
}
</script>
<script>
"use strict";
description();
debug("");

var gl;
var canvas;

function checkDimensions() {
  // We expect that for the sizes being testing drawingBufferWidth and drawingBufferHeight
  // will match canvas.width and canvas.height.

  // We need to test that devicePixelRatio does not effect the backbuffer size of a canvas.
  shouldBe('gl.drawingBufferWidth', 'canvas.width');
  shouldBe('gl.drawingBufferHeight', 'canvas.height');
}

// This uses gl_FragCoord to draw a device pixel relavent pattern.
// If drawBufferWidth or drawBufferHeight are not in device pixels
// this test should fail.
function checkGrid(gl, width, height) {
  var program = wtu.setupProgram(gl, ["vshaderGrid", "fshaderGrid"], ["a_position"]);
  wtu.setupUnitQuad(gl);
  gl.useProgram(program);
  shouldBe('gl.getError()', 'gl.NO_ERROR');

  wtu.clearAndDrawUnitQuad(gl);

  var pixels = new Uint8Array(width * height * 4);
  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

  var colors = [
    [ { color: [0,   0, 0, 255], name: "black" },  { color: [255,   0, 0, 255], name: "red"    } ],
    [ { color: [0, 255, 0, 255], name: "green" },  { color: [255, 255, 0, 255], name: "yellow" } ],
  ];

  for (var yy = 0; yy < height; ++yy) {
    for (var xx = 0; xx < width; ++xx) {
      var info = colors[yy % 2][xx % 2];
      var color = info.color;
      var offset = (yy * width + xx) * 4;
      for (var jj = 0; jj < 4; ++jj) {
        if (pixels[offset + jj] != color[jj]) {
          var actual = [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
          testFailed("at " + xx + ", " + yy + " expected " + color + "(" + info.name + ") was " + actual);
          return;
        }
      }
    }
  }
  testPassed("grid rendered correctly");
}

// This passes device coordinate vertices in to make sure gl.viewport is not being mucked with.
function checkQuad(gl, width, height) {
  var deviceToClipSpace = function(value, range) {
    return value / range * 2 - 1;
  }

  var program = wtu.setupColorQuad(gl);

  // draw a small green square in the top right corner.
  var deviceX1 = width - 4;
  var deviceX2 = width;
  var deviceY1 = height - 4;
  var deviceY2 = height;

  var clipX1 = deviceToClipSpace(deviceX1, width);
  var clipX2 = deviceToClipSpace(deviceX2, width);
  var clipY1 = deviceToClipSpace(deviceY1, height);
  var clipY2 = deviceToClipSpace(deviceY2, height);

  var vertexObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array(
        [ clipX2, clipY2,
          clipX1, clipY2,
          clipX1, clipY1,
          clipX2, clipY2,
          clipX1, clipY1,
          clipX2, clipY1]),
      gl.STATIC_DRAW);
  gl.enableVertexAttribArray(0);
  gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);

  var green = [0, 255, 0, 255];
  var black = [0, 0, 0, 0];
  gl.clearColor(0, 0, 0, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  wtu.drawUByteColorQuad(gl, [0, 255, 0, 255]);

  var squareWidth = deviceX2 - deviceX1;
  var squareHeight = deviceY2 - deviceY1;

  // check the square.
  wtu.checkCanvasRect(gl, deviceX1, deviceY1, squareWidth, squareHeight, green, "should be green");
  // check outside the square.
  wtu.checkCanvasRect(gl, 0, 0, width, height - squareHeight, black, "should be black");
  wtu.checkCanvasRect(gl, 0, height - squareHeight, width - squareWidth, squareHeight, black, "should be black");
}


function test(desiredWidth, desiredHeight) {
  debug("");
  debug("testing canvas width = " + desiredWidth + ", height = " + desiredHeight);

  // Make a fresh canvas.
  canvas = document.createElement("canvas");
  canvas.width = desiredWidth;
  canvas.height = desiredHeight;

  // This 'gl' must be global for shouldBe to work.
  gl = wtu.create3DContext(canvas, {antialias: false});
  if (!gl) {
    testFailed("context does not exist");
  } else {
    testPassed("context exists");

    // Check the dimensions are correct.
    checkDimensions();

    // Draw a pixel grid using a shader that draws in device coordinates
    checkGrid(gl, desiredWidth, desiredHeight);

    // Draw a quad in the top right corner.
    checkQuad(gl, desiredWidth, desiredHeight);

    shouldBe('gl.getError()', 'gl.NO_ERROR');

    debug("");
    debug("testing resizing canvas to width = " + desiredWidth + ", height = " + desiredHeight);

    var oldViewport = gl.getParameter(gl.VIEWPORT);

    // flip width and height
    canvas.width = desiredHeight;
    canvas.height = desiredWidth;

    // fix the viewport
    gl.viewport(0, 0, desiredHeight, desiredWidth);

    // Check the dimensions are correct.
    checkDimensions();

    // Draw a pixel grid using a shader that draws in device coordinates
    checkGrid(gl, desiredHeight, desiredWidth);

    // Draw a quad in the top right corner.
    checkQuad(gl, desiredHeight, desiredWidth);

    shouldBe('gl.getError()', 'gl.NO_ERROR');
  }
}

var wtu = WebGLTestUtils;

// test a few sizes
test(32, 16);
test(128, 64);
test(256, 512);

debug("")
var successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
