<!--

/*
** 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 Out Of Memory Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="../conformance/resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<script>
"use strict";
debug("This tests WebGL running out of memory.");

debug("");
debug("Canvas.getContext");

var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("canvas");
if (!gl) {
  testFailed("context does not exist");
} else {
  testPassed("context exists");

  debug("");
  debug("Allocating shaders.");

  function makeBigShader() {
    var lines = [];
    var line = "// ";
    for (var ii = 0; ii < 1024; ++ii) {
      line += String.fromCharCode(48 + ii % 10);
    }
    for (var ii = 0; ii < 1024; ++ii) {
      lines[ii] = line;
    }
    var oneMB = lines.join();
    for (var ii = 0; ii < 64; ++ii) {
      lines[ii] = oneMB;
    }
    return lines.join("\n");
  }

  var shaderSource = makeBigShader();
  debug("created " + Math.floor(shaderSource.length / 1024 / 1024) + "MB shader");

  var intervalId;
  var count = 0;

  function makeShader() {
    ++count;
    debug ("creating shader #" + count + " mem = " + Math.floor(shaderSource.length * count / 1024 / 1024) + "MB");
    var shader = gl.createShader(gl.VERTEX_SHADER);
    if (shader == null) {
      window.clearInterval(intervalId);
      testPassed("createShader returns null");  // not sure this is a passing
      finish();
    } else {
      gl.shaderSource(shader, shaderSource);
      var err = gl.getError();
      if (err != gl.NO_ERROR) {
        window.clearInterval(intervalId);
        assertMsg(err == gl.OUT_OF_MEMORY, "shaderSource returns OUT_OF_MEMORY");
        finish();
      }
    }
  }

  intervalId = window.setInterval(makeShader, 1000/15);
}

function finish() {
  debug("");
  var successfullyParsed = true;
}

</script>
<!-- <script src="../resources/js-test-post.js"></script> -->

<script>
"use strict";
</script>

</body>
</html>
