/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Shader execution utilities.
 *//*--------------------------------------------------------------------*/
'use strict';
goog.provide('modules.shared.glsShaderExecUtil');
goog.require('framework.common.tcuMatrix');
goog.require('framework.common.tcuMatrixUtil');
goog.require('framework.common.tcuTexture');
goog.require('framework.opengl.gluDrawUtil');
goog.require('framework.opengl.gluShaderProgram');
goog.require('framework.opengl.gluShaderUtil');
goog.require('framework.opengl.gluTextureUtil');
goog.require('framework.opengl.gluVarType');

goog.scope(function() {

    var glsShaderExecUtil = modules.shared.glsShaderExecUtil;
    var gluVarType = framework.opengl.gluVarType;
    var gluShaderUtil = framework.opengl.gluShaderUtil;
    var gluShaderProgram = framework.opengl.gluShaderProgram;
    var gluDrawUtil = framework.opengl.gluDrawUtil;
    var gluTextureUtil = framework.opengl.gluTextureUtil;
    var tcuTexture = framework.common.tcuTexture;
    var tcuMatrix = framework.common.tcuMatrix;
    var tcuMatrixUtil = framework.common.tcuMatrixUtil;

    var DE_ASSERT = function(x) {
        if (!x)
            throw new Error('Assert failed');
    };

    var setParentClass = function(child, parent) {
        child.prototype = Object.create(parent.prototype);
        child.prototype.constructor = child;
    };

    /**
     * @constructor
     * @param {string=} name
     * @param {gluVarType.VarType=} varType
     */
    glsShaderExecUtil.Symbol = function(name, varType) {
        name = name === undefined ? '<unnamed>' : name;
        /** @type {string} */ this.name = name;
        /** @type {gluVarType.VarType} */ this.varType = varType || null;
    };

    //! Complete shader specification.
    /**
     * @constructor
     */
    glsShaderExecUtil.ShaderSpec = function() {
        /** @type {gluShaderUtil.GLSLVersion} */ this.version = gluShaderUtil.GLSLVersion.V300_ES; //!< Shader version.
        /** @type {Array<glsShaderExecUtil.Symbol>} */ this.inputs = [];
        /** @type {Array<glsShaderExecUtil.Symbol>} */ this.outputs = [];
        /** @type {string} */ this.globalDeclarations = ''; //!< These are placed into global scope. Can contain uniform declarations for example.
        /** @type {*} */ this.source; //!< Source snippet to be executed.
    };

    /**
     * Base class for shader executor.
     * @constructor
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     */
    glsShaderExecUtil.ShaderExecutor = function(shaderSpec) {
        /** @type {Array<glsShaderExecUtil.Symbol>} */ this.m_inputs = shaderSpec.inputs;
        /** @type {Array<glsShaderExecUtil.Symbol>} */ this.m_outputs = shaderSpec.outputs;
    };

    glsShaderExecUtil.ShaderExecutor.prototype.useProgram = function() {
        DE_ASSERT(this.isOk);
        gl.useProgram(this.getProgram());
    };

    /**
     * @return {boolean}
     */
    glsShaderExecUtil.ShaderExecutor.prototype.isOk = function() {
        throw new Error('Virtual function. Please override.');
    };

    /**
     * @return {WebGLProgram}
     */
    glsShaderExecUtil.ShaderExecutor.prototype.getProgram = function() {
        throw new Error('Virtual function. Please override.');
    };

    /**
     * @param {number} numValues
     * @param {Array<Array<number>>} inputs
     * @return {Array<goog.TypedArray>} outputs
     */
    glsShaderExecUtil.ShaderExecutor.prototype.execute = function(numValues, inputs) {
        throw new Error('Virtual function. Please override.');
    };

    /**
     * Base class for shader executor.
     * @param {gluShaderProgram.shaderType} shaderType
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     * @return {glsShaderExecUtil.ShaderExecutor}
     */
    glsShaderExecUtil.createExecutor = function(shaderType, shaderSpec) {
        switch (shaderType) {
            case gluShaderProgram.shaderType.VERTEX: return new glsShaderExecUtil.VertexShaderExecutor(shaderSpec);
            case gluShaderProgram.shaderType.FRAGMENT: return new glsShaderExecUtil.FragmentShaderExecutor(shaderSpec);
            default:
                throw new Error('Unsupported shader type: ' + shaderType);
        }
    };

    /**
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     * @return {string}
     */
    glsShaderExecUtil.generateVertexShader = function(shaderSpec) {
        /** @type {boolean} */ var usesInout = true;
        /** @type {string} */ var in_ = usesInout ? 'in' : 'attribute';
        /** @type {string} */ var out = usesInout ? 'out' : 'varying';
        /** @type {string} */ var src = '';
        /** @type {number} */ var vecSize;
        /** @type {gluShaderUtil.DataType} */ var intBaseType;

        src += '#version 300 es\n';

        if (shaderSpec.globalDeclarations.length > 0)
            src += (shaderSpec.globalDeclarations + '\n');

        for (var i = 0; i < shaderSpec.inputs.length; ++i)
            src += (in_ + ' ' + gluVarType.declareVariable(shaderSpec.inputs[i].varType, shaderSpec.inputs[i].name) + ';\n');

        for (var i = 0; i < shaderSpec.outputs.length; i++) {
            var output = shaderSpec.outputs[i];
            DE_ASSERT(output.varType.isBasicType());

            if (gluShaderUtil.isDataTypeBoolOrBVec(output.varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeScalarSize(output.varType.getBasicType());
                intBaseType = vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT;
                /** @type {gluVarType.VarType} */ var intType = new gluVarType.VarType().VarTypeBasic(intBaseType, gluShaderUtil.precision.PRECISION_HIGHP);

                src += ('flat ' + out + ' ' + gluVarType.declareVariable(intType, 'o_' + output.name) + ';\n');
            } else
                src += ('flat ' + out + ' ' + gluVarType.declareVariable(output.varType, output.name) + ';\n');
        }

        src += '\n' +
            'void main (void)\n' +
            '{\n' +
            ' gl_Position = vec4(0.0);\n' +
            ' gl_PointSize = 1.0;\n\n';

        // Declare necessary output variables (bools).
        for (var i = 0; i < shaderSpec.outputs.length; i++) {
            if (gluShaderUtil.isDataTypeBoolOrBVec(shaderSpec.outputs[i].varType.getBasicType()))
                src += ('\t' + gluVarType.declareVariable(shaderSpec.outputs[i].varType, shaderSpec.outputs[i].name) + ';\n');
        }

        //Operation - indented to correct level.
        // TODO: Add indenting
        src += shaderSpec.source;

        // Assignments to outputs.
        for (var i = 0; i < shaderSpec.outputs.length; i++) {
            if (gluShaderUtil.isDataTypeBoolOrBVec(output.varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeScalarSize(output.varType.getBasicType());
                intBaseType = vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT;

                src += ('\to_' + output.name + ' = ' + gluShaderUtil.getDataTypeName(intBaseType) + '(' + output.name + ');\n');
            }
        }

        src += '}\n';

        return src;
    };

    /**
     * @return {string}
     */
    glsShaderExecUtil.generateEmptyFragmentSource = function() {
        /** @type {boolean} */ var customOut = true;
        /** @type {string} */ var src;

        src = '#version 300 es\n';

        // \todo [2013-08-05 pyry] Do we need one dummy output?

        src += 'void main (void)\n{\n';
        if (!customOut)
            src += ' gl.FragColor = vec4(0.0);\n';
        src += '}\n';

        return src;
    };

    /**
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     * @param {string} inputPrefix
     * @param {string} outputPrefix
     * @return {string}
     */
    glsShaderExecUtil.generatePassthroughVertexShader = function(shaderSpec, inputPrefix, outputPrefix) {
        // flat qualifier is not present in earlier versions?
        // DE_ASSERT(glu::glslVersionUsesInOutQualifiers(shaderSpec.version));

        /** @type {string} */ var src;

        src = '#version 300 es\n' +
            'in highp vec4 a_position;\n';

        for (var i = 0; i < shaderSpec.inputs.length; i++) {
            src += ('in ' + gluVarType.declareVariable(shaderSpec.inputs[i].varType, inputPrefix + shaderSpec.inputs[i].name) + ';\n' +
                'flat out ' + gluVarType.declareVariable(shaderSpec.inputs[i].varType, outputPrefix + shaderSpec.inputs[i].name) + ';\n');
        }

        src += '\nvoid main (void)\n{\n' +
            ' gl_Position = a_position;\n' +
            ' gl_PointSize = 1.0;\n';

        for (var i = 0; i < shaderSpec.inputs.length; i++)
            src += ('\t' + outputPrefix + shaderSpec.inputs[i].name + ' = ' + inputPrefix + shaderSpec.inputs[i].name + ';\n');

        src += '}\n';

        return src;
    };

    /**
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     * @param {boolean} useIntOutputs
     * @param {*} outLocationMap
     * @return {string}
     */
    glsShaderExecUtil.generateFragmentShader = function(shaderSpec, useIntOutputs, outLocationMap) {
        /** @type {number} */ var vecSize;
        /** @type {number} */ var numVecs;
        /** @type {gluShaderUtil.DataType} */ var intBasicType;
        /** @type {gluShaderUtil.DataType} */ var uintBasicType;
        /** @type {gluVarType.VarType} */ var uintType;
        /** @type {gluVarType.VarType} */ var intType;

        /** @type {string} */ var src;
        src = '#version 300 es\n';

        if (!shaderSpec.globalDeclarations.length > 0)
            src += (shaderSpec.globalDeclarations + '\n');

        for (var i = 0; i < shaderSpec.inputs.length; i++)
            src += ('flat in ' + gluVarType.declareVariable(shaderSpec.inputs[i].varType, shaderSpec.inputs[i].name) + ';\n');

        for (var outNdx = 0; outNdx < shaderSpec.outputs.length; ++outNdx) {
            /** @type {glsShaderExecUtil.Symbol} */ var output = shaderSpec.outputs[outNdx];
            /** @type {number} */ var location = outLocationMap[output.name];
            /** @type {string} */ var outVarName = 'o_' + output.name;
            /** @type {gluVarType.VariableDeclaration} */ var decl = new gluVarType.VariableDeclaration(output.varType, outVarName, gluVarType.Storage.STORAGE_OUT, undefined, new gluVarType.Layout(location));

            DE_ASSERT(output.varType.isBasicType());

            if (useIntOutputs && gluShaderUtil.isDataTypeFloatOrVec(output.varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeScalarSize(output.varType.getBasicType());
                uintBasicType = vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize) : gluShaderUtil.DataType.UINT;
                uintType = gluVarType.newTypeBasic(uintBasicType, gluShaderUtil.precision.PRECISION_HIGHP);

                decl.varType = uintType;
                src += (decl + ';\n');
            } else if (gluShaderUtil.isDataTypeBoolOrBVec(output.varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeScalarSize(output.varType.getBasicType());
                intBasicType = vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT;
                intType = gluVarType.newTypeBasic(intBasicType, gluShaderUtil.precision.PRECISION_HIGHP);

                decl.varType = intType;
                src += (decl + ';\n');
            } else if (gluShaderUtil.isDataTypeMatrix(output.varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeMatrixNumRows(output.varType.getBasicType());
                numVecs = gluShaderUtil.getDataTypeMatrixNumColumns(output.varType.getBasicType());
                uintBasicType = gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize);
                uintType = gluVarType.newTypeBasic(uintBasicType, gluShaderUtil.precision.PRECISION_HIGHP);

                decl.varType = uintType;
                for (var vecNdx = 0; vecNdx < numVecs; ++vecNdx) {
                    decl.name = outVarName + '_' + (vecNdx);
                    decl.layout.location = location + vecNdx;
                    src += (decl + ';\n');
                }
            } else //src += '';//glu::VariableDeclaration(output.varType, output.name, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, location) << ";\n";
                src += new gluVarType.VariableDeclaration(output.varType, output.name, gluVarType.Storage.STORAGE_OUT, undefined, new gluVarType.Layout(location)) + ';\n';
        }

        src += '\nvoid main (void)\n{\n';

        for (var i = 0; i < shaderSpec.outputs.length; i++) {
            if ((useIntOutputs && gluShaderUtil.isDataTypeFloatOrVec(shaderSpec.outputs[i].varType.getBasicType())) ||
                gluShaderUtil.isDataTypeBoolOrBVec(shaderSpec.outputs[i].varType.getBasicType()) ||
                gluShaderUtil.isDataTypeMatrix(shaderSpec.outputs[i].varType.getBasicType()))
                src += ('\t' + gluVarType.declareVariable(shaderSpec.outputs[i].varType, shaderSpec.outputs[i].name) + ';\n');
        }

        // Operation - indented to correct level.
        // TODO: Add indenting
        src += shaderSpec.source;
        // {
        //     std::istringstream opSrc (shaderSpec.source);
        //     /** @type{number} */ var line;
        //
        //     while (std::getline(opSrc, line))
        //         src += ('\t' << line << '\n');
        // }

        for (var i = 0; i < shaderSpec.outputs.length; i++) {
            if (useIntOutputs && gluShaderUtil.isDataTypeFloatOrVec(shaderSpec.outputs[i].varType.getBasicType()))
                src += (' o_' + shaderSpec.outputs[i].name + ' = floatBitsToUint(' + shaderSpec.outputs[i].name + ');\n');
            else if (gluShaderUtil.isDataTypeMatrix(shaderSpec.outputs[i].varType.getBasicType())) {
                numVecs = gluShaderUtil.getDataTypeMatrixNumColumns(shaderSpec.outputs[i].varType.getBasicType());

                for (var vecNdx = 0; vecNdx < numVecs; ++vecNdx)
                    if (useIntOutputs)
                        src += ('\to_' + shaderSpec.outputs[i].name + '_' + vecNdx + ' = floatBitsToUint(' + shaderSpec.outputs[i].name + '[' + vecNdx + ']);\n');
                    else
                        src += ('\to_' + shaderSpec.outputs[i].name + '_' + vecNdx + ' = ' + shaderSpec.outputs[i].name + '[' + vecNdx + '];\n');
            } else if (gluShaderUtil.isDataTypeBoolOrBVec(shaderSpec.outputs[i].varType.getBasicType())) {
                vecSize = gluShaderUtil.getDataTypeScalarSize(shaderSpec.outputs[i].varType.getBasicType());
                intBasicType = vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT;

                src += ('\to_' + shaderSpec.outputs[i].name + ' = ' + gluShaderUtil.getDataTypeName(intBasicType) + '(' + shaderSpec.outputs[i].name + ');\n');
            }
        }

        src += '}\n';

        return src;
    };

    /**
     * @param {Array<glsShaderExecUtil.Symbol>} outputs
     * @return {gluShaderProgram.TransformFeedbackVaryings}
     */
    glsShaderExecUtil.getTFVaryings = function(outputs) {
        var names = [];
        for (var i = 0; i < outputs.length; i++) {
            if (gluShaderUtil.isDataTypeBoolOrBVec(outputs[i].varType.getBasicType())) {
                names.push('o_' + outputs[i].name);
            } else {
                names.push(outputs[i].name);
            }
        }
        return new gluShaderProgram.TransformFeedbackVaryings(names);
    };

    // VertexProcessorExecutor (base class for vertex and geometry executors)

    /**
     * @constructor
     * @extends {glsShaderExecUtil.ShaderExecutor}
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     * @param {gluShaderProgram.ProgramSources} sources
     */
    glsShaderExecUtil.VertexProcessorExecutor = function(shaderSpec, sources) {
        sources.add(glsShaderExecUtil.getTFVaryings(shaderSpec.outputs));
        sources.add(new gluShaderProgram.TransformFeedbackMode(gl.INTERLEAVED_ATTRIBS));
        glsShaderExecUtil.ShaderExecutor.call(this, shaderSpec);
        this.m_program = new gluShaderProgram.ShaderProgram(gl, sources);
    };

    setParentClass(glsShaderExecUtil.VertexProcessorExecutor, glsShaderExecUtil.ShaderExecutor);

    /**
     * @return {boolean}
     */
    glsShaderExecUtil.VertexProcessorExecutor.prototype.isOk = function() {
        return this.m_program.isOk();
    };

    /**
     * @return {WebGLProgram}
     */
    glsShaderExecUtil.VertexProcessorExecutor.prototype.getProgram = function() {
        return this.m_program.getProgram();
    };

    /**
     * @param {Array<*>} arr
     * @return {number}
     */
    glsShaderExecUtil.computeTotalScalarSize = function(arr) {
        /** @type {number} */ var size = 0;
        for (var i = 0; i < arr.length; i++)
            size += arr[i].varType.getScalarSize();
        return size;
    };

    /**
     * @param {Array<number>} ptr
     * @param {number} colNdx
     * @param {number} size Column size
     * @return {Array<number>}
     */
    glsShaderExecUtil.getColumn = function(ptr, colNdx, size) {
        var begin = colNdx * size;
        var end = (colNdx + 1) * size;
        return ptr.slice(begin, end);
    };

    glsShaderExecUtil.VertexProcessorExecutor.prototype.execute = function(numValues, inputs) {
        /** @type {glsShaderExecUtil.Symbol} */ var symbol;
        var outputs = [];
        /** @type {boolean} */ var useTFObject = true;
        /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [];
        var transformFeedback = gl.createTransformFeedback();
        var outputBuffer = gl.createBuffer();

        /** @type {number} */ var outputBufferStride = glsShaderExecUtil.computeTotalScalarSize(this.m_outputs) * 4;

        // Setup inputs.
        for (var inputNdx = 0; inputNdx < this.m_inputs.length; inputNdx++) {
            symbol = this.m_inputs[inputNdx];
            /*const void* */var ptr = inputs[inputNdx];
            /** @type {gluShaderUtil.DataType} */ var basicType = symbol.varType.getBasicType();
            /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(basicType);

            if (gluShaderUtil.isDataTypeFloatOrVec(basicType))
                vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding(symbol.name, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeIntOrIVec(basicType))
                vertexArrays.push(gluDrawUtil.newInt32VertexArrayBinding(symbol.name, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeUintOrUVec(basicType))
                vertexArrays.push(gluDrawUtil.newUint32VertexArrayBinding(symbol.name, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeMatrix(basicType)) {
                /** @type {number} */ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(basicType);
                /** @type {number} */ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(basicType);
                // A matrix consists of several (column-major) vectors. A buffer is created for
                // every vector in gluDrawUtil.draw() below. Data in every buffer will be tightly
                // packed. So the stride should be 0. This is different from the code in native
                // deqp, which use only one buffer for a matrix, the data is interleaved.
                /** @type {number} */ var stride = 0;

                for (var colNdx = 0; colNdx < numCols; ++colNdx)
                    vertexArrays.push(gluDrawUtil.newFloatColumnVertexArrayBinding(symbol.name,
                        colNdx,
                        numRows,
                        numValues,
                        stride,
                        glsShaderExecUtil.getColumn(ptr, colNdx, numRows * numValues)));
            } else
                DE_ASSERT(false);
        }

        // Setup TF outputs.
        if (useTFObject)
            gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
        gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, outputBuffer);
        gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, outputBufferStride * numValues, gl.STREAM_READ);
        gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, outputBuffer);

        // Draw with rasterization disabled.
        gl.beginTransformFeedback(gl.POINTS);
        gl.enable(gl.RASTERIZER_DISCARD);
        gluDrawUtil.draw(gl, this.m_program.getProgram(), vertexArrays,
            new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.POINTS, numValues));
        gl.disable(gl.RASTERIZER_DISCARD);
        gl.endTransformFeedback();

        // Read back data.
        var result = new ArrayBuffer(outputBufferStride * numValues);
        gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, new Uint8Array(result));
        /** @type {number} */ var curOffset = 0; // Offset in buffer in bytes.

        for (var outputNdx = 0; outputNdx < this.m_outputs.length; outputNdx++) {
            symbol = this.m_outputs[outputNdx];
            /** @type {number} */ var scalarSize = symbol.varType.getScalarSize();
            var readPtr = new Uint8Array(result, curOffset);

            if (scalarSize * 4 === outputBufferStride)
                outputs[outputNdx] = readPtr;
            else {
                var dstPtr = new Uint8Array(scalarSize * numValues * 4);

                for (var ndx = 0; ndx < numValues; ndx++)
                    for (var j = 0; j < scalarSize * 4; j++) {
                        dstPtr[scalarSize * 4 * ndx + j] = readPtr[ndx * outputBufferStride + j];
                    }
                outputs[outputNdx] = dstPtr;
            }
            curOffset += scalarSize * 4;
          }

        if (useTFObject)
            gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
        gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);

        return outputs;
    };

    // VertexShaderExecutor

    /**
     * @constructor
     * @extends {glsShaderExecUtil.VertexProcessorExecutor}
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     */
    glsShaderExecUtil.VertexShaderExecutor = function(shaderSpec) {
        var sources = gluShaderProgram.makeVtxFragSources(glsShaderExecUtil.generateVertexShader(shaderSpec),
            glsShaderExecUtil.generateEmptyFragmentSource());
        glsShaderExecUtil.VertexProcessorExecutor.call(this, shaderSpec, sources);
    };

    setParentClass(glsShaderExecUtil.VertexShaderExecutor, glsShaderExecUtil.VertexProcessorExecutor);

    /**
     * @constructor
     * @extends {glsShaderExecUtil.ShaderExecutor}
     * @param {glsShaderExecUtil.ShaderSpec} shaderSpec
     */
    glsShaderExecUtil.FragmentShaderExecutor = function(shaderSpec) {
        glsShaderExecUtil.ShaderExecutor.call(this, shaderSpec);
        /** @type {Array<glsShaderExecUtil.Symbol>} */ this.m_outLocationSymbols = [];
        this.m_outLocationMap = glsShaderExecUtil.generateLocationMap(this.m_outputs, this.m_outLocationSymbols);
        var sources = gluShaderProgram.makeVtxFragSources(glsShaderExecUtil.generatePassthroughVertexShader(shaderSpec, 'a_', ''),
            glsShaderExecUtil.generateFragmentShader(shaderSpec, true, this.m_outLocationMap));
        this.m_program = new gluShaderProgram.ShaderProgram(gl, sources);
    };

    setParentClass(glsShaderExecUtil.FragmentShaderExecutor, glsShaderExecUtil.ShaderExecutor);

    /**
     * @return {boolean}
     */
    glsShaderExecUtil.FragmentShaderExecutor.prototype.isOk = function() {
        return this.m_program.isOk();
    };

    /**
     * @return {WebGLProgram}
     */
    glsShaderExecUtil.FragmentShaderExecutor.prototype.getProgram = function() {
        return this.m_program.getProgram();
    };

    /**
     * @param {gluVarType.VarType} outputType
     * @param {boolean} useIntOutputs
     * @return {tcuTexture.TextureFormat}
     */
    glsShaderExecUtil.getRenderbufferFormatForOutput = function(outputType, useIntOutputs) {
        var channelOrderMap = [
            tcuTexture.ChannelOrder.R,
            tcuTexture.ChannelOrder.RG,
            tcuTexture.ChannelOrder.RGBA, // No RGB variants available.
            tcuTexture.ChannelOrder.RGBA
        ];

        var basicType = outputType.getBasicType();
        var numComps = gluShaderUtil.getDataTypeNumComponents(basicType);
        var channelType;

        switch (gluShaderUtil.getDataTypeScalarType(basicType)) {
            case 'uint': channelType = tcuTexture.ChannelType.UNSIGNED_INT32; break;
            case 'int': channelType = tcuTexture.ChannelType.SIGNED_INT32; break;
            case 'bool': channelType = tcuTexture.ChannelType.SIGNED_INT32; break;
            case 'float': channelType = useIntOutputs ? tcuTexture.ChannelType.UNSIGNED_INT32 : tcuTexture.ChannelType.FLOAT; break;
            default:
                throw new Error('Invalid output type ' + gluShaderUtil.getDataTypeScalarType(basicType));
        }

        return new tcuTexture.TextureFormat(channelOrderMap[numComps - 1], channelType);
    };

    glsShaderExecUtil.FragmentShaderExecutor.prototype.execute = function(numValues, inputs) {
        /** @type {boolean} */ var useIntOutputs = true;
        /** @type {glsShaderExecUtil.Symbol} */ var symbol;
        var outputs = [];
        var maxRenderbufferSize = /** @type {number} */ (gl.getParameter(gl.MAX_RENDERBUFFER_SIZE));
        /** @type {number} */ var framebufferW = Math.min(maxRenderbufferSize, numValues);
        /** @type {number} */ var framebufferH = Math.ceil(numValues / framebufferW);

        var framebuffer = gl.createFramebuffer();
        var renderbuffers = [];
        for (var i = 0; i < this.m_outLocationSymbols.length; i++)
         renderbuffers.push(gl.createRenderbuffer());

        var vertexArrays = [];
        var positions = [];

        if (framebufferH > maxRenderbufferSize)
            throw new Error('Value count is too high for maximum supported renderbuffer size');

        // Compute positions - 1px points are used to drive fragment shading.
        for (var valNdx = 0; valNdx < numValues; valNdx++) {
            /** @type {number} */ var ix = valNdx % framebufferW;
            /** @type {number} */ var iy = Math.floor(valNdx / framebufferW);
            var fx = -1 + 2 * (ix + 0.5) / framebufferW;
            var fy = -1 + 2 * (iy + 0.5) / framebufferH;

            positions[2 * valNdx] = fx;
            positions[2 * valNdx + 1] = fy;
        }

        // Vertex inputs.
        vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding('a_position', 2, numValues, 0, positions));

        for (var inputNdx = 0; inputNdx < this.m_inputs.length; inputNdx++) {
            symbol = this.m_inputs[inputNdx];
            var attribName = 'a_' + symbol.name;
            var ptr = inputs[inputNdx];
            /** @type {gluShaderUtil.DataType} */ var basicType = symbol.varType.getBasicType();
            /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(basicType);

            if (gluShaderUtil.isDataTypeFloatOrVec(basicType))
                vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding(attribName, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeIntOrIVec(basicType))
                vertexArrays.push(gluDrawUtil.newInt32VertexArrayBinding(attribName, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeUintOrUVec(basicType))
                vertexArrays.push(gluDrawUtil.newUint32VertexArrayBinding(attribName, vecSize, numValues, 0, ptr));
            else if (gluShaderUtil.isDataTypeMatrix(basicType)) {
                var numRows = gluShaderUtil.getDataTypeMatrixNumRows(basicType);
                var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(basicType);
                // A matrix consists of several (column-major) vectors. A buffer is created for
                // every vector in gluDrawUtil.draw() below. Data in every buffer will be tightly
                // packed. So the stride should be 0. This is different from the code in native
                // deqp, which use only one buffer for a matrix, the data is interleaved.
                var stride = 0;

                for (var colNdx = 0; colNdx < numCols; ++colNdx)
                    vertexArrays.push(gluDrawUtil.newFloatColumnVertexArrayBinding(attribName,
                       colNdx,
                       numRows,
                       numValues,
                       stride,
                       glsShaderExecUtil.getColumn(ptr, colNdx, numRows * numValues)));
            } else
                DE_ASSERT(false);
        }

        // Construct framebuffer.
        gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);

        for (var outNdx = 0; outNdx < this.m_outLocationSymbols.length; ++outNdx) {
            symbol = this.m_outLocationSymbols[outNdx];
            var renderbuffer = renderbuffers[outNdx];
            var format = gluTextureUtil.getInternalFormat(glsShaderExecUtil.getRenderbufferFormatForOutput(symbol.varType, useIntOutputs));

            gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
            gl.renderbufferStorage(gl.RENDERBUFFER, format, framebufferW, framebufferH);
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + outNdx, gl.RENDERBUFFER, renderbuffer);
        }
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        assertMsgOptions(gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE, 'Framebuffer is incomplete', false, true);

        var drawBuffers = [];
        for (var ndx = 0; ndx < this.m_outLocationSymbols.length; ndx++)
            drawBuffers[ndx] = gl.COLOR_ATTACHMENT0 + ndx;
        gl.drawBuffers(drawBuffers);

        // Render
        gl.viewport(0, 0, framebufferW, framebufferH);
        gluDrawUtil.draw(gl, this.m_program.getProgram(), vertexArrays,
        new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.POINTS, numValues));

        // Read back pixels.

        // \todo [2013-08-07 pyry] Some fast-paths could be added here.

        for (var outNdx = 0; outNdx < this.m_outputs.length; ++outNdx) {
            symbol = this.m_outputs[outNdx];
            /** @type {number} */ var outSize = symbol.varType.getScalarSize();
            /** @type {number} */ var outVecSize = gluShaderUtil.getDataTypeNumComponents(symbol.varType.getBasicType());
            /** @type {number} */ var outNumLocs = gluShaderUtil.getDataTypeNumLocations(symbol.varType.getBasicType());
            var format = glsShaderExecUtil.getRenderbufferFormatForOutput(symbol.varType, useIntOutputs);
            var readFormat = new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, format.type);
            var transferFormat = gluTextureUtil.getTransferFormat(readFormat);
            /** @type {number} */ var outLocation = this.m_outLocationMap[symbol.name];
            var tmpBuf = new tcuTexture.TextureLevel(readFormat, framebufferW, framebufferH);

            for (var locNdx = 0; locNdx < outNumLocs; ++locNdx) {
                gl.readBuffer(gl.COLOR_ATTACHMENT0 + outLocation + locNdx);
                gl.readPixels(0, 0, framebufferW, framebufferH, transferFormat.format, transferFormat.dataType, tmpBuf.getAccess().getDataPtr());

                if (outSize == 4 && outNumLocs == 1) {
                    outputs[outNdx] = new Uint8Array(tmpBuf.getAccess().getBuffer());
                } else {
                    if (locNdx == 0)
                        outputs[outNdx] = new Uint32Array(numValues * outVecSize);
                    var srcPtr = new Uint32Array(tmpBuf.getAccess().getBuffer());
                    for (var valNdx = 0; valNdx < numValues; valNdx++) {
                        var srcOffset = valNdx * 4;
                        var dstOffset = outSize * valNdx + outVecSize * locNdx;
                        for (var j = 0; j < outVecSize; j++)
                        outputs[outNdx][dstOffset + j] = srcPtr[srcOffset + j];
                    }
                }
            }
        }

        // \todo [2013-08-07 pyry] Clear draw buffers & viewport?
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        return outputs;
    };

    glsShaderExecUtil.generateLocationMap = function(symbols, locationSymbols) {
        var ret = [];
        locationSymbols.length = 0;
        var location = 0;

        for (var i = 0; i < symbols.length; i++) {
            var symbol = symbols[i];
            var numLocations = gluShaderUtil.getDataTypeNumLocations(symbol.varType.getBasicType());
            ret[symbol.name] = location;
            location += numLocations;

            for (var ndx = 0; ndx < numLocations; ++ndx)
                locationSymbols.push(symbol);
        }

        return ret;
    };

});
