<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";

let wtu = WebGLTestUtils;
let gl = wtu.create3DContext(null, null, 2);
let ext = null;
let queryExt = null;

function runClearTest()
{
    debug("");
    debug("Testing clear");

    let width = 256;
    let height = 256;

    let views = gl.getParameter(ext.MAX_VIEWS_OVR);

    let fb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
    ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);

    gl.viewport(0, 0, width, height);

    gl.clearColor(1, 0, 0, 1);

    let query = gl.createQuery();
    gl.beginQuery(queryExt.TIME_ELAPSED_EXT, query);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from setup");

    gl.clear(gl.COLOR_BUFFER_BIT);
    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "multiview clear should generate invalid operation when a timer query is active");

    gl.endQuery(queryExt.TIME_ELAPSED_EXT);

    let readFb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
    for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
        gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
        let expectedColor = [0, 0, 0, 0];
        wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be untouched');
    }
}

function runFragmentShaderRenderTest()
{
    debug("");
    debug("Testing rendering with different colors in fragment shader");

    let width = 256;
    let height = 256;

    let views = gl.getParameter(ext.MAX_VIEWS_OVR);

    let multiviewShaders = [
      getMultiviewPassthroughVertexShader(views),
      getMultiviewColorFragmentShader()
    ];
    let testProgram = wtu.setupProgram(gl, multiviewShaders, ['a_position'], [0], true);
    if (!testProgram) {
        testFailed("Compilation with extension enabled failed.");
        return;
    }

    let fb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
    ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);

    gl.viewport(0, 0, width, height);

    let query = gl.createQuery();
    gl.beginQuery(queryExt.TIME_ELAPSED_EXT, query);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from setup");

    wtu.drawUnitQuad(gl);
    wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "multiview draw should generate invalid operation when a timer query is active");

    gl.endQuery(queryExt.TIME_ELAPSED_EXT);

    let readFb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
    for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
        gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
        let expectedColor = [0, 0, 0, 0];
        wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be untouched');
    }
}

description("This test verifies the functionality of the OVR_multiview2 extension and its interaction with EXT_disjoint_timer_query_webgl2, if it is available.");

debug("");

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

  if (!gl.getExtension("OVR_multiview2") || !gl.getExtension("EXT_disjoint_timer_query_webgl2")) {
      testPassed("No OVR_multiview2 support or no EXT_disjoint_timer_query_webgl2 support -- this is legal");
  } else {
      testPassed("Successfully enabled OVR_multiview2 and EXT_disjoint_timer_query_webgl2 extensions");
      ext = gl.getExtension('OVR_multiview2');
      queryExt = gl.getExtension('EXT_disjoint_timer_query_webgl2');

      runClearTest();

      wtu.setupUnitQuad(gl, 0, 1);

      runFragmentShaderRenderTest();
  }
}

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

</body>
</html>
