<!--

/*
** Copyright (c) 2013 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_texture_half_float Conformance Tests</title>
<script src="resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../../resources/js-test.js"></script>
<script src="resources/webgl-test.js"></script>
<script src="resources/webgl-test-utils.js"></script></head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<canvas id="canvas2d" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script id="testFragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
uniform vec4 subtractor;
varying vec2 texCoord;
void main()
{
    vec4 color = texture2D(tex, texCoord);
    if (abs(color.r - subtractor.r) +
        abs(color.g - subtractor.g) +
        abs(color.b - subtractor.b) +
        abs(color.a - subtractor.a) < 8.0) {
        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    } else {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
}
</script>
<!-- Shaders for testing half-floating-point render targets -->
<script id="positionVertexShader" type="x-shader/x-vertex">
attribute vec4 vPosition;
void main()
{
    gl_Position = vPosition;
}
</script>
<script id="floatingPointFragmentShader" type="x-shader/x-fragment">
void main()
{
    gl_FragColor = vec4(10000.0, 10000.0, 10000.0, 10000.0);
}
</script>
<script>
if (window.testRunner)
    window.testRunner.dumpAsText();

"use strict"
description("This test verifies the functionality of OES_texture_half_float with null/non-null ArrayBufferView");

debug("");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var colorCanvas = document.getElementById("canvas2d");
colorCanvas.width = 2;
colorCanvas.height = 2;
var ctx = colorCanvas.getContext("2d");
ctx.fillStyle = "rgb(255,0,0)";
ctx.fillRect(0, 0, 2, 2);
var gl = wtu.create3DContext(canvas);
// This constant must be defined in order to run the texture creation test without the extension enabled.
var halfFloatOESEnum = 0x8D61;
var ext = null;

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

    // Verify that allocation of texture fails if extension is not enabled
    runTextureCreationTest(false);
    ext = gl.getExtension("OES_texture_half_float")
    if (!ext) {
        testPassed("No OES_texture_half_float support. This is legal");
    } else {
        testPassed("Successfully enabled OES_texture_half_float extension");

        var program = wtu.setupTexturedQuad(gl);

        // Check if creation of texture succeed's with various formats and null ArrayBufferView
        var formats = [
          { format: gl.RGBA,            expected: [255,   0,   0, 255], },
          { format: gl.RGB,             expected: [255,   0,   0, 255], },
          { format: gl.LUMINANCE,       expected: [255, 255, 255, 255], },
          { format: gl.ALPHA,           expected: [  0,   0,   0, 255], },
          { format: gl.LUMINANCE_ALPHA, expected: [255, 255, 255, 255], },
        ];
        formats.forEach(function(f) {
            runTextureCreationTest(true, f.format, null, f.expected);
        });
        
        // Texture creation should fail when passed with non-null, non-Uint16 ArrayBufferView
        formats.forEach(function(f) {
            var width = 2;
            var height = 2;
            var format = f.format;
            
            // Float32Array
            var float32Data = new Float32Array(width * height * getNumberOfChannels(format));
            for (var ii = 0; ii < float32Data.length; ii++) {
                float32Data[ii] = 1000;
            }
            runTextureCreationTest(true, format, float32Data, null);

            // Int16Array
            var int16Data = new Int16Array(width * height * getNumberOfChannels(format));
            for (var ii = 0; ii <  int16Data.length; ii++) {
                int16Data[ii] = 1000;
            }
            runTextureCreationTest(true, format, int16Data, null);
        });

        // Test that Uint16 encoded half float values can be used as texture data.
        
        // First test that values in the 0-1 range can be written and read.
        var halfFloatOneThird = 0x3555; // Half float 1/3
        var uint16Formats = [
          { format: gl.RGBA,            expected: [85, 85, 85,  85], },
          { format: gl.RGB,             expected: [85, 85, 85, 255], },
          { format: gl.LUMINANCE,       expected: [85, 85, 85, 255], },
          { format: gl.ALPHA,           expected: [ 0,  0,  0,  85], },
          { format: gl.LUMINANCE_ALPHA, expected: [85, 85, 85,  85], },
        ];

        uint16Formats.forEach(function(f) {
            var width = 2;
            var height = 2;
            var format = f.format;

            var uint16Data = new Uint16Array(width * height * getNumberOfChannels(format));
            for (var ii = 0; ii <  uint16Data.length; ii++) {
                uint16Data[ii] = halfFloatOneThird;
            }
            runTextureCreationTest(true, format, uint16Data, f.expected);
        });

        // Next check that values outside the 0-1 range can be written.
        var halfFloatTenK = 0x70E2; // Half float 10000
        var uint16Formats2 = [
          { format: gl.RGBA, subtractor: [10000, 10000, 10000, 10000], },
          { format: gl.RGB,  subtractor: [10000, 10000, 10000, 1], },
        ];

        uint16Formats2.forEach(function(f) {
            var width = 2;
            var height = 2;
            var format = f.format;

            var uint16Data = new Uint16Array(width * height * getNumberOfChannels(format));
            for (var ii = 0; ii <  uint16Data.length; ii++) {
                uint16Data[ii] = halfFloatTenK;
            }
            runRenderTest(format, f.subtractor, uint16Data);
        });

        // Check if attaching texture as FBO target succeeds (Not mandatory)
        runRenderTest(gl.RGBA, [10000, 10000, 10000, 10000], null);
        runRenderTest(gl.RGB, [10000, 10000, 10000, 1], null);

        // Check of getExtension() returns same object
        runUniqueObjectTest();
    }
}

function getNumberOfChannels(format)
{
    if (format == gl.RGBA)
        return 4;
    else if (format == gl.RGB)
        return 3;
    else if (format == gl.LUMINANCE || format == gl.ALPHA)
        return 1;
    else if (format == gl.LUMINANCE_ALPHA)
        return 2;
}

function getFormatName(format)
{
    if (format == gl.RGBA)
        return "RGBA";
    else if (format == gl.RGB)
        return "RGB";
    else if (format == gl.LUMINANCE)
        return "LUMINANCE";
    else if (format == gl.ALPHA)
        return "ALPHA";
    else if (format == gl.LUMINANCE_ALPHA)
        return "LUMINANCE_ALPHA";
}

function allocateTexture()
{
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    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, "texture parameter setup should succeed");
    return texture;
}

function runTextureCreationTest(extensionEnabled, opt_format, opt_data, opt_expected)
{
    var format = opt_format || gl.RGBA;
    var data = opt_data || null;
    var expectSuccess = true;
    
    if (!extensionEnabled || !opt_expected)
        expectSuccess = false;
    debug("Testing texture creation with extension " + (extensionEnabled ? "enabled" : "disabled") +
          ", format " + getFormatName(format) + ", and data " + (data ? "non-null" : "null") +
          ". Expect " + (expectSuccess ? "Success" : "Failure"));   

    var texture = allocateTexture();
    var width = 2;
    var height = 2;
    gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, halfFloatOESEnum, data);
    if(!extensionEnabled) {
        wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Half floating point texture must be disallowed if OES_texture_half_float isn't enabled");
        return;
    } else if (!opt_expected) {
        wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Half floating point texture allocation must be disallowed when ArrayBufferView is not-null and not-Uint16");
        return;
    } else {
        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Half floating point texture allocation should succeed if OES_texture_half_float is enabled");

        if (!data) {
            gl.texImage2D(gl.TEXTURE_2D, 0, format, format, halfFloatOESEnum, colorCanvas);
        }
        wtu.clearAndDrawUnitQuad(gl);
        wtu.checkCanvas(gl, opt_expected);
        // Check that linear fails.
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        wtu.clearAndDrawUnitQuad(gl);
        wtu.checkCanvas(gl, [0, 0, 0, 255], "should be black");
    }

}

function checkRenderingResults()
{
    wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
}

function runRenderTest(format, subtractor, data)
{
    var formatString = wtu.glEnumToString(gl, format);

    debug("");

    if (!data) {
        debug("Testing half floating point " + formatString + " render target");
    } else {
        debug("Testing half floating point " + formatString + " from a Uint16Array");
    }

    var texture = allocateTexture();
    var width = 2;
    var height = 2;

    gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, ext.HALF_FLOAT_OES, data);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Half floating point texture allocation should succeed if OES_texture_half_float is enabled");

    if (!data) {
        // Try to use this texture as render target
        var fbo = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
        gl.bindTexture(gl.TEXTURE_2D, null);

        // It is legal for a WebGL implementation exposing the OES_texture_half_float extension to
        // support half floating point textures but not as attachments to framebuffer objects.
        if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
            debug("Half floating point render targets not supported -- this is legal");
            return;
        }

        var renderProgram =
            wtu.setupProgram(gl,
                             ["positionVertexShader", "floatingPointFragmentShader"],
                             ['vPosition'],
                             [0]);
        wtu.drawUnitQuad(gl);
        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Rendering to half floating point texture should succeed");
    }

    // Now sample from the half floating-point texture and verify we got the correct values.
    var texturedShaders = [
      wtu.setupSimpleTextureVertexShader(gl),
          "testFragmentShader"
      ];
    var testProgram =
        wtu.setupProgram(gl,
                        [wtu.setupSimpleTextureVertexShader(gl), "testFragmentShader"],
                        ['vPosition', 'texCoord0'],
                        [0, 1]);
    var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.useProgram(testProgram);
    gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor);
    wtu.drawUnitQuad(gl);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering from half floating point texture should succeed");
    checkRenderingResults();
}

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

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

</body>
</html>
