﻿<!--

/*
** 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 OES_standard_derivatives 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: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<!-- Shaders for testing standard derivatives -->

<!-- Shader omitting the required #extension pragma -->
<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 texCoord;
void main() {
    float dx = dFdx(texCoord.x);
    float dy = dFdy(texCoord.y);
    float w = fwidth(texCoord.x);
    gl_FragColor = vec4(dx, dy, w, 1.0);
}
</script>

<!-- Shader to test macro definition -->
<script id="macroFragmentShader" type="x-shader/x-fragment">
precision mediump float;
void main() {
#ifdef GL_OES_standard_derivatives
    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
#else
    // Error expected
    #error no GL_OES_standard_derivatives;
#endif
}
</script>

<!-- Shader with required #extension pragma -->
<script id="testFragmentShader" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
precision mediump float;
varying vec2 texCoord;
void main() {
    float dx = dFdx(texCoord.x);
    float dy = dFdy(texCoord.y);
    float w = fwidth(texCoord.x);
    gl_FragColor = vec4(dx, dy, w, 1.0);
}
</script>
<!-- Shaders to link with test fragment shaders -->
<script id="goodVertexShader" type="x-shader/x-vertex">
attribute vec4 vPosition;
varying vec2 texCoord;
void main() {
    texCoord = vPosition.xy;
    gl_Position = vPosition;
}
</script>
<!-- Shaders to test output -->
<script id="outputVertexShader" type="x-shader/x-vertex">
attribute vec4 vPosition;
varying vec4 position;
void main() {
    position = vPosition;
    gl_Position = vPosition;
}
</script>
<script id="outputFragmentShader" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
precision mediump float;
varying vec4 position;
void main() {
    float dzdx = dFdx(position.z);
    float dzdy = dFdy(position.z);
    float fw = fwidth(position.z);
    gl_FragColor = vec4(abs(dzdx) * 40.0, abs(dzdy) * 40.0, fw * 40.0, 1.0);
}
</script>

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

debug("");

var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas);
var ext = null;

// Run all tests once.
runAllTests();

// Run all tests against with a new context to test for any cache issues.
debug("");
debug("Testing new context to catch cache errors");
gl = wtu.create3DContext();
ext = null;
runAllTests();

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

        // Run tests with extension disabled
        runHintTestDisabled();
        runShaderTests(false);

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

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

            runSupportedTest(true);

            runHintTestEnabled();
            runShaderTests(true);
            runOutputTests();
            runUniqueObjectTest();

            // Run deferred link tests.
            runDeferredLinkTests();
        }
    }

}

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

function runHintTestDisabled() {
    debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension disabled");

    // Use the constant directly as we don't have the extension
    var FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;

    gl.getParameter(FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES should not be queryable if extension is disabled");

    gl.hint(FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
    wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "hint should not accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES if extension is disabled");
}

function runHintTestEnabled() {
    debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension enabled");

    shouldBe("ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES", "0x8B8B");

    gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES query should succeed if extension is enabled");

    // Default value is DONT_CARE
    if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) == gl.DONT_CARE) {
        testPassed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is DONT_CARE");
    } else {
        testFailed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is not DONT_CARE");
    }

    // Ensure that we can set the target
    gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "hint should accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES");

    // Test all the hint modes
    var validModes = ["FASTEST", "NICEST", "DONT_CARE"];
    var anyFailed = false;
    for (var n = 0; n < validModes.length; n++) {
        var mode = validModes[n];
        gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl[mode]);
        if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) != gl[mode]) {
            testFailed("Round-trip of hint()/getParameter() failed on mode " + mode);
            anyFailed = true;
        }
    }
    if (!anyFailed) {
        testPassed("Round-trip of hint()/getParameter() with all supported modes");
    }
}

function runShaderTests(extensionEnabled) {
    debug("");
    debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));

    // Expect the macro shader to succeed ONLY if enabled
    var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
    if (extensionEnabled) {
        if (macroFragmentProgram) {
            // Expected result
            testPassed("GL_OES_standard_derivatives defined in shaders when extension is enabled");
        } else {
            testFailed("GL_OES_standard_derivatives not defined in shaders when extension is enabled");
        }
    } else {
        if (macroFragmentProgram) {
            testFailed("GL_OES_standard_derivatives defined in shaders when extension is disabled");
        } else {
            testPassed("GL_OES_standard_derivatives not defined in shaders when extension disabled");
        }
    }

    // Always expect the shader missing the #pragma to fail (whether enabled or not)
    var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
    if (missingPragmaFragmentProgram) {
        testFailed("Shader built-ins allowed without #extension pragma");
    } else {
        testPassed("Shader built-ins disallowed without #extension pragma");
    }

    // Try to compile a shader using the built-ins that should only succeed if enabled
    var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
    if (extensionEnabled) {
        if (testFragmentProgram) {
            testPassed("Shader built-ins compiled successfully when extension enabled");
        } else {
            testFailed("Shader built-ins failed to compile when extension enabled");
        }
    } else {
        if (testFragmentProgram) {
            testFailed("Shader built-ins compiled successfully when extension disabled");
        } else {
            testPassed("Shader built-ins failed to compile when extension disabled");
        }
    }
}

function runOutputTests() {
    // This tests does several draws with various values of z.
    // The output of the fragment shader is:
    // [dFdx(z), dFdy(z), fwidth(z), 1.0]
    // The expected math: (note the conversion to uint8)
    //    canvas.width = canvas.height = 50
    //    dFdx = totalChange.x / canvas.width  = 0.5 / 50.0 = 0.01
    //    dFdy = totalChange.y / canvas.height = 0.5 / 50.0 = 0.01
    //    fw = abs(dFdx + dFdy) = 0.01 + 0.01 = 0.02
    //    r = floor(dFdx * 40.0 * 255) = 102
    //    g = floor(dFdy * 40.0 * 255) = 102
    //    b = floor(fw * 40.0 * 255) = 204

    var e = 5; // Amount of variance to allow in result pixels - may need to be tweaked higher

    debug("Testing various draws for valid built-in function behavior");

    canvas.width = 50; canvas.height = 50;
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST);

    var positionLoc = 0;
    var texcoordLoc = 1;
    var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
    var quadParameters = wtu.setupUnitQuad(gl, positionLoc, texcoordLoc);

    function expectResult(target, message) {
        var locations = [
            [ 0.1, 0.1 ],
            [ 0.9, 0.1 ],
            [ 0.1, 0.9 ],
            [ 0.9, 0.9 ],
            [ 0.5, 0.5 ]
        ];
        for (var n = 0; n < locations.length; n++) {
            var loc = locations[n];
            var px = Math.floor(loc[0] * canvas.width);
            var py = Math.floor(loc[1] * canvas.height);
            wtu.checkCanvasRect(gl, px, py, 1, 1, target, message, 4);
        }
    };

    function setupBuffers(tl, tr, bl, br) {
        gl.bindBuffer(gl.ARRAY_BUFFER, quadParameters[0]);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
           1.0,  1.0, tr,
          -1.0,  1.0, tl,
          -1.0, -1.0, bl,
           1.0,  1.0, tr,
          -1.0, -1.0, bl,
           1.0, -1.0, br]), gl.STATIC_DRAW);
        gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
    };

    // Draw 1: (no variation)
    setupBuffers(0.0, 0.0, 0.0, 0.0);
    wtu.clearAndDrawUnitQuad(gl);
    expectResult([0, 0, 0, 255],
                 "Draw 1 (no variation) should pass");

    // Draw 2: (variation in x)
    setupBuffers(1.0, 0.0, 1.0, 0.0);
    wtu.clearAndDrawUnitQuad(gl);
    expectResult([204, 0, 204, 255],
                 "Draw 2 (variation in x) should pass");

    // Draw 3: (variation in y)
    setupBuffers(1.0, 1.0, 0.0, 0.0);
    wtu.clearAndDrawUnitQuad(gl);
    expectResult([0, 204, 204, 255],
                 "Draw 3 (variation in y) should pass");

    // Draw 4: (variation in x & y)
    setupBuffers(1.0, 0.5, 0.5, 0.0);
    wtu.clearAndDrawUnitQuad(gl);
    expectResult([102, 102, 204, 255],
                 "Draw 4 (variation in x & y) should pass");
}

function runUniqueObjectTest()
{
    debug("Testing that getExtension() returns the same object each time");
    ext = null;
    gl.getExtension("OES_standard_derivatives").myProperty = 2;
    webglHarnessCollectGarbage();
    shouldBe('gl.getExtension("OES_standard_derivatives").myProperty', '2');
}

function runDeferredLinkTests() {
    debug("");
    debug("Testing deferred shader compilation tests.");

    // Test for compilation failures that are caused by missing extensions
    // do not succeed if extensions are enabled during linking. This would
    // only happen for deferred shader compilations.

    // First test if link succeeds with extension enabled.
    var glEnabled = wtu.create3DContext();
    var extEnabled = glEnabled.getExtension("OES_standard_derivatives");
    if (!extEnabled) {
        testFailed("Deferred link test expects the extension to be supported");
    }

    var vertexShader = wtu.loadShaderFromScript(glEnabled, "goodVertexShader");
    var fragmentShader = wtu.loadShaderFromScript(glEnabled, "macroFragmentShader");

    if (!vertexShader || !fragmentShader) {
        testFailed("Could not create good shaders.");
        return;
    }

    var program = wtu.setupProgram(glEnabled, [vertexShader, fragmentShader]);

    if (!program) {
        testFailed("Compilation with extension enabled failed.");
        return;
    }

    // Create new context to test link failure without extension enabled.
    var glDeferred = wtu.create3DContext();

    var vertexShader = wtu.loadShaderFromScript(glDeferred, "goodVertexShader", glDeferred.VERTEX_SHADER, undefined, undefined, true);
    var fragmentShader = wtu.loadShaderFromScript(glDeferred, "macroFragmentShader", glDeferred.FRAGMENT_SHADER, undefined, undefined, true);

    if (vertexShader == null || fragmentShader == null) {
        testFailed("Could not create shaders.");
        return;
    }

    // Shader compilations should have failed due to extensions not enabled.
    glDeferred.getExtension("OES_standard_derivatives");
    var program = wtu.setupProgram(glDeferred, [vertexShader, fragmentShader]);
    if (program) {
        testFailed("Compilation with extension disabled then linking with extension enabled should have failed.");
        return;
    }

    testPassed("Compilation with extension disabled then linking with extension enabled.");
}

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

</body>
</html>
