<!--
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">
<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>
<div id="console"></div>

<script>
"use strict";
description("Tests calling WebGL APIs with objects from other contexts");

var wtu = WebGLTestUtils;
var contextA = wtu.create3DContext();
var contextB = wtu.create3DContext();
var bufferA = contextA.createBuffer();
var bufferB = contextB.createBuffer();
var frameBufferA = contextA.createFramebuffer();
var frameBufferB = contextB.createFramebuffer();
var programA = wtu.loadStandardProgram(contextA);
var programB = wtu.loadStandardProgram(contextB);
var renderBufferA = contextA.createRenderbuffer();
var renderBufferB = contextB.createRenderbuffer();
var shaderA = wtu.loadStandardVertexShader(contextA);
var shaderB = wtu.loadStandardVertexShader(contextB);
var textureA = contextA.createTexture();
var textureB = contextB.createTexture();
var locationA = contextA.getUniformLocation(programA, 'u_modelViewProjMatrix');
var locationB = contextB.getUniformLocation(programB, 'u_modelViewProjMatrix');
var uniformData = [];

function generateFloat32Array(length) {
    uniformData = new Float32Array(length);
}

function generateFloatArray(length) {
    uniformData = new Array(length);
    for (var i = 0; i < length; i++) {
        uniformData[i] = 0.0;
    }
}

function generateInt32Array(length) {
    uniformData = new Int32Array(length);
}

function generateIntArray(length) {
    uniformData = new Array(length);
    for (var i = 0; i < length; i++) {
        uniformData[i] = 0;
    }
}

// Make the bindable objects valid in both contexts first.
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, bufferA)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindBuffer(contextA.ARRAY_BUFFER, null)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, bufferB)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindBuffer(contextB.ARRAY_BUFFER, null)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferA)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, null)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindFramebuffer(contextB.FRAMEBUFFER, frameBufferB)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindFramebuffer(contextB.FRAMEBUFFER, null)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferA)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, null)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindRenderbuffer(contextB.RENDERBUFFER, renderBufferB)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindRenderbuffer(contextB.RENDERBUFFER, null)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTexture(contextA.TEXTURE_2D, textureA)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.bindTexture(contextA.TEXTURE_2D, null)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTexture(contextB.TEXTURE_2D, textureB)");
wtu.shouldGenerateGLError(contextB, contextB.NO_ERROR, "contextB.bindTexture(contextB.TEXTURE_2D, null)");

wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programA, shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderA)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindAttribLocation(programB, 0, 'foo')");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindBuffer(contextA.ARRAY_BUFFER, bufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindTexture(contextA.TEXTURE_2D, textureB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.compileShader(shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteBuffer(bufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteFramebuffer(frameBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteProgram(programB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteRenderbuffer(renderBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteShader(shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteShader(shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.deleteTexture(textureB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programA, shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderA)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferRenderbuffer(contextA.FRAMEBUFFER, contextA.DEPTH_ATTACHMENT, contextA.RENDERBUFFER, renderBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferTexture2D(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, contextA.TEXTURE_2D, textureB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveAttrib(programB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getActiveUniform(programB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getAttachedShaders(programB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getAttribLocation(programB, 'a_vertex')");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramParameter(programB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramInfoLog(programB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderParameter(shaderB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderInfoLog(shaderB, 0)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderSource(shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniform(programB, locationA)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniform(programA, locationB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniformLocation(programB, 'u_modelViewProjMatrix')");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isBuffer(bufferB)");
shouldBeFalse("contextA.isBuffer(bufferB)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isFramebuffer(frameBufferB)");
shouldBeFalse("contextA.isFramebuffer(frameBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isProgram(programB)");
shouldBeFalse("contextA.isProgram(programB)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isRenderbuffer(renderBufferB)");
shouldBeFalse("contextA.isRenderbuffer(renderBufferB)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isShader(shaderB)");
shouldBeFalse("contextA.isShader(shaderB)");
wtu.shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.isTexture(textureB)");
shouldBeFalse("contextA.isTexture(textureB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.linkProgram(programB)");
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.shaderSource(shaderB, 'foo')");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1f(locationB, 0.0)");
generateFloat32Array(1);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData)");
generateFloatArray(1);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1fv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1i(locationB, 0)");
generateInt32Array(1);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData)");
generateIntArray(1);      wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform1iv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2f(locationB, 0.0, 0.0)");
generateFloat32Array(2);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData)");
generateFloatArray(2);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2fv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2i(locationB, 0, 0)");
generateInt32Array(2);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData)");
generateIntArray(2);      wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform2iv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3f(locationB, 0.0, 0.0, 0.0)");
generateFloat32Array(3);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData)");
generateFloatArray(3);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3fv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3i(locationB, 0, 0, 0)");
generateInt32Array(3);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData)");
generateIntArray(3);      wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform3iv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4f(locationB, 0.0, 0.0, 0.0, 0.0)");
generateFloat32Array(4);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData)");
generateFloatArray(4);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4fv(locationB, uniformData)");
                          wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4i(locationB, 0, 0, 0, 0)");
generateInt32Array(4);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData)");
generateIntArray(4);      wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniform4iv(locationB, uniformData)");
generateFloat32Array(4);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData)");
generateFloatArray(4);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix2fv(locationB, false, uniformData)");
generateFloat32Array(9);  wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData)");
generateFloatArray(9);    wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix3fv(locationB, false, uniformData)");
generateFloat32Array(16); wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData)");
generateFloatArray(16);   wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.uniformMatrix4fv(locationB, false, uniformData)");

var successfullyParsed = true;
</script>

<script src="../../js/js-test-post.js"></script>
</body>
</html>
