diff -r 000000000000 -r 6474c204b198 content/canvas/test/webgl-conformance/conformance/resources/webgl-test.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/canvas/test/webgl-conformance/conformance/resources/webgl-test.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,805 @@ +/* +Copyright (C) 2011 Apple Computer, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +function webglTestLog(msg) { + if (window.console && window.console.log) { + window.console.log(msg); + } + if (document.getElementById("console")) { + var log = document.getElementById("console"); + log.innerHTML += msg + "
"; + } +} + +// +// create3DContext +// +// Returns the WebGLRenderingContext for any known implementation. +// +function create3DContext(canvas, attributes) +{ + if (!canvas) + canvas = document.createElement("canvas"); + var names = ["webgl", "experimental-webgl"]; + var context = null; + for (var i = 0; i < names.length; ++i) { + try { + context = canvas.getContext(names[i], attributes); + } catch (e) { + } + if (context) { + break; + } + } + if (!context) { + throw "Unable to fetch WebGL rendering context for Canvas"; + } + return context; +} + +function createGLErrorWrapper(context, fname) { + return function() { + var rv = context[fname].apply(context, arguments); + var err = context.getError(); + if (err != 0) + throw "GL error " + err + " in " + fname; + return rv; + }; +} + +function create3DContextWithWrapperThatThrowsOnGLError(canvas, attributes) { + var context = create3DContext(canvas, attributes); + // Thanks to Ilmari Heikkinen for the idea on how to implement this so elegantly. + var wrap = {}; + for (var i in context) { + try { + if (typeof context[i] == 'function') { + wrap[i] = createGLErrorWrapper(context, i); + } else { + wrap[i] = context[i]; + } + } catch (e) { + webglTestLog("createContextWrapperThatThrowsOnGLError: Error accessing " + i); + } + } + wrap.getError = function() { + return context.getError(); + }; + return wrap; +} + +function getGLErrorAsString(ctx, err) { + if (err === ctx.NO_ERROR) { + return "NO_ERROR"; + } + for (var name in ctx) { + if (ctx[name] === err) { + return name; + } + } + return "0x" + err.toString(16); +} + +// Pass undefined for glError to test that it at least throws some error +function shouldGenerateGLError(ctx, glErrors, evalStr) { + if (!glErrors.length) { + glErrors = [glErrors]; + } + var exception; + try { + eval(evalStr); + } catch (e) { + exception = e; + } + if (exception) { + testFailed(evalStr + " threw exception " + exception); + } else { + var err = ctx.getError(); + if (glErrors.indexOf(err) < 0) { + var errStrs = []; + for (var ii = 0; ii < glErrors.length; ++ii) { + errStrs.push(getGLErrorAsString(ctx, glErrors[ii])); + } + testFailed(evalStr + " expected: " + errStrs.join(" or ") + ". Was " + getGLErrorAsString(ctx, err) + "."); + } else { + testPassed(evalStr + " generated expected GL error: " + getGLErrorAsString(ctx, err) + "."); + } + } +} + +/** + * Tests that the first error GL returns is the specified error. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {number|!Array.} glError The expected gl + * error. Multiple errors can be passed in using an + * array. + * @param {string} opt_msg Optional additional message. + */ +function glErrorShouldBe(gl, glErrors, opt_msg) { + if (!glErrors.length) { + glErrors = [glErrors]; + } + opt_msg = opt_msg || ""; + var err = gl.getError(); + var ndx = glErrors.indexOf(err); + if (ndx < 0) { + if (glErrors.length == 1) { + testFailed("getError expected: " + getGLErrorAsString(gl, glErrors[0]) + + ". Was " + getGLErrorAsString(gl, err) + " : " + opt_msg); + } else { + var errs = []; + for (var ii = 0; ii < glErrors.length; ++ii) { + errs.push(getGLErrorAsString(gl, glErrors[ii])); + } + testFailed("getError expected one of: [" + errs.join(", ") + + "]. Was " + getGLErrorAsString(gl, err) + " : " + opt_msg); + } + } else { + testPassed("getError was expected value: " + + getGLErrorAsString(gl, err) + " : " + opt_msg); + } +}; + +// +// createProgram +// +// Create and return a program object, attaching each of the given shaders. +// +// If attribs are given, bind an attrib with that name at that index. +// +function createProgram(gl, vshaders, fshaders, attribs) +{ + if (typeof(vshaders) == "string") + vshaders = [vshaders]; + if (typeof(fshaders) == "string") + fshaders = [fshaders]; + + var shaders = []; + var i; + + for (i = 0; i < vshaders.length; ++i) { + var shader = loadShader(gl, vshaders[i], gl.VERTEX_SHADER); + if (!shader) + return null; + shaders.push(shader); + } + + for (i = 0; i < fshaders.length; ++i) { + var shader = loadShader(gl, fshaders[i], gl.FRAGMENT_SHADER); + if (!shader) + return null; + shaders.push(shader); + } + + var prog = gl.createProgram(); + for (i = 0; i < shaders.length; ++i) { + gl.attachShader(prog, shaders[i]); + } + + if (attribs) { + for (var i = 0; i < attribs.length; ++i) { + gl.bindAttribLocation(prog, i, attribs[i]); + } + } + + gl.linkProgram(prog); + + // Check the link status + var linked = gl.getProgramParameter(prog, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + var error = gl.getProgramInfoLog(prog); + webglTestLog("Error in program linking:" + error); + + gl.deleteProgram(prog); + for (i = 0; i < shaders.length; ++i) + gl.deleteShader(shaders[i]); + return null; + } + + return prog; +} + +// +// initWebGL +// +// Initialize the Canvas element with the passed name as a WebGL object and return the +// WebGLRenderingContext. +// +// Load shaders with the passed names and create a program with them. Return this program +// in the 'program' property of the returned context. +// +// For each string in the passed attribs array, bind an attrib with that name at that index. +// Once the attribs are bound, link the program and then use it. +// +// Set the clear color to the passed array (4 values) and set the clear depth to the passed value. +// Enable depth testing and blending with a blend func of (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) +// +function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth, contextAttribs) +{ + var canvas = document.getElementById(canvasName); + var gl = create3DContext(canvas, contextAttribs); + if (!gl) { + alert("No WebGL context found"); + return null; + } + + // Create the program object + gl.program = createProgram(gl, vshader, fshader, attribs); + if (!gl.program) + return null; + + gl.useProgram(gl.program); + + gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + gl.clearDepth(clearDepth); + + gl.enable(gl.DEPTH_TEST); + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + + return gl; +} + +// +// getShaderSource +// +// Load the source from the passed shader file. +// +function getShaderSource(file) +{ + var xhr = new XMLHttpRequest(); + xhr.open("GET", file, false); + xhr.send(); + return xhr.responseText; +} + + +// +// loadShader +// +// 'shader' is either the id of a