﻿<!--

/*
** 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 WebGL_debug_shaders Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 1px; height: 1px;"> </canvas>
<div id="console"></div>
<!-- Shaders for testing standard derivatives -->

<script>
"use strict";
description("This test verifies the functionality of the WEBGL_debug_shaders extension, if it is available.");

debug("");

var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("canvas");
var ext = null;
var shader = null;
var program = null;
var info = null;
var translatedSource;
var newTranslatedSource;

if (!gl) {
    testFailed("WebGL context does not exist");
} else {
    testPassed("WebGL context exists");

    // Query the extension and store globally so shouldBe can access it
    ext = gl.getExtension("WEBGL_debug_shaders");
    if (!ext) {
        testPassed("No WEBGL_debug_shaders support -- this is legal");

        runSupportedTest(false);
    } else {
        testPassed("Successfully enabled WEBGL_debug_shaders extension");

        runSupportedTest(true);
        runTestEnabled();
    }
}

function runSupportedTest(extensionEnabled) {
    var supported = gl.getSupportedExtensions();
    if (supported.indexOf("WEBGL_debug_shaders") >= 0) {
        if (extensionEnabled) {
            testPassed("WEBGL_debug_shaders listed as supported and getExtension succeeded");
        } else {
            testFailed("WEBGL_debug_shaders listed as supported but getExtension failed");
        }
    } else {
        if (extensionEnabled) {
            testFailed("WEBGL_debug_shaders not listed as supported but getExtension succeeded");
        } else {
            testPassed("WEBGL_debug_shaders not listed as supported and getExtension failed -- this is legal");
        }
    }
}

function runTestEnabled() {
    debug("Testing function with extension enabled");

    var shaderInfos = [
      {
        source: "void main() { gl_Position = vec4(1.0, 0.0, 0.0, 1.0); }",
        type: gl.VERTEX_SHADER
      },
      {
        source: "void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }",
        type: gl.FRAGMENT_SHADER
      }
    ];

    // Do this twice to test for caching issues.
    for (var jj = 0; jj < 2; ++jj) {
        debug("pass:" + (jj + 1));
        program = gl.createProgram();
        for (var ii = 0; ii < shaderInfos.length; ++ii) {
            info = shaderInfos[ii];

            shader = gl.createShader(info.type);

            // if no source has been defined or compileShader() has not been called,
            // getTranslatedShaderSource() should return an empty string.
            shouldBe("ext.getTranslatedShaderSource(shader)", '""');
            gl.shaderSource(shader, info.source);
            shouldBe("ext.getTranslatedShaderSource(shader)", '""');
            gl.compileShader(shader);
            shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
            translatedSource = ext.getTranslatedShaderSource(shader);
            wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No gl error should occur");
            if (translatedSource && translatedSource.length > 0) {
                testPassed("Successfully called getTranslatedShaderSource()");
            } else {
                testFailed("Calling getTranslatedShaderSource() failed");
            }
            gl.attachShader(program, shader);
        }
        gl.linkProgram(program);
        shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
    }

    // Test changing the source. Make sure we get the correct source each time.
    debug("test changing source");
    shader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(shader, "void main() { gl_FragColor = vec4(gl_FragCoord.x, 0.0, 0.0, 1.0); }");
    gl.compileShader(shader);
    shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
    shouldThrow("ext.getTranslatedShaderSource(null)");
    translatedSource = ext.getTranslatedShaderSource(shader);
    shouldBeTrue('translatedSource && translatedSource.indexOf("gl_FragCoord") >= 0');
    // change the source but don't compile.
    gl.shaderSource(shader, "void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }");
    // the source should NOT change. It should be the same as the old source.
    newTranslatedSource = ext.getTranslatedShaderSource(shader);
    shouldBe('newTranslatedSource', 'translatedSource');
    // now compile.
    gl.compileShader(shader);
    shouldBeTrue("gl.getShaderParameter(shader, gl.COMPILE_STATUS)");
    // the source should have change.
    newTranslatedSource = ext.getTranslatedShaderSource(shader);
    shouldNotBe('newTranslatedSource', 'translatedSource');
}

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

</body>
</html>
