﻿<!--

/*
** 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 OES_vertex_array_object_bufferData 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>
<!-- comment in the script tag below to test through JS emualation of the extension. -->
<!--
<script src="../../../demos/google/resources/OESVertexArrayObject.js"></script>
-->
</head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main(void) {
    gl_Position = a_position;
    v_color = a_color;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main(void) {
    gl_FragColor = v_color;
}
</script>
<script>
"use strict";
description("This test verifies drawing results when using gl.bufferData with the OES_vertex_array_object extension.");

debug("");

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

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

    // Setup emulated OESVertexArrayObject if it has been included.
    if (window.setupVertexArrayObject) {
        debug("using emuated OES_vertex_array_object");
        setupVertexArrayObject(gl);
    }

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

    } else {
        testPassed("Successfully enabled OES_vertex_array_object extension");

        runBufferDataTest();
        wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
    }
}

/**
 * The OES_vertex_array_object extension seems to work incorrectly on some handheld devices,
 * namely the Nexus 5, and Nexus 7 (in 2014/01) when using bufferData before binding the VAO.
 * The tested OS was Android KitKat 4.4.2, the effects were the same in all tested browsers
 * (Chrome, Chrome Beta, Firefox, Firefox Beta), so it is likely a driver bug.
 * These devices have the similar Adreno 320 and Adreno 330 GPUs respectively.
 *
 * The issuse resulted from this sequence of actions in a requestAnimationFrame loop:
 * 1. upload some vertex buffers with gl.bufferData (eg. colors)
 * 2. bind the VAO
 * 3. clear the canvas
 * 4. draw (some triangles) to the canvas
 * 5. unbind the VAO
 *
 * This caused the drawn triangles to be drawn with black (0) for most of the frames, with some
 * rare frames presenting the correct render results. Interestingly on both devices exactly every
 * 64th frame passed (starting with the very first one), the others failed.
 * (Because of this, we test multiple frames.)
 * When positions were uploaded, seemingly nothing was drawn, that's likely because the
 * position buffer was also all 0s.
 *
 * The issue did not occur:
 * - if step 1. and 2. were swapped
 * - or if step5 was ommited (probably because that makes step 2 a no-op since the VAO is bound)
 */
function runBufferDataTest() {
    debug("Testing draws with bufferData");

    canvas.width = 50; canvas.height = 50;
    gl.viewport(0, 0, canvas.width, canvas.height);

    var testColor = [0, 255, 0, 255];
    var clearColor = [255, 0, 0, 255];

    // Where the issue occures, this is the sequence of success/failure every time:
    // result:           success fail fail fail fail ... success fail fail ...
    // currentTestCount: 0       1    2    3    4    ... 64      65   66   ...
    // So with just 1 test it passes, but 2 tests are enough. Here we use 3.
    var numberOfTests = 3;
    var currentTestCount = 0;

    var positionLoc = 0;
    var colorLoc = 1;
    var gridRes = 1;

    var program = wtu.setupSimpleVertexColorProgram(gl, positionLoc, colorLoc);

    var vao0 = ext.createVertexArrayOES();
    ext.bindVertexArrayOES(vao0);

    var buffers = wtu.setupIndexedQuadWithOptions(gl,
    { gridRes: gridRes,
      positionLocation: positionLoc
    });

    var colorTypedArray = createColorTypedArray();

    var colorBuffer = gl.createBuffer(gl.ARRAY_BUFFER);
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.enableVertexAttribArray(colorLoc);
    gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);

    ext.bindVertexArrayOES(null);

    testDrawing();

    function testDrawing() {
        // this order works fine:
        // ext.bindVertexArrayOES(vao0);
        // uploadColor();

        // this order doesn't:
        uploadColor();
        ext.bindVertexArrayOES(vao0);

        wtu.clearAndDrawIndexedQuad(gl, 1, clearColor);

        ext.bindVertexArrayOES(null);

        //debug("<span>"+currentTestCount+"</span");
        wtu.checkCanvas(gl, testColor, "should be green")

        if (++currentTestCount < numberOfTests) {
            testDrawing();
            // wtu.requestAnimFrame(testDrawing);
        } else {
            // clean up
            ext.deleteVertexArrayOES(vao0);
        }
    }

    function uploadColor() {
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colorTypedArray, gl.STREAM_DRAW);
    }

    function createColorTypedArray() {
        var colors = [];
        var pOffset = 0;
        for (var yy = 0; yy <= gridRes; ++yy) {
          for (var xx = 0; xx <= gridRes; ++xx) {
            colors[pOffset + 0] = testColor[0];
            colors[pOffset + 1] = testColor[1];
            colors[pOffset + 2] = testColor[2];
            colors[pOffset + 3] = testColor[3];
            pOffset += 4;
          }
        }
        return new Float32Array(colors);
    }
}

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

</body>
</html>
