<!DOCTYPE html>
<html>
<head>
<title>texImage2D with ImageBitmap.</title>
<script src="../../../resources/js-test.js"></script>
<script src="resources/webgl-test.js"> </script>
<script src="resources/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="example"></canvas>
<div id="description"></div>
<script>
function loadImage(url) {
  return new Promise((resolve, reject) => {
    var img = document.createElement('img');
    img.onload = () => resolve(img);
    img.onerror = e => reject(e);
    img.src = url;
  });
}

function checkPixel(buf, width, x, y, color, tolerance) {
  function msgFailed() {
    return "pixel " + x + ", " + y + " should be " +
            color[0] + ", " +
            color[1] + ", " +
            color[2] + ", " +
            color[3] + " was " +
            buf[off + 0] + ", " +
            buf[off + 1] + ", " +
            buf[off + 2] + ", " +
            buf[off + 3];
  }
  function msgPassed() {
    return "pixel " + x + ", " + y + " was " +
            color[0] + ", " +
            color[1] + ", " +
            color[2] + ", " +
            color[3];
  }
  var off = (y * width + x) * 4;
  for (var ii = 0; ii < 4; ++ii) {
    var delta = Math.abs(buf[off + ii] - color[ii]);
    if (delta > tolerance) {
      testFailed(msgFailed());
      return;
    }
  }
  testPassed(msgPassed());
}

function checkPixelRange(buf, width, x, y, color, allowedRange) {
  var off = (y * width + x) * 4;
  var msg = "pixel " + x + ", " + y + " should be within " +
            allowedRange + " units of " +
            color[0] + ", " +
            color[1] + ", " +
            color[2] + ", " +
            color[3];
  var subMsg = " was " +
            buf[off + 0] + ", " +
            buf[off + 1] + ", " +
            buf[off + 2] + ", " +
            buf[off + 3];
  // When running in WebKit's test harness, we don't want to print the
  // pixel value when the test passes, because different machines might
  // have different results and we record the text output.
  var inDumpRenderTree = window.testRunner;
  for (var ii = 0; ii < 4; ++ii) {
    if (Math.abs(buf[off + ii] - color[ii]) > allowedRange) {
      testFailed(msg + subMsg);
      return;
    }
  }
  testPassed(msg + (inDumpRenderTree ? "" : subMsg));
}

async function test() {
  var wtu = WebGLTestUtils;
  var canvas = document.getElementById("example");
  var gl = wtu.create3DContext(canvas);
  var program = wtu.setupTexturedQuad(gl);

  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");

  var img = await loadImage('resources/3x3.png');

  var loc = gl.getUniformLocation(program, "tex");
  gl.uniform1i(loc, 0);

  gl.disable(gl.BLEND);
  gl.disable(gl.DEPTH_TEST);

  var width = canvas.width;
  var height = canvas.height;

  var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

  var bitmap = await createImageBitmap(img);

  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
                bitmap);
  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
  wtu.drawQuad(gl);

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

  var tolerance = 1;
  var left = 0;
  var middle = Math.floor(width / 2);
  var right = width - 1;
  var bottom = 0;
  var center = Math.floor(height / 2);
  var top = height - 1;
  checkPixel(buf, width, left,   top,    [  0,   0,   0, 255]);
  checkPixel(buf, width, middle, top,    [  0,   0, 255, 255]);
  checkPixel(buf, width, right,  top,    [255,   0,   0, 255]);
  checkPixel(buf, width, left,   center, [255,   0, 255, 255]);
  checkPixel(buf, width, middle, center, [255,   0,   0, 255]);
  checkPixel(buf, width, right,  center, [  0, 255,   0, 255], tolerance);
  checkPixel(buf, width, left,   bottom, [255,   0,   0, 255]);
  checkPixel(buf, width, middle, bottom, [255, 255,   0, 255]);
  checkPixel(buf, width, right,  bottom, [255,   0,   0, 255]);
}

window.testRunner.waitUntilDone();
test().then(() => {
  window.testRunner.notifyDone();
}, e => {
  testFailed(String(e));
});
</script>
