//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ProgramExecutable.h: Collects the information and interfaces common to both Programs and
// ProgramPipelines in order to execute/draw with either.

#ifndef LIBANGLE_PROGRAMEXECUTABLE_H_
#define LIBANGLE_PROGRAMEXECUTABLE_H_

#include "common/BinaryStream.h"
#include "libANGLE/Caps.h"
#include "libANGLE/InfoLog.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/VaryingPacking.h"
#include "libANGLE/angletypes.h"

namespace rx
{
class GLImplFactory;
class LinkSubTask;
class ProgramExecutableImpl;
}  // namespace rx

namespace gl
{

// This small structure encapsulates binding sampler uniforms to active GL textures.
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct SamplerBinding
{
    SamplerBinding() = default;
    SamplerBinding(TextureType textureTypeIn,
                   GLenum samplerTypeIn,
                   SamplerFormat formatIn,
                   uint16_t startIndex,
                   uint16_t elementCount)
        : textureType(textureTypeIn),
          format(formatIn),
          textureUnitsStartIndex(startIndex),
          textureUnitsCount(elementCount)
    {
        SetBitField(samplerType, samplerTypeIn);
    }

    GLuint getTextureUnit(const std::vector<GLuint> &boundTextureUnits,
                          unsigned int arrayIndex) const
    {
        return boundTextureUnits[textureUnitsStartIndex + arrayIndex];
    }

    // Necessary for retrieving active textures from the GL state.
    TextureType textureType;
    SamplerFormat format;
    uint16_t samplerType;
    // [textureUnitsStartIndex, textureUnitsStartIndex+textureUnitsCount) Points to the subset in
    // mSamplerBoundTextureUnits that stores the texture unit bound to this sampler. Cropped by the
    // amount of unused elements reported by the driver.
    uint16_t textureUnitsStartIndex;
    uint16_t textureUnitsCount;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

struct ImageBinding
{
    ImageBinding() = default;
    ImageBinding(size_t count, TextureType textureTypeIn)
        : textureType(textureTypeIn), boundImageUnits(count, 0)
    {}
    ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn);

    // Necessary for distinguishing between textures with images and texture buffers.
    TextureType textureType;

    // List of all textures bound.
    // Cropped by the amount of unused elements reported by the driver.
    std::vector<GLuint> boundImageUnits;
};

ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct ProgramInput
{
    ProgramInput() = default;
    ProgramInput(const sh::ShaderVariable &var);

    GLenum getType() const { return pod.type; }
    bool isBuiltIn() const { return pod.flagBits.isBuiltIn; }
    bool isArray() const { return pod.flagBits.isArray; }
    bool isActive() const { return pod.flagBits.active; }
    bool isPatch() const { return pod.flagBits.isPatch; }
    int getLocation() const { return pod.location; }
    unsigned int getBasicTypeElementCount() const { return pod.basicTypeElementCount; }
    unsigned int getArraySizeProduct() const { return pod.arraySizeProduct; }
    uint32_t getId() const { return pod.id; }
    sh::InterpolationType getInterpolation() const
    {
        return static_cast<sh::InterpolationType>(pod.interpolation);
    }

    void setLocation(int location) { pod.location = location; }
    void resetEffectiveLocation()
    {
        if (pod.flagBits.hasImplicitLocation)
        {
            pod.location = -1;
        }
    }

    std::string name;
    std::string mappedName;

    // The struct bellow must only contain data of basic type so that entire struct can memcpy-able.
    struct PODStruct
    {
        uint16_t type;  // GLenum
        uint16_t arraySizeProduct;

        int location;

        uint8_t interpolation;  // sh::InterpolationType
        union
        {
            struct
            {
                uint8_t active : 1;
                uint8_t isPatch : 1;
                uint8_t hasImplicitLocation : 1;
                uint8_t isArray : 1;
                uint8_t isBuiltIn : 1;
                uint8_t padding : 3;
            } flagBits;
            uint8_t flagBitsAsUByte;
        };
        int16_t basicTypeElementCount;

        uint32_t id;
    } pod;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct ProgramOutput
{
    ProgramOutput() = default;
    ProgramOutput(const sh::ShaderVariable &var);
    GLenum getType() const { return pod.type; }
    bool isBuiltIn() const { return pod.isBuiltIn; }
    bool isArray() const { return pod.isArray; }
    int getLocation() const { return pod.location; }
    unsigned int getOutermostArraySize() const { return pod.outermostArraySize; }
    unsigned int getBasicTypeElementCount() const { return pod.basicTypeElementCount; }
    void resetEffectiveLocation()
    {
        if (pod.hasImplicitLocation)
        {
            pod.location = -1;
        }
    }

    std::string name;
    std::string mappedName;

    struct PODStruct
    {
        GLenum type;
        int location;
        int index;
        uint32_t id;

        uint16_t outermostArraySize;
        uint16_t basicTypeElementCount;

        uint32_t isPatch : 1;
        uint32_t yuv : 1;
        uint32_t isBuiltIn : 1;
        uint32_t isArray : 1;
        uint32_t hasImplicitLocation : 1;
        uint32_t hasShaderAssignedLocation : 1;
        uint32_t hasApiAssignedLocation : 1;
        uint32_t pad : 25;
    } pod;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

// A varying with transform feedback enabled. If it's an array, either the whole array or one of its
// elements specified by 'arrayIndex' can set to be enabled.
struct TransformFeedbackVarying : public sh::ShaderVariable
{
    TransformFeedbackVarying() = default;

    TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn)
        : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn)
    {
        ASSERT(!isArrayOfArrays());
    }

    TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent)
        : arrayIndex(GL_INVALID_INDEX)
    {
        sh::ShaderVariable *thisVar = this;
        *thisVar                    = field;
        interpolation               = parent.interpolation;
        isInvariant                 = parent.isInvariant;
        ASSERT(parent.isShaderIOBlock || !parent.name.empty());
        if (!parent.name.empty())
        {
            name       = parent.name + "." + name;
            mappedName = parent.mappedName + "." + mappedName;
        }
        structOrBlockName       = parent.structOrBlockName;
        mappedStructOrBlockName = parent.mappedStructOrBlockName;
    }

