diff options
Diffstat (limited to '')
-rw-r--r-- | testing/web-platform/tests/webcodecs/webgl-test-utils.js | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webcodecs/webgl-test-utils.js b/testing/web-platform/tests/webcodecs/webgl-test-utils.js new file mode 100644 index 0000000000..f623a6c986 --- /dev/null +++ b/testing/web-platform/tests/webcodecs/webgl-test-utils.js @@ -0,0 +1,321 @@ +// Copyright 2011 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +WebGLTestUtils = (function() { + /** + * Converts a WebGL enum to a string + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {number} value The enum value. + * @return {string} The enum as a string. + */ + var glEnumToString = function(gl, value) { + for (var p in gl) { + if (gl[p] == value) { + return p; + } + } + return '0x' + value.toString(16); + }; + + var lastError = ''; + + /** + * Returns the last compiler/linker error. + * @return {string} The last compiler/linker error. + */ + var getLastError = function() { + return lastError; + }; + + // clang-format off + + /** + * A vertex shader for a single texture. + * @type {string} + */ + var simpleTextureVertexShader = [ + 'attribute vec4 vPosition;', // + 'attribute vec2 texCoord0;', + 'varying vec2 texCoord;', + 'void main() {', + ' gl_Position = vPosition;', + ' texCoord = texCoord0;', + '}' + ].join('\n'); + + /** + * A fragment shader for a single texture. + * @type {string} + */ + var simpleTextureFragmentShader = [ + 'precision mediump float;', + 'uniform sampler2D tex;', + 'varying vec2 texCoord;', + 'void main() {', + ' gl_FragData[0] = texture2D(tex, texCoord);', + '}' + ].join('\n'); + + // clang-format on + + /** + * Creates a simple texture vertex shader. + * @param {!WebGLContext} gl The WebGLContext to use. + * @return {!WebGLShader} + */ + var setupSimpleTextureVertexShader = function(gl) { + return loadShader(gl, simpleTextureVertexShader, gl.VERTEX_SHADER); + }; + + /** + * Creates a simple texture fragment shader. + * @param {!WebGLContext} gl The WebGLContext to use. + * @return {!WebGLShader} + */ + var setupSimpleTextureFragmentShader = function(gl) { + return loadShader(gl, simpleTextureFragmentShader, gl.FRAGMENT_SHADER); + }; + + /** + * Creates a program, attaches shaders, binds attrib locations, links the + * program and calls useProgram. + * @param {!Array.<!WebGLShader>} shaders The shaders to attach . + * @param {!Array.<string>} opt_attribs The attribs names. + * @param {!Array.<number>} opt_locations The locations for the attribs. + */ + var setupProgram = function(gl, shaders, opt_attribs, opt_locations) { + var realShaders = []; + var program = gl.createProgram(); + for (var ii = 0; ii < shaders.length; ++ii) { + var shader = shaders[ii]; + if (typeof shader == 'string') { + var element = document.getElementById(shader); + if (element) { + shader = loadShaderFromScript(gl, shader); + } else { + shader = loadShader( + gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER); + } + } + gl.attachShader(program, shader); + } + if (opt_attribs) { + for (var ii = 0; ii < opt_attribs.length; ++ii) { + gl.bindAttribLocation( + program, opt_locations ? opt_locations[ii] : ii, opt_attribs[ii]); + } + } + gl.linkProgram(program); + + // Check the link status + var linked = gl.getProgramParameter(program, gl.LINK_STATUS); + if (!linked) { + gl.deleteProgram(program); + return null; + } + + gl.useProgram(program); + return program; + }; + + /** + * Creates a simple texture program. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {number} opt_positionLocation The attrib location for position. + * @param {number} opt_texcoordLocation The attrib location for texture + * coords. + * @return {WebGLProgram} + */ + var setupSimpleTextureProgram = function( + gl, opt_positionLocation, opt_texcoordLocation) { + opt_positionLocation = opt_positionLocation || 0; + opt_texcoordLocation = opt_texcoordLocation || 1; + var vs = setupSimpleTextureVertexShader(gl); + var fs = setupSimpleTextureFragmentShader(gl); + if (!vs || !fs) { + return null; + } + var program = setupProgram( + gl, [vs, fs], ['vPosition', 'texCoord0'], + [opt_positionLocation, opt_texcoordLocation]); + if (!program) { + gl.deleteShader(fs); + gl.deleteShader(vs); + } + gl.useProgram(program); + return program; + }; + + /** + * Creates buffers for a textured unit quad and attaches them to vertex + * attribs. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {number} opt_positionLocation The attrib location for position. + * @param {number} opt_texcoordLocation The attrib location for texture + * coords. + * @return {!Array.<WebGLBuffer>} The buffer objects that were + * created. + */ + var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation) { + opt_positionLocation = opt_positionLocation || 0; + opt_texcoordLocation = opt_texcoordLocation || 1; + var objects = []; + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData( + gl.ARRAY_BUFFER, new Float32Array([ + 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, -1.0, + -1.0, 0.0, 1.0, -1.0, 0.0 + ]), + gl.STATIC_DRAW); + gl.enableVertexAttribArray(opt_positionLocation); + gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0); + objects.push(vertexObject); + + var vertexObject = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array( + [1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0]), + gl.STATIC_DRAW); + gl.enableVertexAttribArray(opt_texcoordLocation); + gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0); + objects.push(vertexObject); + return objects; + }; + + /** + * Creates a program and buffers for rendering a textured quad. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {number} opt_positionLocation The attrib location for position. + * @param {number} opt_texcoordLocation The attrib location for texture + * coords. + * @return {!WebGLProgram} + */ + var setupTexturedQuad = function( + gl, opt_positionLocation, opt_texcoordLocation) { + var program = setupSimpleTextureProgram( + gl, opt_positionLocation, opt_texcoordLocation); + setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation); + return program; + }; + + /** + * Draws a previously setup quad. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {!Array.<number>} opt_color The color to fill clear with before + * drawing. A 4 element array where each element is in the range 0 to + * 255. Default [255, 255, 255, 255] + */ + var drawQuad = function(gl, opt_color) { + opt_color = opt_color || [255, 255, 255, 255]; + gl.clearColor( + opt_color[0] / 255, opt_color[1] / 255, opt_color[2] / 255, + opt_color[3] / 255); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLES, 0, 6); + }; + + /** + * Links a WebGL program, throws if there are errors. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {!WebGLProgram} program The WebGLProgram to link. + * @param {function(string): void) opt_errorCallback callback for errors. + */ + var linkProgram = function(gl, program, opt_errorCallback) { + // Link the program + gl.linkProgram(program); + + // Check the link status + var linked = gl.getProgramParameter(program, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + gl.deleteProgram(program); + return false; + } + + return true; + }; + + /** + * Loads a shader. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {string} shaderSource The shader source. + * @param {number} shaderType The type of shader. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {!WebGLShader} The created shader. + */ + var loadShader = + function(gl, shaderSource, shaderType, opt_errorCallback) { + var errFn = opt_errorCallback || (_ => {}); + // Create the shader object + var shader = gl.createShader(shaderType); + if (shader == null) { + errFn('*** Error: unable to create shader \'' + shaderSource + '\''); + return null; + } + + // Load the shader source + gl.shaderSource(shader, shaderSource); + var err = gl.getError(); + if (err != gl.NO_ERROR) { + errFn( + '*** Error loading shader \'' + shader + + '\':' + glEnumToString(gl, err)); + return null; + } + + // Compile the shader + gl.compileShader(shader); + + // Check the compile status + var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + lastError = gl.getShaderInfoLog(shader); + errFn('*** Error compiling shader \'' + shader + '\':' + lastError); + gl.deleteShader(shader); + return null; + } + + return shader; + } + + /** + * Loads shaders from source, creates a program, attaches the shaders and + * links. + * @param {!WebGLContext} gl The WebGLContext to use. + * @param {string} vertexShader The vertex shader. + * @param {string} fragmentShader The fragment shader. + * @param {function(string): void) opt_errorCallback callback for errors. + * @return {!WebGLProgram} The created program. + */ + var loadProgram = function( + gl, vertexShader, fragmentShader, opt_errorCallback) { + var program = gl.createProgram(); + gl.attachShader( + program, + loadShader(gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback)); + gl.attachShader( + program, + loadShader(gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback)); + return linkProgram(gl, program, opt_errorCallback) ? program : null; + }; + + return { + drawQuad: drawQuad, + getLastError: getLastError, + glEnumToString: glEnumToString, + loadProgram: loadProgram, + loadShader: loadShader, + setupProgram: setupProgram, + setupSimpleTextureFragmentShader: setupSimpleTextureFragmentShader, + setupSimpleTextureProgram: setupSimpleTextureProgram, + setupSimpleTextureVertexShader: setupSimpleTextureVertexShader, + setupTexturedQuad: setupTexturedQuad, + setupUnitQuad: setupUnitQuad, + }; +}()); |