diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js new file mode 100644 index 0000000000..0c340ee380 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js @@ -0,0 +1,488 @@ +/*------------------------------------------------------------------------- + * drawElements Quality gluShaderProgram.Program OpenGL ES Utilities + * ------------------------------------------------ + * + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +'use strict'; +goog.provide('framework.opengl.gluShaderProgram'); + +goog.scope(function() { + +var gluShaderProgram = framework.opengl.gluShaderProgram; + +/** + * gluShaderProgram.Shader type enum + * @enum {number} + */ +gluShaderProgram.shaderType = { + VERTEX: 0, + FRAGMENT: 1 +}; + +/** + * gluShaderProgram.Shader type enum name + * @param {gluShaderProgram.shaderType} shaderType + * @return {string} + */ +gluShaderProgram.getShaderTypeName = function(shaderType) { + var s_names = + [ + 'vertex', + 'fragment' + ]; + + return s_names[shaderType]; +}; + +/** + * Get GL shader type from gluShaderProgram.shaderType + * @param {WebGL2RenderingContext} gl WebGL context + * @param {gluShaderProgram.shaderType} type gluShaderProgram.Shader Type + * @return {number} GL shader type + */ +gluShaderProgram.getGLShaderType = function(gl, type) { + var _glShaderType; + switch (type) { + case gluShaderProgram.shaderType.VERTEX: _glShaderType = gl.VERTEX_SHADER; break; + case gluShaderProgram.shaderType.FRAGMENT: _glShaderType = gl.FRAGMENT_SHADER; break; + default: + throw new Error('Unknown shader type ' + type); + } + return _glShaderType; +}; + +/** + * Declares shader information + * @constructor + * @param {gluShaderProgram.shaderType} type + * @param {string=} source + */ +gluShaderProgram.ShaderInfo = function(type, source) { + this.type = type; /** gluShaderProgram.Shader type. */ + this.source = source; /** gluShaderProgram.Shader source. */ + this.infoLog; /** Compile info log. */ + this.compileOk = false; /** Did compilation succeed? */ + this.compileTimeUs = 0; /** Compile time in microseconds (us). */ +}; + +/** + * Generates vertex shader info from source + * @param {string} source + * @return {gluShaderProgram.ShaderInfo} vertex shader info + */ +gluShaderProgram.genVertexSource = function(source) { +/** @type {gluShaderProgram.ShaderInfo} */ var shader = new gluShaderProgram.ShaderInfo(gluShaderProgram.shaderType.VERTEX, source); + return shader; +}; + +/** + * Generates fragment shader info from source + * @param {string} source + * @return {gluShaderProgram.ShaderInfo} fragment shader info + */ +gluShaderProgram.genFragmentSource = function(source) { +/** @type {gluShaderProgram.ShaderInfo} */ var shader = new gluShaderProgram.ShaderInfo(gluShaderProgram.shaderType.FRAGMENT, source); + return shader; +}; + +/** + * Generates shader from WebGL context and type + * @constructor + * @param {WebGL2RenderingContext} gl WebGL context + * @param {gluShaderProgram.shaderType} type gluShaderProgram.Shader Type + */ +gluShaderProgram.Shader = function(gl, type) { + this.gl = gl; + this.info = new gluShaderProgram.ShaderInfo(type); /** Client-side clone of state for debug / perf reasons. */ + this.shader = gl.createShader(gluShaderProgram.getGLShaderType(gl, type)); + assertMsgOptions(gl.getError() == gl.NO_ERROR, 'gl.createShader()', false, true); + + this.setSources = function(source) { + this.gl.shaderSource(this.shader, source); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'glshaderSource()', false, true); + this.info.source = source; + }; + + this.getCompileStatus = function() { + return this.info.compileOk; + }; + + this.compile = function() { + this.info.compileOk = false; + this.info.compileTimeUs = 0; + this.info.infoLog = ''; + + /** @type {Date} */ var compileStart = new Date(); + this.gl.compileShader(this.shader); + /** @type {Date} */ var compileEnd = new Date(); + this.info.compileTimeUs = 1000 * (compileEnd.getTime() - compileStart.getTime()); + + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.compileShader()', false, true); + + var compileStatus = this.gl.getShaderParameter(this.shader, this.gl.COMPILE_STATUS); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'glGetShaderParameter()', false, true); + + this.info.compileOk = compileStatus; + this.info.infoLog = this.gl.getShaderInfoLog(this.shader); + }; + + this.getShader = function() { + return this.shader; + }; + + this.destroy = function() { + this.gl.deleteShader(this.shader); + }; + +}; +/** + * Creates gluShaderProgram.ProgramInfo + * @constructor + */ +gluShaderProgram.ProgramInfo = function() { + /** @type {string} */ this.infoLog = ''; /** Link info log. */ + /** @type {boolean} */ this.linkOk = false; /** Did link succeed? */ + /** @type {number} */ this.linkTimeUs = 0; /** Link time in microseconds (us). */ +}; + +/** + * Creates program. + * Inner methods: attach shaders, bind attributes location, link program and transform Feedback Varyings + * @constructor + * @param {WebGL2RenderingContext} gl WebGL context + * @param {WebGLProgram=} programID + */ +gluShaderProgram.Program = function(gl, programID) { + this.gl = gl; + this.program = programID || null; + this.info = new gluShaderProgram.ProgramInfo(); + + if (!programID) { + this.program = gl.createProgram(); + assertMsgOptions(gl.getError() == gl.NO_ERROR, 'gl.createProgram()', false, true); + } +}; + +/** + * @return {WebGLProgram} + */ +gluShaderProgram.Program.prototype.getProgram = function() { return this.program; }; + +/** + * @return {gluShaderProgram.ProgramInfo} + */ +gluShaderProgram.Program.prototype.getInfo = function() { return this.info; }; + +/** + * @param {WebGLShader} shader + */ +gluShaderProgram.Program.prototype.attachShader = function(shader) { + this.gl.attachShader(this.program, shader); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.attachShader()', false, true); +}; + +/** + * @param {WebGLShader} shader + */ +gluShaderProgram.Program.prototype.detachShader = function(shader) { + this.gl.detachShader(this.program, shader); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.detachShader()', false, true); +}; + +/** + * @param {number} location + * @param {string} name + */ +gluShaderProgram.Program.prototype.bindAttribLocation = function(location, name) { + this.gl.bindAttribLocation(this.program, location, name); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.bindAttribLocation()', false, true); +}; + +gluShaderProgram.Program.prototype.link = function() { + this.info.linkOk = false; + this.info.linkTimeUs = 0; + this.info.infoLog = ''; + + /** @type {Date} */ var linkStart = new Date(); + this.gl.linkProgram(this.program); + /** @type {Date} */ var linkEnd = new Date(); + this.info.linkTimeUs = 1000 * (linkEnd.getTime() - linkStart.getTime()); + + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.linkProgram()', false, true); + + var linkStatus = this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.getProgramParameter()', false, true); + this.info.linkOk = linkStatus; + this.info.infoLog = this.gl.getProgramInfoLog(this.program); + if (!this.info.linkOk) + bufferedLogToConsole("program linking: " + this.info.infoLog); +}; + +/** + * return {boolean} + */ +gluShaderProgram.Program.prototype.getLinkStatus = function() { + return this.info.linkOk; +}; + +/** + * @param {Array<string>} varyings + * @param {number} bufferMode + */ +gluShaderProgram.Program.prototype.transformFeedbackVaryings = function(varyings, bufferMode) { + this.gl.transformFeedbackVaryings(this.program, varyings, bufferMode); + assertMsgOptions(this.gl.getError() == this.gl.NO_ERROR, 'gl.transformFeedbackVaryings()', false, true); +}; + +/** + * Assigns gl WebGL context and programSources. Declares array of shaders and new program() + * @constructor + * @param {WebGL2RenderingContext} gl WebGL context + * @param {gluShaderProgram.ProgramSources} programSources + */ +gluShaderProgram.ShaderProgram = function(gl, programSources) { + this.gl = gl; + this.programSources = programSources; + this.shaders = []; + this.program = new gluShaderProgram.Program(gl); + + /** @type {boolean} */ this.shadersOK = true; + + for (var i = 0; i < programSources.sources.length; i++) { + /** @type {gluShaderProgram.Shader} */ var shader = new gluShaderProgram.Shader(gl, programSources.sources[i].type); + shader.setSources(programSources.sources[i].source); + shader.compile(); + this.shaders.push(shader); + this.shadersOK = this.shadersOK && shader.getCompileStatus(); + if (!shader.getCompileStatus()) { + bufferedLogToConsole('gluShaderProgram.Shader:\n' + programSources.sources[i].source); + bufferedLogToConsole('Compile status: ' + shader.getCompileStatus()); + bufferedLogToConsole('Shader infoLog: ' + shader.info.infoLog); + } + } + + if (this.shadersOK) { + for (var i = 0; i < this.shaders.length; i++) + this.program.attachShader(this.shaders[i].getShader()); + + for (var attrib in programSources.attribLocationBindings) + this.program.bindAttribLocation(programSources.attribLocationBindings[attrib], attrib); + + if (programSources.transformFeedbackBufferMode) + if (programSources.transformFeedbackBufferMode === gl.NONE) + assertMsgOptions(programSources.transformFeedbackVaryings.length === 0, 'Transform feedback sanity check', false, true); + else + this.program.transformFeedbackVaryings(programSources.transformFeedbackVaryings, programSources.transformFeedbackBufferMode); + + /* TODO: GLES 3.1: set separable flag */ + + this.program.link(); + + } +}; + +/** + * return {WebGLProgram} + */ +gluShaderProgram.ShaderProgram.prototype.getProgram = function() { + return this.program.program; + }; + +/** + * @return {gluShaderProgram.ProgramInfo} + */ +gluShaderProgram.ShaderProgram.prototype.getProgramInfo = function() { + return this.program.info; +}; + +gluShaderProgram.ShaderProgram.prototype.isOk = function() { + return this.shadersOK && this.program.getLinkStatus(); +}; + +gluShaderProgram.containerTypes = { + ATTRIB_LOCATION_BINDING: 0, + TRANSFORM_FEEDBACK_MODE: 1, + TRANSFORM_FEEDBACK_VARYING: 2, + TRANSFORM_FEEDBACK_VARYINGS: 3, + SHADER_SOURCE: 4, + PROGRAM_SEPARABLE: 5, + PROGRAM_SOURCES: 6, + + CONTAINER_TYPE_LAST: 7, + ATTACHABLE_BEGIN: 0, // ATTRIB_LOCATION_BINDING + ATTACHABLE_END: 5 + 1 // PROGRAM_SEPARABLE + 1 +}; + +/** + * @constructor + */ +gluShaderProgram.AttribLocationBinding = function(name, location) { + this.name = name; + this.location = location; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.ATTRIB_LOCATION_BINDING; + }; +}; + +/** + * @constructor + */ +gluShaderProgram.TransformFeedbackMode = function(mode) { + this.mode = mode; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_MODE; + }; +}; + +/** + * @constructor + * @param {string} name + */ +gluShaderProgram.TransformFeedbackVarying = function(name) { + /** @type {string} */ this.name = name; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYING; + }; +}; + +/** + * @constructor + * @param {Array<string>} array + */ +gluShaderProgram.TransformFeedbackVaryings = function(array) { + /** @type {Array<string>} */ this.array = array; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYINGS; + }; +}; + +/** + * @constructor + */ +gluShaderProgram.ProgramSeparable = function(separable) { + this.separable = separable; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.PROGRAM_SEPARABLE; + }; +}; + +/** + * @constructor + */ +gluShaderProgram.VertexSource = function(str) { + this.shaderType = gluShaderProgram.shaderType.VERTEX; + this.source = str; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.SHADER_SOURCE; + }; +}; + +/** + * @constructor + */ +gluShaderProgram.FragmentSource = function(str) { + this.shaderType = gluShaderProgram.shaderType.FRAGMENT; + this.source = str; + + this.getContainerType = function() { + return gluShaderProgram.containerTypes.SHADER_SOURCE; + }; +}; + +/** + * Create gluShaderProgram.ProgramSources. + * @constructor + */ +gluShaderProgram.ProgramSources = function() { + /** @type {Array<gluShaderProgram.ShaderInfo>} */ this.sources = []; + this.attribLocationBindings = []; + /** @type {Array<string>} */ this.transformFeedbackVaryings = []; + this.transformFeedbackBufferMode = 0; + this.separable = false; +}; + +gluShaderProgram.ProgramSources.prototype.getContainerType = function() { + return gluShaderProgram.containerTypes.PROGRAM_SOURCES; +}; + +gluShaderProgram.ProgramSources.prototype.add = function(item) { + var type = undefined; + if (typeof(item.getContainerType) == 'function') { + type = item.getContainerType(); + if ( + typeof(type) != 'number' || + type < gluShaderProgram.containerTypes.ATTACHABLE_BEGIN || + type >= gluShaderProgram.containerTypes.ATTACHABLE_END + ) { + type = undefined; + } + } + + switch (type) { + case gluShaderProgram.containerTypes.ATTRIB_LOCATION_BINDING: + this.attribLocationBindings.push(item); + break; + + case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_MODE: + this.transformFeedbackBufferMode = item.mode; + break; + + case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYING: + this.transformFeedbackVaryings.push(item.name); + break; + + case gluShaderProgram.containerTypes.TRANSFORM_FEEDBACK_VARYINGS: + this.transformFeedbackVaryings = this.transformFeedbackVaryings.concat(item.array); + break; + + case gluShaderProgram.containerTypes.SHADER_SOURCE: + this.sources.push(new gluShaderProgram.ShaderInfo(item.shaderType, item.source)); + break; + + case gluShaderProgram.containerTypes.PROGRAM_SEPARABLE: + this.separable = item.separable; + break; + + default: + throw new Error('Type \"' + type + '\" cannot be added to gluShaderProgram.ProgramSources.'); + break; + } + + return this; +}; + +/** + * //! Helper for constructing vertex-fragment source pair. + * @param {string} vertexSrc + * @param {string} fragmentSrc + * @return {gluShaderProgram.ProgramSources} + */ +gluShaderProgram.makeVtxFragSources = function(vertexSrc, fragmentSrc) { + /** @type {gluShaderProgram.ProgramSources} */ var sources = new gluShaderProgram.ProgramSources(); + sources.sources.push(gluShaderProgram.genVertexSource(vertexSrc)); + sources.sources.push(gluShaderProgram.genFragmentSource(fragmentSrc)); + return sources; +}; + +}); |