    std::string nameWithArrayIndex() const
    {
        std::stringstream fullNameStr;
        fullNameStr << name;
        if (arrayIndex != GL_INVALID_INDEX)
        {
            fullNameStr << "[" << arrayIndex << "]";
        }
        return fullNameStr.str();
    }
    GLsizei size() const
    {
        return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
    }

    GLuint arrayIndex;
};

class ProgramState;
class ProgramPipelineState;

class ProgramExecutable;
using SharedProgramExecutable = std::shared_ptr<ProgramExecutable>;

class ProgramExecutable final : public angle::Subject
{
  public:
    ProgramExecutable(rx::GLImplFactory *factory, InfoLog *infoLog);
    ~ProgramExecutable() override;

    void destroy(const Context *context);

    ANGLE_INLINE rx::ProgramExecutableImpl *getImplementation() const { return mImplementation; }

    void save(gl::BinaryOutputStream *stream) const;
    void load(gl::BinaryInputStream *stream);

    InfoLog &getInfoLog() const { return *mInfoLog; }
    std::string getInfoLogString() const;
    void resetInfoLog() const { mInfoLog->reset(); }

    void resetLinkedShaderStages() { mPod.linkedShaderStages.reset(); }
    const ShaderBitSet getLinkedShaderStages() const { return mPod.linkedShaderStages; }
    void setLinkedShaderStages(ShaderType shaderType)
    {
        mPod.linkedShaderStages.set(shaderType);
        updateCanDrawWith();
    }
    bool hasLinkedShaderStage(ShaderType shaderType) const
    {
        ASSERT(shaderType != ShaderType::InvalidEnum);
        return mPod.linkedShaderStages[shaderType];
    }
    size_t getLinkedShaderStageCount() const { return mPod.linkedShaderStages.count(); }
    bool hasLinkedGraphicsShader() const
    {
        return mPod.linkedShaderStages.any() &&
               mPod.linkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
    }
    bool hasLinkedTessellationShader() const
    {
        return mPod.linkedShaderStages[ShaderType::TessEvaluation];
    }
    ShaderType getFirstLinkedShaderStageType() const;
    ShaderType getLastLinkedShaderStageType() const;

    ShaderType getLinkedTransformFeedbackStage() const
    {
        return GetLastPreFragmentStage(mPod.linkedShaderStages);
    }

    const AttributesMask &getActiveAttribLocationsMask() const
    {
        return mPod.activeAttribLocationsMask;
    }
    bool isAttribLocationActive(size_t attribLocation) const
    {
        ASSERT(attribLocation < mPod.activeAttribLocationsMask.size());
        return mPod.activeAttribLocationsMask[attribLocation];
    }

    AttributesMask getNonBuiltinAttribLocationsMask() const { return mPod.attributesMask; }
    unsigned int getMaxActiveAttribLocation() const { return mPod.maxActiveAttribLocation; }
    ComponentTypeMask getAttributesTypeMask() const { return mPod.attributesTypeMask; }
    AttributesMask getAttributesMask() const { return mPod.attributesMask; }

