summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js510
1 files changed, 510 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js
new file mode 100644
index 0000000000..baa05a9708
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js
@@ -0,0 +1,510 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality 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.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+
+var gluDrawUtil = framework.opengl.gluDrawUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+/**
+ * Description of a vertex array binding
+ * @constructor
+ * @param {number} type GL gluDrawUtil.Type of data
+ * @param {(number|undefined)} location Binding location
+ * @param {number} components Number of components per vertex
+ * @param {number} elements Number of elements in the array
+ * @param {Array<number>} data Source data
+ * @param {number=} stride
+ * @param {number=} offset
+ */
+gluDrawUtil.VertexArrayBinding = function(type, location, components, elements, data, stride, offset) {
+ this.type = type;
+ this.location = location === undefined ? -1 : location;
+ this.components = components;
+ this.elements = elements;
+ this.data = data;
+ /** @type {?string} */ this.name = null;
+ this.stride = stride || 0;
+ this.offset = offset || 0;
+};
+
+/**
+ * Description of a vertex array binding
+ * @param {gluDrawUtil.BindingPoint} binding
+ * @param {gluDrawUtil.VertexArrayPointer} pointer
+ * @param {number=} dataType GL Data Type
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.vabFromBindingPointAndArrayPointer = function(binding, pointer, dataType) {
+ var type = dataType === undefined ? gl.FLOAT : dataType;
+ var location = binding.location;
+ var components = pointer.numComponents;
+ var elements = pointer.numElements;
+ var data = pointer.data;
+ var vaBinding = new gluDrawUtil.VertexArrayBinding(type, location, components, elements, data);
+ vaBinding.componentType = pointer.componentType;
+ vaBinding.name = binding.name;
+ vaBinding.convert = pointer.convert;
+ vaBinding.stride = pointer.stride;
+ return vaBinding;
+};
+
+/**
+ * ! Lower named bindings to locations and eliminate bindings that are not used by program.
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {WebGLProgram} program
+ * @param {Array} inputArray - Array with the named binding locations
+ * @param {Array=} outputArray - Array with the lowered locations
+ * @return {Array} outputArray
+ */
+gluDrawUtil.namedBindingsToProgramLocations = function(gl, program, inputArray, outputArray) {
+ outputArray = outputArray || [];
+
+ for (var i = 0; i < inputArray.length; i++) {
+ var cur = inputArray[i];
+ if (cur.name) {
+ //assert(binding.location >= 0);
+ var location = gl.getAttribLocation(program, cur.name);
+ if (location >= 0) {
+ if (cur.location >= 0)
+ location += cur.location;
+ // Add binding.location as an offset to accomodate matrices.
+ outputArray.push(new gluDrawUtil.VertexArrayBinding(cur.type, location, cur.components, cur.elements, cur.data, cur.stride, cur.offset));
+ }
+ } else {
+ outputArray.push(cur);
+ }
+ }
+
+ return outputArray;
+};
+
+/**
+ * Creates vertex buffer, binds it and draws elements
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {WebGLProgram} program ID, vertexProgramID
+ * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays
+ * @param {gluDrawUtil.PrimitiveList} primitives to gluDrawUtil.draw
+ * @param { {beforeDrawCall:function(), afterDrawCall:function()}=} callback
+ */
+gluDrawUtil.draw = function(gl, program, vertexArrays, primitives, callback) {
+ /** TODO: finish implementation */
+ /** @type {Array<WebGLBuffer>} */ var objects = [];
+
+ // Lower bindings to locations
+ vertexArrays = gluDrawUtil.namedBindingsToProgramLocations(gl, program, vertexArrays);
+
+ for (var i = 0; i < vertexArrays.length; i++) {
+ /** @type {WebGLBuffer} */ var buffer = gluDrawUtil.vertexBuffer(gl, vertexArrays[i]);
+ objects.push(buffer);
+ }
+
+ if (primitives.indices) {
+ /** @type {WebGLBuffer} */ var elemBuffer = gluDrawUtil.indexBuffer(gl, primitives);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer);
+
+ if (callback)
+ callback.beforeDrawCall();
+
+ gluDrawUtil.drawIndexed(gl, primitives, 0);
+
+ if (callback)
+ callback.afterDrawCall();
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ } else {
+ if (callback)
+ callback.beforeDrawCall();
+
+ gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, primitives.type), 0, primitives.numElements);
+
+ if (callback)
+ callback.afterDrawCall();
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'drawArrays', false, true);
+ for (var i = 0; i < vertexArrays.length; i++) {
+ gl.disableVertexAttribArray(vertexArrays[i].location);
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+};
+
+/**
+ * Creates vertex buffer, binds it and draws elements
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.PrimitiveList} primitives Primitives to gluDrawUtil.draw
+ * @param {number} offset
+ */
+gluDrawUtil.drawIndexed = function(gl, primitives, offset) {
+/** @type {number} */ var mode = gluDrawUtil.getPrimitiveGLType(gl, primitives.type);
+ /** TODO: C++ implementation supports different index types, we use only int16.
+ Could it cause any issues?
+
+ deUint32 indexGLType = getIndexGLType(primitives.indexType);
+ */
+
+ gl.drawElements(mode, primitives.indices.length, gl.UNSIGNED_SHORT, offset);
+};
+
+/**
+ * Enums for primitive types
+ * @enum
+ */
+gluDrawUtil.primitiveType = {
+ TRIANGLES: 0,
+ TRIANGLE_STRIP: 1,
+ TRIANGLE_FAN: 2,
+
+ LINES: 3,
+ LINE_STRIP: 4,
+ LINE_LOOP: 5,
+
+ POINTS: 6,
+
+ PATCHES: 7
+};
+
+/**
+ * get GL type from primitive type
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
+ * @return {number} GL primitive type
+ */
+gluDrawUtil.getPrimitiveGLType = function(gl, type) {
+ switch (type) {
+ case gluDrawUtil.primitiveType.TRIANGLES: return gl.TRIANGLES;
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return gl.TRIANGLE_STRIP;
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN: return gl.TRIANGLE_FAN;
+ case gluDrawUtil.primitiveType.LINES: return gl.LINES;
+ case gluDrawUtil.primitiveType.LINE_STRIP: return gl.LINE_STRIP;
+ case gluDrawUtil.primitiveType.LINE_LOOP: return gl.LINE_LOOP;
+ case gluDrawUtil.primitiveType.POINTS: return gl.POINTS;
+// case gluDrawUtil.primitiveType.PATCHES: return gl.PATCHES;
+ default:
+ throw new Error('Unknown primitive type ' + type);
+ }
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Points
+ * @param {number} numElements
+ */
+gluDrawUtil.pointsFromElements = function(numElements) {
+ return new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.POINTS, numElements);
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Triangles
+ * @param {Array<number>} indices
+ */
+gluDrawUtil.triangles = function(indices) {
+ return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.TRIANGLES, indices);
+};
+
+/**
+ * Calls gluDrawUtil.newPrimitiveListFromIndices() to create primitive list for Patches
+ * @param {Array<number>} indices
+ */
+gluDrawUtil.patches = function(indices) {
+ return gluDrawUtil.newPrimitiveListFromIndices(gluDrawUtil.primitiveType.PATCHES, indices);
+};
+
+/**
+ * Creates primitive list for Triangles or Patches, depending on type
+ * @param {gluDrawUtil.primitiveType} type gluDrawUtil.primitiveType
+ * @param {number} numElements
+ * @constructor
+ */
+gluDrawUtil.PrimitiveList = function(type, numElements) {
+ this.type = type;
+ this.indices = 0;
+ this.numElements = numElements;
+};
+
+/**
+ * @param {gluDrawUtil.primitiveType} type
+ * @param {Array<number>} indices
+ * @return {gluDrawUtil.PrimitiveList}
+ */
+gluDrawUtil.newPrimitiveListFromIndices = function(type, indices) {
+ /** @type {gluDrawUtil.PrimitiveList} */ var primitiveList = new gluDrawUtil.PrimitiveList(type, 0);
+ primitiveList.indices = indices;
+ return primitiveList;
+};
+
+/**
+ * Create Element Array Buffer
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.PrimitiveList} primitives to construct the buffer from
+ * @return {WebGLBuffer} indexObject buffer with elements
+ */
+gluDrawUtil.indexBuffer = function(gl, primitives) {
+ /** @type {WebGLBuffer} */ var indexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(primitives.indices), gl.STATIC_DRAW);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ return indexObject;
+};
+
+/**
+ * Create Array Buffer
+ * @param {WebGL2RenderingContext} gl WebGL context
+ * @param {gluDrawUtil.VertexArrayBinding} vertexArray primitives, Array buffer descriptor
+ * @return {WebGLBuffer} buffer of vertices
+ */
+gluDrawUtil.vertexBuffer = function(gl, vertexArray) {
+ /** @type {goog.TypedArray} */ var typedArray;
+ switch (vertexArray.type) {
+ case gl.BYTE: typedArray = new Int8Array(vertexArray.data); break;
+ case gl.UNSIGNED_BYTE: typedArray = new Uint8Array(vertexArray.data); break;
+ case gl.SHORT: typedArray = new Int16Array(vertexArray.data); break;
+ case gl.UNSIGNED_SHORT: typedArray = new Uint16Array(vertexArray.data); break;
+ case gl.INT: typedArray = new Int32Array(vertexArray.data); break;
+ case gl.UNSIGNED_INT: typedArray = new Uint32Array(vertexArray.data); break;
+ default: typedArray = new Float32Array(vertexArray.data); break;
+ }
+
+ /** @type {WebGLBuffer} */ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bindBuffer', false, true);
+ gl.bufferData(gl.ARRAY_BUFFER, typedArray, gl.STATIC_DRAW);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'bufferData', false, true);
+ gl.enableVertexAttribArray(vertexArray.location);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'enableVertexAttribArray', false, true);
+ if (vertexArray.type === gl.FLOAT) {
+ gl.vertexAttribPointer(vertexArray.location, vertexArray.components, vertexArray.type, false, vertexArray.stride, vertexArray.offset);
+ } else {
+ gl.vertexAttribIPointer(vertexArray.location, vertexArray.components, vertexArray.type, vertexArray.stride, vertexArray.offset);
+ }
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'vertexAttribPointer', false, true);
+ return buffer;
+};
+
+/**
+ * @param {Array<number>} rgba
+ * @constructor
+ */
+gluDrawUtil.Pixel = function(rgba) {
+ this.rgba = rgba;
+};
+
+gluDrawUtil.Pixel.prototype.getRed = function() {
+ return this.rgba[0];
+};
+gluDrawUtil.Pixel.prototype.getGreen = function() {
+ return this.rgba[1];
+};
+gluDrawUtil.Pixel.prototype.getBlue = function() {
+ return this.rgba[2];
+};
+gluDrawUtil.Pixel.prototype.getAlpha = function() {
+ return this.rgba[3];
+};
+gluDrawUtil.Pixel.prototype.equals = function(otherPixel) {
+ return this.rgba[0] == otherPixel.rgba[0] &&
+ this.rgba[1] == otherPixel.rgba[1] &&
+ this.rgba[2] == otherPixel.rgba[2] &&
+ this.rgba[3] == otherPixel.rgba[3];
+};
+
+/**
+ * @constructor
+ */
+gluDrawUtil.Surface = function() {
+};
+
+gluDrawUtil.Surface.prototype.readSurface = function(gl, x, y, width, height) {
+ this.buffer = new Uint8Array(width * height * 4);
+ gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, this.buffer);
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ return this.buffer;
+};
+
+gluDrawUtil.Surface.prototype.getPixel = function(x, y) {
+ /** @type {number} */ var base = (x + y * this.width) * 4;
+ /** @type {Array<number>} */
+ var rgba = [
+ this.buffer[base],
+ this.buffer[base + 1],
+ this.buffer[base + 2],
+ this.buffer[base + 3]
+ ];
+ return new gluDrawUtil.Pixel(rgba);
+};
+
+gluDrawUtil.Surface.prototype.getPixelUintRGB8 = function(x, y) {
+ /** @type {number} */ var base = (x + y * this.width) * 4;
+ /** @type {number} */
+ return (this.buffer[base] << 16) +
+ (this.buffer[base + 1] << 8) +
+ this.buffer[base + 2];
+};
+
+/**
+ * @enum
+ */
+gluDrawUtil.VertexComponentType = {
+ // Standard types: all conversion types apply.
+ VTX_COMP_UNSIGNED_INT8: 0,
+ VTX_COMP_UNSIGNED_INT16: 1,
+ VTX_COMP_UNSIGNED_INT32: 2,
+ VTX_COMP_SIGNED_INT8: 3,
+ VTX_COMP_SIGNED_INT16: 4,
+ VTX_COMP_SIGNED_INT32: 5,
+
+ // Special types: only CONVERT_NONE is allowed.
+ VTX_COMP_FIXED: 6,
+ VTX_COMP_HALF_FLOAT: 7,
+ VTX_COMP_FLOAT: 8
+};
+
+/**
+ * @enum
+ */
+gluDrawUtil.VertexComponentConversion = {
+ VTX_COMP_CONVERT_NONE: 0, //!< No conversion: integer types, or floating-point values.
+ VTX_COMP_CONVERT_NORMALIZE_TO_FLOAT: 1, //!< Normalize integers to range [0,1] or [-1,1] depending on type.
+ VTX_COMP_CONVERT_CAST_TO_FLOAT: 2 //!< Convert to floating-point directly.
+};
+
+/**
+ * gluDrawUtil.VertexArrayPointer
+ * @constructor
+ * @param {gluDrawUtil.VertexComponentType} componentType_
+ * @param {gluDrawUtil.VertexComponentConversion} convert_
+ * @param {number} numComponents_
+ * @param {number} numElements_
+ * @param {number} stride_
+ * @const @param {Array<number>} data_
+ */
+gluDrawUtil.VertexArrayPointer = function(componentType_, convert_, numComponents_, numElements_, stride_, data_) {
+ this.componentType = componentType_;
+ this.convert = convert_;
+ this.numComponents = numComponents_;
+ this.numElements = numElements_;
+ this.stride = stride_;
+ this.data = data_;
+};
+
+/**
+ * gluDrawUtil.BindingPoint
+ * @constructor
+ * @param {string} name
+ * @param {number} location
+ * @param {number=} offset
+ */
+gluDrawUtil.BindingPoint = function(name, location, offset) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.location = location;
+ /** @type {number} */ this.offset = offset || 0;
+};
+
+/**
+ * bindingPointFromLocation
+ * @param {number} location
+ * return {gluDrawUtil.BindingPoint}
+ */
+gluDrawUtil.bindingPointFromLocation = function(location) {
+ return new gluDrawUtil.BindingPoint('', location);
+};
+
+/**
+ * bindingPointFromName
+ * @param {string} name
+ * @param {number=} location
+ * return {gluDrawUtil.BindingPoint}
+ */
+gluDrawUtil.bindingPointFromName = function(name, location) {
+ location = location === undefined ? -1 : location;
+ return new gluDrawUtil.BindingPoint(name, location);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newInt32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_SIGNED_INT32,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.INT);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newUint32VertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_UNSIGNED_INT32,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer, gl.UNSIGNED_INT);
+};
+
+/**
+ * @param {string} name
+ * @param {number} numComponents
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newFloatVertexArrayBinding = function(name, numComponents, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, numComponents, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
+};
+
+/**
+ * @param {string} name
+ * @param {number} column
+ * @param {number} rows
+ * @param {number} numElements
+ * @param {number} stride
+ * @param {Array<number>} data
+ * @return {gluDrawUtil.VertexArrayBinding}
+ */
+gluDrawUtil.newFloatColumnVertexArrayBinding = function(name, column, rows, numElements, stride, data) {
+ var bindingPoint = gluDrawUtil.bindingPointFromName(name);
+ bindingPoint.location = column;
+ var arrayPointer = new gluDrawUtil.VertexArrayPointer(gluDrawUtil.VertexComponentType.VTX_COMP_FLOAT,
+ gluDrawUtil.VertexComponentConversion.VTX_COMP_CONVERT_NONE, rows, numElements, stride, data);
+ return gluDrawUtil.vabFromBindingPointAndArrayPointer(bindingPoint, arrayPointer);
+};
+
+});