<!--

/*
** Copyright (c) 2014 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 Rendering Feedback Loop</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>
    <canvas id="example" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
    <div id="description"></div>
    <div id="console"></div>

    <script id="vs" type="text/something-not-javascript">
    attribute vec4 a_position;
    attribute vec2 a_texCoord;
    varying vec2 v_texCoord;
    void main() {
        gl_Position = a_position;
        v_texCoord = a_texCoord;
    }
    </script>
    <script id="fs" type="text/something-not-javascript">
    precision mediump float;
    varying vec2 v_texCoord;
    uniform sampler2D u_texture;
    void main() {
        // Shader swizzles color channels so we can tell if the draw succeeded.
        gl_FragColor = texture2D(u_texture, v_texCoord).gbra;
    }
    </script>
    <script>
    "use strict";
    description("Checks that rendering feedback loops fail correctly.");
    var wtu = WebGLTestUtils;
    var gl = wtu.create3DContext("example");

    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
                  new Uint8Array([255, 0, 0, 255]));
    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);

    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture");

    var framebuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);

    assertMsg(gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE,
        "framebuffer should be FRAMEBUFFER_COMPLETE.");

    var program = wtu.setupProgram(gl, ["vs", "fs"], ["a_position", "a_texCoord"]);
    gl.uniform1i(gl.getUniformLocation(program, "u_texture"), 0);
    gl.disable(gl.BLEND);
    gl.disable(gl.DEPTH_TEST);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after initWebGL");

    // Drawing with a texture that is also bound to the current framebuffer should fail
    var bufferObjects = wtu.setupUnitQuad(gl, 0, 1);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    wtu.drawUnitQuad(gl);
    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "after draw with invalid feedback loop");

    // Ensure that the texture contents did not change after the previous render
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    wtu.clearAndDrawUnitQuad(gl);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
    wtu.checkCanvas(gl, [0, 0, 255, 255], "Should be blue.");

    // Drawing when texture is bound to an inactive uniform should succeed
    var texture2 = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture2);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
                  new Uint8Array([0, 255, 0, 255]));
    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);

    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    wtu.drawUnitQuad(gl);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after draw where framebuffer texture is bound to inactive texture unit");
    wtu.checkCanvas(gl, [255, 0, 0, 255], "Should be red.");

    var successfullyParsed = true;
    </script>

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

  </body>
</html>
