<!--

/*
** 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 Big FBO Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../../devtools/src/debug/webgl-debug.js"></script>
<script src="../js/js-test-pre.js"></script>
<script src="../js/webgl-test-utils.js"></script>
</head>
<body>
<canvas id="canvas" width="256" height="256"> </canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
varying vec2 texCoord;
void main()
{
  gl_Position = vec4(vPosition.xyz, 1.0);
  texCoord = texCoord0;
}
</script>

<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
  gl_FragColor = texture2D(tex, texCoord);
}
</script>
<script>
"use strict";
window.onload = init;

var g_textures = [];

debug("Tests the performance of using lots of large FBOs");

function init() {
  if (confirm(
      "After clicking OK your machine may become unresponsive or crash.")) {
    main();
  } else {
    debug("cancelled");
  }
}

function checkFBOStatus(gl) {
  var err = gl.getError();
  if (err != gl.NO_ERROR) {
    if (err != gl.OUT_OF_MEMORY)
      testFailed("gl.getError returned " + err);
    else
      testPassed("OUT-OF-MEMORY");
    return false;
  }
  var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
  if (status != gl.FRAMEBUFFER_COMPLETE) {
    testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status));
    return false;
  }
  return true;
}

function setupFBO(gl, size) {
  var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  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);

  var fb = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);

  gl.texImage2D(gl.TEXTURE_2D,
                0,                 // level
                gl.RGBA,           // internalFormat
                size,              // width
                size,              // height
                0,                 // border
                gl.RGBA,           // format
                gl.UNSIGNED_BYTE,  // type
                null);             // data
  if (!checkFBOStatus(gl))
    return null;

  return { fb: fb, tex: tex };
}

function checkPixels(gl) {
  var width = 256;
  var height = 256;

  var thresh = 3;

  var buf = new Uint8Array(width * height * 4);
  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
  for (var yy = 0; yy < height; ++yy) {
    for (var xx = 0; xx < width; ++xx) {
      var offset = (yy * width + xx) * 4;
      if (Math.abs(buf[offset] - 255) > thresh ||
          Math.abs(buf[offset + 1] - 0) > thresh ||
          Math.abs(buf[offset + 2] - 0) > thresh) {
        testFailed("drawing results incorrect");
        return false;
      }
    }
  }
  return true;
}

function handleContextLost() {
  debug("context lost");
}

function main() {
  debug("");
  debug("Checking for out of memory handling.");

  var canvas = document.getElementById("canvas");
  canvas.addEventListener('webglcontextlost', handleContextLost);
  var wtu = WebGLTestUtils;
  var gl = wtu.create3DContext("canvas");
  var prog = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition", "texCoord0"]);

  WebGLDebugUtils.init(gl);

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

  var vertexObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    -1,1,0, 1,1,0, -1,-1,0,
    -1,-1,0, 1,1,0, 1,-1,0
  ]), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(0);
  gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);

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

  var texLoc = gl.getUniformLocation(prog, "tex");
  gl.uniform1i(texLoc, 0);

  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);

  wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup should succeed");

  var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
  debug("max render buffer size: " + size +
        ", size used: " + (size / 2));
  size /= 2;

  var maxFBOs = 200;
  var numFBOs = 0;
  allocateNextFBO();

  function allocateNextFBO() {
    if (numFBOs >= maxFBOs) {
      phase2();
      return;
    }
    if (!allocateFBO()) {
      phase2();
      return;
    }
    ++numFBOs;
    setTimeout(allocateNextFBO, 100);
  }

  function allocateFBO() {
    debug("");
    debug("trying to create fbo #" + (numFBOs + 1));
    var t = setupFBO(gl, 2);
    if (!t) {
      return false;
    }

    var tex = t.tex;
    var fb = t.fb;

    debug("allocating fbo color buffer of size " + size + " x " + size);
    gl.texImage2D(gl.TEXTURE_2D,
                  0,                 // level
                  gl.RGBA,           // internalFormat
                  size,              // width
                  size,              // height
                  0,                 // border
                  gl.RGBA,           // format
                  gl.UNSIGNED_BYTE,  // type
                  null);             // data
    if (!checkFBOStatus(gl)) {
      return false;
    }
    g_textures.push(tex);
    debug("succeeded in creating fbo");

    debug("clearing the fbo with red color");
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    gl.clearColor(1, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);

    debug("deleting fbo, but the now red texture should be untouched");
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    gl.deleteFramebuffer(fb);

    debug("drawing to the canvas using the red texture");
    gl.clearColor(0, 0, 0, 1);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
    if (!checkPixels(gl)) {
      return false;
    }

    debug("succeeded in drawing");
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "each run with no error");
    return true;
  }

  function phase2() {
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);

    debug("");
    debug("fbos allocated:" + numFBOs);
    if (!checkPixels(gl)) {
      testFailed("final check of canvas drawing buffer pixels failed");
    }
    debug("");
    finishTest();
  }
}

var successfullyParsed = true;
</script>

</body>
</html>