    const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
    void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; }
    SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const
    {
        return mActiveSamplerFormats[textureUnitIndex];
    }
    const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const
    {
        return mActiveSamplerShaderBits[textureUnitIndex];
    }
    const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; }
    void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; }
    const ActiveTextureArray<ShaderBitSet> &getActiveImageShaderBits() const
    {
        return mActiveImageShaderBits;
    }

    const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; }

    const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const
    {
        return mActiveSamplerTypes;
    }

    const ProgramUniformBlockMask &getActiveUniformBufferBlocks() const
    {
        return mActiveUniformBufferBlocks;
    }

    const ProgramStorageBlockMask &getActiveStorageBufferBlocks() const
    {
        return mActiveStorageBufferBlocks;
    }

    void setActive(size_t textureUnit,
                   const SamplerBinding &samplerBinding,
                   const gl::LinkedUniform &samplerUniform);
    void setInactive(size_t textureUnit);
    void hasSamplerTypeConflict(size_t textureUnit);
    void hasSamplerFormatConflict(size_t textureUnit);

    void updateActiveSamplers(const ProgramExecutable &executable);

    bool hasDefaultUniforms() const { return !getDefaultUniformRange().empty(); }
    bool hasTextures() const { return !getSamplerBindings().empty(); }
    bool hasUniformBuffers() const { return !mUniformBlocks.empty(); }
    bool hasStorageBuffers() const { return !mShaderStorageBlocks.empty(); }
    bool hasAtomicCounterBuffers() const { return !mAtomicCounterBuffers.empty(); }
    bool hasImages() const { return !mImageBindings.empty(); }
    bool hasTransformFeedbackOutput() const
    {
        return !getLinkedTransformFeedbackVaryings().empty();
    }
    bool usesColorFramebufferFetch() const { return mPod.fragmentInoutIndices.any(); }
    bool usesDepthFramebufferFetch() const { return mPod.hasDepthInputAttachment; }
    bool usesStencilFramebufferFetch() const { return mPod.hasStencilInputAttachment; }

    // Count the number of uniform and storage buffer declarations, counting arrays as one.
    size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); }

    void updateCanDrawWith() { mPod.canDrawWith = hasLinkedShaderStage(ShaderType::Vertex); }
    bool hasVertexShader() const { return mPod.canDrawWith; }

    const std::vector<ProgramInput> &getProgramInputs() const { return mProgramInputs; }
    const std::vector<ProgramOutput> &getOutputVariables() const { return mOutputVariables; }
    const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
    const std::vector<VariableLocation> &getSecondaryOutputLocations() const
    {
        return mSecondaryOutputLocations;
    }
    const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
    const std::vector<std::string> &getUniformNames() const { return mUniformNames; }
    const std::vector<std::string> &getUniformMappedNames() const { return mUniformMappedNames; }
    const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
    const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
    const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
    const std::vector<GLuint> &getSamplerBoundTextureUnits() const
    {
        return mSamplerBoundTextureUnits;
    }
    const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
    const std::vector<ShPixelLocalStorageLayout> &getPixelLocalStorageLayouts() const
    {
        return mPixelLocalStorageLayouts;
    }
    std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; }
    const RangeUI &getDefaultUniformRange() const { return mPod.defaultUniformRange; }
    const RangeUI &getSamplerUniformRange() const { return mPod.samplerUniformRange; }
    const RangeUI &getImageUniformRange() const { return mPod.imageUniformRange; }
    const RangeUI &getAtomicCounterUniformRange() const { return mPod.atomicCounterUniformRange; }
    DrawBufferMask getFragmentInoutIndices() const { return mPod.fragmentInoutIndices; }
    bool hasClipDistance() const { return mPod.hasClipDistance; }
    bool hasDiscard() const { return mPod.hasDiscard; }
    bool hasFragCoord() const { return mPod.hasFragCoord; }
    bool hasDepthInputAttachment() const { return mPod.hasDepthInputAttachment; }
    bool hasStencilInputAttachment() const { return mPod.hasStencilInputAttachment; }
    bool enablesPerSampleShading() const { return mPod.enablesPerSampleShading; }
    BlendEquationBitSet getAdvancedBlendEquations() const { return mPod.advancedBlendEquations; }
    const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
    {
        return mLinkedTransformFeedbackVaryings;
    }
    GLint getTransformFeedbackBufferMode() const { return mPod.transformFeedbackBufferMode; }
    const sh::WorkGroupSize &getComputeShaderLocalSize() const
    {
        return mPod.computeShaderLocalSize;
    }
    void remapUniformBlockBinding(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding);
    GLuint getUniformBlockBinding(size_t uniformBlockIndex) const
    {
        ASSERT(uniformBlockIndex < mUniformBlocks.size());

        // Unlike SSBOs and atomic counter buffers, GLES allows UBOs bindings to be remapped.  Note
        // that desktop GL allows SSBO bindings to also be remapped, but that's not allowed in GLES.
        //
        // It's therefore important to never directly reference block.pod.inShaderBinding unless the
        // specific shader-specified binding is required.
        return mUniformBlockIndexToBufferBinding[uniformBlockIndex];
    }
    GLuint getShaderStorageBlockBinding(size_t blockIndex) const
    {
        ASSERT(blockIndex < mShaderStorageBlocks.size());
        // The buffer binding for SSBOs is the one specified in the shader
        return mShaderStorageBlocks[blockIndex].pod.inShaderBinding;
    }
    GLuint getAtomicCounterBufferBinding(size_t blockIndex) const
    {
        ASSERT(blockIndex < mAtomicCounterBuffers.size());
        // The buffer binding for atomic counter buffers is the one specified in the shader
        return mAtomicCounterBuffers[blockIndex].pod.inShaderBinding;
    }
    const InterfaceBlock &getUniformBlockByIndex(size_t index) const
    {
        ASSERT(index < mUniformBlocks.size());
        return mUniformBlocks[index];
    }
    const InterfaceBlock &getShaderStorageBlockByIndex(size_t index) const
    {
        ASSERT(index < mShaderStorageBlocks.size());
        return mShaderStorageBlocks[index];
    }
    const BufferVariable &getBufferVariableByIndex(size_t index) const
    {
        ASSERT(index < mBufferVariables.size());
        return mBufferVariables[index];
    }
    const std::vector<GLsizei> &getTransformFeedbackStrides() const
    {
        return mTransformFeedbackStrides;
    }
    const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
    {
        return mAtomicCounterBuffers;
    }
    const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
    {
        return mShaderStorageBlocks;
    }
    const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
    const LinkedUniform &getUniformByIndex(size_t index) const
    {
        ASSERT(index < static_cast<size_t>(mUniforms.size()));
        return mUniforms[index];
    }
    const std::string &getUniformNameByIndex(size_t index) const
    {
        ASSERT(index < static_cast<size_t>(mUniforms.size()));
        return mUniformNames[index];
    }

    GLuint getUniformIndexFromImageIndex(size_t imageIndex) const
    {
        ASSERT(imageIndex < mPod.imageUniformRange.length());
        return static_cast<GLuint>(imageIndex) + mPod.imageUniformRange.low();
    }

    GLuint getUniformIndexFromSamplerIndex(size_t samplerIndex) const
    {
        ASSERT(samplerIndex < mPod.samplerUniformRange.length());
        return static_cast<GLuint>(samplerIndex) + mPod.samplerUniformRange.low();
    }

    void saveLinkedStateInfo(const ProgramState &state);
    const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const
    {
        return mLinkedOutputVaryings[shaderType];
    }
    const std::vector<sh::ShaderVariable> &getLinkedInputVaryings(ShaderType shaderType) const
    {
        return mLinkedInputVaryings[shaderType];
    }

    const std::vector<sh::ShaderVariable> &getLinkedUniforms(ShaderType shaderType) const
    {
        return mLinkedUniforms[shaderType];
    }

    const std::vector<sh::InterfaceBlock> &getLinkedUniformBlocks(ShaderType shaderType) const
    {
        return mLinkedUniformBlocks[shaderType];
    }

    int getLinkedShaderVersion(ShaderType shaderType) const
    {
        return mPod.linkedShaderVersions[shaderType];
    }

    bool isYUVOutput() const { return mPod.hasYUVOutput; }

    PrimitiveMode getGeometryShaderInputPrimitiveType() const
    {
        return mPod.geometryShaderInputPrimitiveType;
    }

    PrimitiveMode getGeometryShaderOutputPrimitiveType() const
    {
        return mPod.geometryShaderOutputPrimitiveType;
    }

    int getGeometryShaderInvocations() const { return mPod.geometryShaderInvocations; }

    int getGeometryShaderMaxVertices() const { return mPod.geometryShaderMaxVertices; }

    GLint getTessControlShaderVertices() const { return mPod.tessControlShaderVertices; }
    GLenum getTessGenMode() const { return mPod.tessGenMode; }
    GLenum getTessGenPointMode() const { return mPod.tessGenPointMode; }
    GLenum getTessGenSpacing() const { return mPod.tessGenSpacing; }
    GLenum getTessGenVertexOrder() const { return mPod.tessGenVertexOrder; }

    int getNumViews() const { return mPod.numViews; }
    bool usesMultiview() const { return mPod.numViews != -1; }

    rx::SpecConstUsageBits getSpecConstUsageBits() const { return mPod.specConstUsageBits; }

    int getDrawIDLocation() const { return mPod.drawIDLocation; }
    int getBaseVertexLocation() const { return mPod.baseVertexLocation; }
    int getBaseInstanceLocation() const { return mPod.baseInstanceLocation; }

    bool hasDrawIDUniform() const { return getDrawIDLocation() >= 0; }
    bool hasBaseVertexUniform() const { return getBaseVertexLocation() >= 0; }
    bool hasBaseInstanceUniform() const { return getBaseInstanceLocation() >= 0; }

    void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); }
    bool validateSamplers(const Caps &caps) const
    {
        // Use the cache if:
        // - we aren't using an info log (which gives the full error).
        // - The sample mapping hasn't changed and we've already validated.
        if (mCachedValidateSamplersResult.valid())
        {
            return mCachedValidateSamplersResult.value();
        }

        return validateSamplersImpl(caps);
    }

    ComponentTypeMask getFragmentOutputsTypeMask() const { return mPod.drawBufferTypeMask; }
    DrawBufferMask getActiveOutputVariablesMask() const { return mPod.activeOutputVariablesMask; }
    DrawBufferMask getActiveSecondaryOutputVariablesMask() const
    {
        return mPod.activeSecondaryOutputVariablesMask;
    }

    GLuint getInputResourceIndex(const GLchar *name) const;
    GLuint getOutputResourceIndex(const GLchar *name) const;
    void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    void getBufferVariableResourceName(GLuint index,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLchar *name) const;
    const ProgramInput &getInputResource(size_t index) const
    {
        ASSERT(index < mProgramInputs.size());
        return mProgramInputs[index];
    }
    GLuint getInputResourceMaxNameSize() const;
    GLuint getOutputResourceMaxNameSize() const;
    GLuint getInputResourceLocation(const GLchar *name) const;
    GLuint getOutputResourceLocation(const GLchar *name) const;
    const std::string getInputResourceName(GLuint index) const;
    const std::string getOutputResourceName(GLuint index) const;
    const gl::ProgramOutput &getOutputResource(size_t index) const
    {
        ASSERT(index < mOutputVariables.size());
        return mOutputVariables[index];
    }

    GLint getFragDataLocation(const std::string &name) const;

    // EXT_blend_func_extended
    GLint getFragDataIndex(const std::string &name) const;

    GLsizei getTransformFeedbackVaryingMaxLength() const;
    GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
    const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
    void getTransformFeedbackVarying(GLuint index,
                                     GLsizei bufSize,
                                     GLsizei *length,
                                     GLsizei *size,
                                     GLenum *type,
                                     GLchar *name) const;

    void getActiveAttribute(GLuint index,
                            GLsizei bufsize,
                            GLsizei *length,
                            GLint *size,
                            GLenum *type,
                            GLchar *name) const;
    GLint getActiveAttributeMaxLength() const;
    GLuint getAttributeLocation(const std::string &name) const;

    void getActiveUniform(GLuint index,
                          GLsizei bufsize,
                          GLsizei *length,
                          GLint *size,
                          GLenum *type,
                          GLchar *name) const;
    GLint getActiveUniformMaxLength() const;
    bool isValidUniformLocation(UniformLocation location) const;
    const LinkedUniform &getUniformByLocation(UniformLocation location) const;
    const VariableLocation &getUniformLocation(UniformLocation location) const;
    UniformLocation getUniformLocation(const std::string &name) const;
    GLuint getUniformIndex(const std::string &name) const;

    void getActiveUniformBlockName(const Context *context,
                                   const UniformBlockIndex blockIndex,
                                   GLsizei bufSize,
                                   GLsizei *length,
                                   GLchar *blockName) const;
    void getActiveShaderStorageBlockName(const GLuint blockIndex,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLchar *blockName) const;

    GLint getActiveUniformBlockMaxNameLength() const;
    GLint getActiveShaderStorageBlockMaxNameLength() const;

    GLuint getUniformBlockIndex(const std::string &name) const;
    GLuint getShaderStorageBlockIndex(const std::string &name) const;

    GLuint getUniformIndexFromName(const std::string &name) const;
    GLuint getUniformIndexFromLocation(UniformLocation location) const;
    Optional<GLuint> getSamplerIndex(UniformLocation location) const;
    bool isSamplerUniformIndex(GLuint index) const;
    GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
    bool isImageUniformIndex(GLuint index) const;
    GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
    GLuint getBufferVariableIndexFromName(const std::string &name) const;

    bool linkUniforms(const Caps &caps,
                      const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
                      const ProgramAliasedBindings &uniformLocationBindings,
                      GLuint *combinedImageUniformsCount,
                      std::vector<UnusedUniform> *unusedUniforms);

    void copyInputsFromProgram(const ProgramExecutable &executable);
    void copyUniformBuffersFromProgram(const ProgramExecutable &executable,
                                       ShaderType shaderType,
                                       ProgramUniformBlockArray<GLuint> *ppoUniformBlockMap);
    void copyStorageBuffersFromProgram(const ProgramExecutable &executable, ShaderType shaderType);
    void clearSamplerBindings();
    void copySamplerBindingsFromProgram(const ProgramExecutable &executable);
    void copyImageBindingsFromProgram(const ProgramExecutable &executable);
    void copyOutputsFromProgram(const ProgramExecutable &executable);
    void copyUniformsFromProgramMap(const ShaderMap<SharedProgramExecutable> &executables);

    void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
    void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
    void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
    void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
    void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
    void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
    void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
    void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
    void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
    void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
    void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
    void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
    void setUniformMatrix2fv(UniformLocation location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value);
    void setUniformMatrix3fv(UniformLocation location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value);
    void setUniformMatrix4fv(UniformLocation location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value);
    void setUniformMatrix2x3fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
    void setUniformMatrix3x2fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
    void setUniformMatrix2x4fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
    void setUniformMatrix4x2fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
    void setUniformMatrix3x4fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);
    void setUniformMatrix4x3fv(UniformLocation location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value);

    void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
    void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
    void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;

    void setDrawIDUniform(GLint drawid);
    void setBaseVertexUniform(GLint baseVertex);
    void setBaseInstanceUniform(GLuint baseInstance);

    ProgramUniformBlockMask getUniformBufferBlocksMappedToBinding(size_t uniformBufferIndex)
    {
        return mUniformBufferBindingToUniformBlocks[uniformBufferIndex];
    }

    const ProgramUniformBlockArray<GLuint> &getUniformBlockIndexToBufferBindingForCapture() const
    {
        return mUniformBlockIndexToBufferBinding;
    }

    const ShaderMap<SharedProgramExecutable> &getPPOProgramExecutables() const
    {
        return mPPOProgramExecutables;
    }

    bool IsPPO() const { return mIsPPO; }

    // Post-link task helpers
    const std::vector<std::shared_ptr<rx::LinkSubTask>> &getPostLinkSubTasks() const
    {
        return mPostLinkSubTasks;
    }

    const std::vector<std::shared_ptr<angle::WaitableEvent>> &getPostLinkSubTaskWaitableEvents()
        const
    {
        return mPostLinkSubTaskWaitableEvents;
    }

    void onPostLinkTasksComplete() const
    {
        mPostLinkSubTasks.clear();
        mPostLinkSubTaskWaitableEvents.clear();
    }

    void waitForPostLinkTasks(const Context *context);

    void updateActiveUniformBufferBlocks();
    void updateActiveStorageBufferBlocks();

  private:
    friend class Program;
    friend class ProgramPipeline;
    friend class ProgramState;
    friend class ProgramPipelineState;

    void reset();

    void updateActiveImages(const ProgramExecutable &executable);

    bool linkMergedVaryings(const Caps &caps,
                            const Limitations &limitations,
                            const Version &clientVersion,
                            bool webglCompatibility,
                            const ProgramMergedVaryings &mergedVaryings,
                            const LinkingVariables &linkingVariables,
                            ProgramVaryingPacking *varyingPacking);

    bool linkValidateTransformFeedback(const Caps &caps,
                                       const Version &clientVersion,
                                       const ProgramMergedVaryings &varyings,
                                       ShaderType stage);

    void gatherTransformFeedbackVaryings(const ProgramMergedVaryings &varyings, ShaderType stage);

    void updateTransformFeedbackStrides();

    bool validateSamplersImpl(const Caps &caps) const;

    bool linkValidateOutputVariables(const Caps &caps,
                                     const Version &version,
                                     GLuint combinedImageUniformsCount,
                                     GLuint combinedShaderStorageBlocksCount,
                                     int fragmentShaderVersion,
                                     const ProgramAliasedBindings &fragmentOutputLocations,
                                     const ProgramAliasedBindings &fragmentOutputIndices);

    bool gatherOutputTypes();

    void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
    bool linkAtomicCounterBuffers(const Caps &caps);

    void getResourceName(const std::string name,
                         GLsizei bufSize,
                         GLsizei *length,
                         GLchar *dest) const;
    bool shouldIgnoreUniform(UniformLocation location) const;
    GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
    GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;

    void initInterfaceBlockBindings();
    void setUniformValuesFromBindingQualifiers();

    // Both these function update the cached uniform values and return a modified "count"
    // so that the uniform update doesn't overflow the uniform.
    template <typename T>
    GLsizei clampUniformCount(const VariableLocation &locationInfo,
                              GLsizei count,
                              int vectorSize,
                              const T *v);
    template <size_t cols, size_t rows, typename T>
    GLsizei clampMatrixUniformCount(UniformLocation location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const T *v);

    void updateSamplerUniform(Context *context,
                              const VariableLocation &locationInfo,
                              GLsizei clampedCount,
                              const GLint *v);

    // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
    void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);

    template <typename DestT>
    void getUniformInternal(const Context *context,
                            DestT *dataOut,
                            UniformLocation location,
                            GLenum nativeType,
                            int components) const;

    template <typename UniformT,
              GLint UniformSize,
              void (rx::ProgramExecutableImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
    void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v);

    template <typename UniformT,
              GLint MatrixC,
              GLint MatrixR,
              void (rx::ProgramExecutableImpl::*
                        SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
    void setUniformMatrixGeneric(UniformLocation location,
                                 GLsizei count,
                                 GLboolean transpose,
                                 const UniformT *v);

    rx::ProgramExecutableImpl *mImplementation;

    // A reference to the owning object's (Program or ProgramPipeline) info log.  It's kept here for
    // convenience as numerous functions reference it.
    InfoLog *mInfoLog;

    ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
    struct PODStruct
    {
        // 8 bytes each
        angle::BitSet<MAX_VERTEX_ATTRIBS> activeAttribLocationsMask;
        ComponentTypeMask attributesTypeMask;
        // attributesMask is identical to mActiveAttribLocationsMask with built-in attributes
        // removed.
        AttributesMask attributesMask;
        ComponentTypeMask drawBufferTypeMask;

        // 4 bytes each
        uint32_t maxActiveAttribLocation;
        // KHR_blend_equation_advanced supported equation list
        BlendEquationBitSet advancedBlendEquations;

        // 1 byte each
        ShaderBitSet linkedShaderStages;
        DrawBufferMask activeOutputVariablesMask;
        DrawBufferMask activeSecondaryOutputVariablesMask;
        uint8_t hasClipDistance : 1;
        uint8_t hasDiscard : 1;
        uint8_t hasYUVOutput : 1;
        uint8_t hasDepthInputAttachment : 1;
        uint8_t hasStencilInputAttachment : 1;
        uint8_t enablesPerSampleShading : 1;
        uint8_t canDrawWith : 1;
        uint8_t isSeparable : 1;

        // 12 bytes
        sh::WorkGroupSize computeShaderLocalSize;

        // 8 bytes each
        RangeUI defaultUniformRange;
        RangeUI samplerUniformRange;
        RangeUI imageUniformRange;
        RangeUI atomicCounterUniformRange;

        // 1 byte.  Bitset of which input attachments have been declared
        DrawBufferMask fragmentInoutIndices;

        // 1 byte
        uint8_t hasFragCoord : 1;
        uint8_t pad : 7;

        // GL_EXT_geometry_shader.
        PrimitiveMode geometryShaderInputPrimitiveType;
        PrimitiveMode geometryShaderOutputPrimitiveType;
        int32_t geometryShaderInvocations;
        int32_t geometryShaderMaxVertices;
        GLenum transformFeedbackBufferMode;

        // GL_OVR_multiview
        int32_t numViews;

        // GL_ANGLE_multi_draw
        int32_t drawIDLocation;

        // GL_ANGLE_base_vertex_base_instance_shader_builtin
        int32_t baseVertexLocation;
        int32_t baseInstanceLocation;

        // GL_EXT_tessellation_shader
        int32_t tessControlShaderVertices;
        GLenum tessGenMode;
        GLenum tessGenSpacing;
        GLenum tessGenVertexOrder;
        GLenum tessGenPointMode;

        // 4 bytes
        rx::SpecConstUsageBits specConstUsageBits;

        // 24 bytes
        ShaderMap<int> linkedShaderVersions;
    } mPod;
    ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

    // Cached mask of active samplers and sampler types.
    ActiveTextureMask mActiveSamplersMask;
    ActiveTextureArray<uint32_t> mActiveSamplerRefCounts;
    ActiveTextureArray<TextureType> mActiveSamplerTypes;
    ActiveTextureMask mActiveSamplerYUV;
    ActiveTextureArray<SamplerFormat> mActiveSamplerFormats;
    ActiveTextureArray<ShaderBitSet> mActiveSamplerShaderBits;

    // Cached mask of active images.
    ActiveTextureMask mActiveImagesMask;
    ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits;

    // Cached mask of active uniform and storage buffer blocks
    ProgramUniformBlockMask mActiveUniformBufferBlocks;
    ProgramStorageBlockMask mActiveStorageBufferBlocks;

    // Names and mapped names of output variables that are arrays include [0] in the end, similarly
    // to uniforms.
    std::vector<ProgramOutput> mOutputVariables;
    std::vector<VariableLocation> mOutputLocations;
    // EXT_blend_func_extended secondary outputs (ones with index 1)
    std::vector<VariableLocation> mSecondaryOutputLocations;
    // Vertex attributes, Fragment input varyings, etc.
    std::vector<ProgramInput> mProgramInputs;
    std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
    // Duplicate of ProgramState::mTransformFeedbackVaryingNames.  This is cached here because the
    // xfb names may change, relink may fail, yet program pipeline link should be able to function
    // with the last installed executable.  In truth, program pipeline link should have been able to
    // hoist transform feedback varyings directly from the executable, among most other things, but
    // that is currently not done.
    //
    // This array is not serialized, it's already done by the program, and will be duplicated during
    // deserialization.
    std::vector<std::string> mTransformFeedbackVaryingNames;
    // The size of the data written to each transform feedback buffer per vertex.
    std::vector<GLsizei> mTransformFeedbackStrides;
    // Uniforms are sorted in order:
    //  1. Non-opaque uniforms
    //  2. Sampler uniforms
    //  3. Image uniforms
    //  4. Atomic counter uniforms
    //  5. Uniform block uniforms
    // This makes opaque uniform validation easier, since we don't need a separate list.
    // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
    // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
    // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
    // [0] in the end. This makes implementation of queries simpler.
    std::vector<LinkedUniform> mUniforms;
    std::vector<std::string> mUniformNames;
    // Only used by GL and D3D backend
    std::vector<std::string> mUniformMappedNames;
    std::vector<InterfaceBlock> mUniformBlocks;
    std::vector<VariableLocation> mUniformLocations;

    std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
    std::vector<InterfaceBlock> mShaderStorageBlocks;
    std::vector<BufferVariable> mBufferVariables;

    // An array of the samplers that are used by the program
    std::vector<SamplerBinding> mSamplerBindings;
    // List of all textures bound to all samplers. Each SamplerBinding will point to a subset in
    // this vector.
    std::vector<GLuint> mSamplerBoundTextureUnits;

    // An array of the images that are used by the program
    std::vector<ImageBinding> mImageBindings;

    // ANGLE_shader_pixel_local_storage: A mapping from binding index to the PLS uniform format at
    // that index.
    std::vector<ShPixelLocalStorageLayout> mPixelLocalStorageLayouts;

    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedOutputVaryings;
    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedInputVaryings;
    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedUniforms;
    ShaderMap<std::vector<sh::InterfaceBlock>> mLinkedUniformBlocks;

    // Cached value of base vertex and base instance
    // need to reset them to zero if using non base vertex or base instance draw calls.
    GLint mCachedBaseVertex;
    GLuint mCachedBaseInstance;

    // GLES allows uniform block indices in the program to be remapped to arbitrary buffer bindings
    // through calls to glUniformBlockBinding.  (Desktop GL also includes
    // glShaderStorageBlockBinding, which does not exist in GLES).
    // This is not a part of the link results, and must be reset on glProgramBinary, so it's not
    // serialized.
    // A map from the program uniform block index to the buffer binding it is mapped to.
    ProgramUniformBlockArray<GLuint> mUniformBlockIndexToBufferBinding;
    // The reverse of the above map, i.e. from buffer bindings to the uniform blocks that are mapped
    // to it.  For example, if the program's uniform blocks 1, 3 and 4 are mapped to buffer binding
    // 2, then mUniformBufferBindingToUniformBlocks[2] will be {1, 3, 4}.
    //
    // This is used to efficiently mark uniform blocks dirty when a buffer bound to a binding has
    // been modified.
    UniformBufferBindingArray<ProgramUniformBlockMask> mUniformBufferBindingToUniformBlocks;

    // PPO only: installed executables from the programs.  Note that these may be different from the
    // programs' current executables, because they may have been unsuccessfully relinked.
    ShaderMap<SharedProgramExecutable> mPPOProgramExecutables;
    // Flag for an easy check for PPO without inspecting mPPOProgramExecutables
    bool mIsPPO;

    bool mBinaryRetrieveableHint;

    // Cache for sampler validation
    mutable Optional<bool> mCachedValidateSamplersResult;

    // Post-link subtask and wait events
    // These tasks are not waited on in |resolveLink|, but instead they are free to
    // run until first usage of the program (or relink).  This is used by the backends (currently
    // only Vulkan) to run post-link optimization tasks which don't affect the link results.
    mutable std::vector<std::shared_ptr<rx::LinkSubTask>> mPostLinkSubTasks;
    mutable std::vector<std::shared_ptr<angle::WaitableEvent>> mPostLinkSubTaskWaitableEvents;
};

void InstallExecutable(const Context *context,
                       const SharedProgramExecutable &toInstall,
                       SharedProgramExecutable *executable);
void UninstallExecutable(const Context *context, SharedProgramExecutable *executable);
}  // namespace gl

#endif  // LIBANGLE_PROGRAMEXECUTABLE_H_
