tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Program.h (33030B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Program.h: Defines the gl::Program class. Implements GL program objects
      8 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
      9 
     10 #ifndef LIBANGLE_PROGRAM_H_
     11 #define LIBANGLE_PROGRAM_H_
     12 
     13 #include <GLES2/gl2.h>
     14 #include <GLSLANG/ShaderVars.h>
     15 
     16 #include <array>
     17 #include <map>
     18 #include <set>
     19 #include <sstream>
     20 #include <string>
     21 #include <vector>
     22 
     23 #include "common/Optional.h"
     24 #include "common/angleutils.h"
     25 #include "common/mathutil.h"
     26 #include "common/utilities.h"
     27 
     28 #include "libANGLE/Constants.h"
     29 #include "libANGLE/Debug.h"
     30 #include "libANGLE/Error.h"
     31 #include "libANGLE/InfoLog.h"
     32 #include "libANGLE/ProgramExecutable.h"
     33 #include "libANGLE/ProgramLinkedResources.h"
     34 #include "libANGLE/RefCountObject.h"
     35 #include "libANGLE/Uniform.h"
     36 #include "libANGLE/angletypes.h"
     37 
     38 namespace rx
     39 {
     40 class GLImplFactory;
     41 class ProgramImpl;
     42 struct TranslatedAttribute;
     43 }  // namespace rx
     44 
     45 namespace gl
     46 {
     47 class Buffer;
     48 class BinaryInputStream;
     49 class BinaryOutputStream;
     50 struct Caps;
     51 class Context;
     52 struct Extensions;
     53 class Framebuffer;
     54 class ProgramExecutable;
     55 class Shader;
     56 class ShaderProgramManager;
     57 class State;
     58 struct UnusedUniform;
     59 struct Version;
     60 
     61 extern const char *const g_fakepath;
     62 
     63 enum class LinkMismatchError
     64 {
     65    // Shared
     66    NO_MISMATCH,
     67    TYPE_MISMATCH,
     68    ARRAYNESS_MISMATCH,
     69    ARRAY_SIZE_MISMATCH,
     70    PRECISION_MISMATCH,
     71    STRUCT_NAME_MISMATCH,
     72    FIELD_NUMBER_MISMATCH,
     73    FIELD_NAME_MISMATCH,
     74 
     75    // Varying specific
     76    INTERPOLATION_TYPE_MISMATCH,
     77    INVARIANCE_MISMATCH,
     78 
     79    // Uniform specific
     80    BINDING_MISMATCH,
     81    LOCATION_MISMATCH,
     82    OFFSET_MISMATCH,
     83    INSTANCE_NAME_MISMATCH,
     84    FORMAT_MISMATCH,
     85 
     86    // Interface block specific
     87    LAYOUT_QUALIFIER_MISMATCH,
     88    MATRIX_PACKING_MISMATCH,
     89 
     90    // I/O block specific
     91    FIELD_LOCATION_MISMATCH,
     92    FIELD_STRUCT_NAME_MISMATCH,
     93 };
     94 
     95 void LogLinkMismatch(InfoLog &infoLog,
     96                     const std::string &variableName,
     97                     const char *variableType,
     98                     LinkMismatchError linkError,
     99                     const std::string &mismatchedStructOrBlockFieldName,
    100                     ShaderType shaderType1,
    101                     ShaderType shaderType2);
    102 
    103 bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock);
    104 
    105 void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var);
    106 void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var);
    107 
    108 void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var);
    109 void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var);
    110 
    111 void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block);
    112 void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block);
    113 
    114 void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block);
    115 void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block);
    116 
    117 void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var);
    118 void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var);
    119 
    120 // Struct used for correlating uniforms/elements of uniform arrays to handles
    121 struct VariableLocation
    122 {
    123    static constexpr unsigned int kUnused = GL_INVALID_INDEX;
    124 
    125    VariableLocation();
    126    VariableLocation(unsigned int arrayIndex, unsigned int index);
    127 
    128    // If used is false, it means this location is only used to fill an empty space in an array,
    129    // and there is no corresponding uniform variable for this location. It can also mean the
    130    // uniform was optimized out by the implementation.
    131    bool used() const { return (index != kUnused); }
    132    void markUnused() { index = kUnused; }
    133    void markIgnored() { ignored = true; }
    134 
    135    bool operator==(const VariableLocation &other) const
    136    {
    137        return arrayIndex == other.arrayIndex && index == other.index;
    138    }
    139 
    140    // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
    141    unsigned int arrayIndex;
    142    // "index" is an index of the variable. The variable contains the indices for other than the
    143    // innermost GLSL arrays.
    144    unsigned int index;
    145 
    146    // If this location was bound to an unreferenced uniform.  Setting data on this uniform is a
    147    // no-op.
    148    bool ignored;
    149 };
    150 
    151 // Information about a variable binding.
    152 // Currently used by CHROMIUM_path_rendering
    153 struct BindingInfo
    154 {
    155    // The type of binding, for example GL_FLOAT_VEC3.
    156    // This can be GL_NONE if the variable is optimized away.
    157    GLenum type;
    158 
    159    // This is the name of the variable in
    160    // the translated shader program. Note that
    161    // this can be empty in the case where the
    162    // variable has been optimized away.
    163    std::string name;
    164 
    165    // True if the binding is valid, otherwise false.
    166    bool valid;
    167 };
    168 
    169 struct ProgramBinding
    170 {
    171    ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {}
    172    ProgramBinding(GLuint index) : location(index), aliased(false) {}
    173 
    174    GLuint location;
    175    // Whether another binding was set that may potentially alias this.
    176    bool aliased;
    177 };
    178 
    179 class ProgramBindings final : angle::NonCopyable
    180 {
    181  public:
    182    ProgramBindings();
    183    ~ProgramBindings();
    184 
    185    void bindLocation(GLuint index, const std::string &name);
    186    int getBindingByName(const std::string &name) const;
    187    int getBinding(const sh::ShaderVariable &variable) const;
    188 
    189    using const_iterator = angle::HashMap<std::string, GLuint>::const_iterator;
    190    const_iterator begin() const;
    191    const_iterator end() const;
    192 
    193    std::map<std::string, GLuint> getStableIterationMap() const;
    194 
    195  private:
    196    angle::HashMap<std::string, GLuint> mBindings;
    197 };
    198 
    199 // Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]")
    200 class ProgramAliasedBindings final : angle::NonCopyable
    201 {
    202  public:
    203    ProgramAliasedBindings();
    204    ~ProgramAliasedBindings();
    205 
    206    void bindLocation(GLuint index, const std::string &name);
    207    int getBindingByName(const std::string &name) const;
    208    int getBindingByLocation(GLuint location) const;
    209    int getBinding(const sh::ShaderVariable &variable) const;
    210 
    211    using const_iterator = angle::HashMap<std::string, ProgramBinding>::const_iterator;
    212    const_iterator begin() const;
    213    const_iterator end() const;
    214 
    215    std::map<std::string, ProgramBinding> getStableIterationMap() const;
    216 
    217  private:
    218    angle::HashMap<std::string, ProgramBinding> mBindings;
    219 };
    220 
    221 class ProgramState final : angle::NonCopyable
    222 {
    223  public:
    224    ProgramState();
    225    ~ProgramState();
    226 
    227    const std::string &getLabel();
    228 
    229    Shader *getAttachedShader(ShaderType shaderType) const;
    230    const gl::ShaderMap<Shader *> &getAttachedShaders() const { return mAttachedShaders; }
    231    const std::vector<std::string> &getTransformFeedbackVaryingNames() const
    232    {
    233        return mTransformFeedbackVaryingNames;
    234    }
    235    GLint getTransformFeedbackBufferMode() const
    236    {
    237        return mExecutable->getTransformFeedbackBufferMode();
    238    }
    239    GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
    240    {
    241        return mExecutable->getUniformBlockBinding(uniformBlockIndex);
    242    }
    243    GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
    244    {
    245        return mExecutable->getShaderStorageBlockBinding(blockIndex);
    246    }
    247    const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const
    248    {
    249        return mExecutable->getActiveUniformBlockBindings();
    250    }
    251    const std::vector<sh::ShaderVariable> &getProgramInputs() const
    252    {
    253        return mExecutable->getProgramInputs();
    254    }
    255    const std::vector<sh::ShaderVariable> &getOutputVariables() const
    256    {
    257        return mExecutable->getOutputVariables();
    258    }
    259    const std::vector<VariableLocation> &getOutputLocations() const
    260    {
    261        return mExecutable->getOutputLocations();
    262    }
    263    const std::vector<VariableLocation> &getSecondaryOutputLocations() const
    264    {
    265        return mExecutable->getSecondaryOutputLocations();
    266    }
    267    const std::vector<LinkedUniform> &getUniforms() const { return mExecutable->getUniforms(); }
    268    const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
    269    const std::vector<InterfaceBlock> &getUniformBlocks() const
    270    {
    271        return mExecutable->getUniformBlocks();
    272    }
    273    const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
    274    {
    275        return mExecutable->getShaderStorageBlocks();
    276    }
    277    const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
    278    const std::vector<SamplerBinding> &getSamplerBindings() const
    279    {
    280        return mExecutable->getSamplerBindings();
    281    }
    282    const std::vector<ImageBinding> &getImageBindings() const
    283    {
    284        return getExecutable().getImageBindings();
    285    }
    286    const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
    287    const RangeUI &getDefaultUniformRange() const { return mExecutable->getDefaultUniformRange(); }
    288    const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); }
    289    const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); }
    290    const RangeUI &getAtomicCounterUniformRange() const
    291    {
    292        return mExecutable->getAtomicCounterUniformRange();
    293    }
    294    const RangeUI &getFragmentInoutRange() const { return mExecutable->getFragmentInoutRange(); }
    295 
    296    const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
    297    {
    298        return mExecutable->getLinkedTransformFeedbackVaryings();
    299    }
    300    const std::vector<GLsizei> &getTransformFeedbackStrides() const
    301    {
    302        return mExecutable->getTransformFeedbackStrides();
    303    }
    304    const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
    305    {
    306        return mExecutable->getAtomicCounterBuffers();
    307    }
    308 
    309    GLuint getUniformIndexFromName(const std::string &name) const;
    310    GLuint getUniformIndexFromLocation(UniformLocation location) const;
    311    Optional<GLuint> getSamplerIndex(UniformLocation location) const;
    312    bool isSamplerUniformIndex(GLuint index) const;
    313    GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
    314    GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
    315    bool isImageUniformIndex(GLuint index) const;
    316    GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
    317    GLuint getAttributeLocation(const std::string &name) const;
    318 
    319    GLuint getBufferVariableIndexFromName(const std::string &name) const;
    320 
    321    int getNumViews() const { return mNumViews; }
    322    bool usesMultiview() const { return mNumViews != -1; }
    323 
    324    bool hasAttachedShader() const;
    325 
    326    ShaderType getFirstAttachedShaderStageType() const;
    327    ShaderType getLastAttachedShaderStageType() const;
    328 
    329    const ProgramAliasedBindings &getUniformLocationBindings() const
    330    {
    331        return mUniformLocationBindings;
    332    }
    333 
    334    const ProgramExecutable &getExecutable() const
    335    {
    336        ASSERT(mExecutable);
    337        return *mExecutable;
    338    }
    339    ProgramExecutable &getExecutable()
    340    {
    341        ASSERT(mExecutable);
    342        return *mExecutable;
    343    }
    344 
    345    bool hasImages() const { return !getImageBindings().empty(); }
    346    rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
    347 
    348    // A Program can only either be graphics or compute, but never both, so it
    349    // can answer isCompute() based on which shaders it has.
    350    bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); }
    351 
    352    const std::string &getLabel() const { return mLabel; }
    353 
    354    uint32_t getLocationsUsedForXfbExtension() const { return mLocationsUsedForXfbExtension; }
    355 
    356    bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; }
    357 
    358    bool isSeparable() const { return mSeparable; }
    359 
    360    int getDrawIDLocation() const { return mDrawIDLocation; }
    361 
    362    int getBaseVertexLocation() const { return mBaseVertexLocation; }
    363 
    364    int getBaseInstanceLocation() const { return mBaseInstanceLocation; }
    365 
    366    ShaderType getAttachedTransformFeedbackStage() const;
    367 
    368  private:
    369    friend class MemoryProgramCache;
    370    friend class Program;
    371 
    372    void updateActiveSamplers();
    373    void updateProgramInterfaceInputs(const Context *context);
    374    void updateProgramInterfaceOutputs(const Context *context);
    375 
    376    // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
    377    void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
    378 
    379    std::string mLabel;
    380 
    381    sh::WorkGroupSize mComputeShaderLocalSize;
    382 
    383    ShaderMap<Shader *> mAttachedShaders;
    384 
    385    uint32_t mLocationsUsedForXfbExtension;
    386    std::vector<std::string> mTransformFeedbackVaryingNames;
    387 
    388    std::vector<VariableLocation> mUniformLocations;
    389    std::vector<BufferVariable> mBufferVariables;
    390 
    391    bool mBinaryRetrieveableHint;
    392    bool mSeparable;
    393    rx::SpecConstUsageBits mSpecConstUsageBits;
    394 
    395    // ANGLE_multiview.
    396    int mNumViews;
    397 
    398    // GL_ANGLE_multi_draw
    399    int mDrawIDLocation;
    400 
    401    // GL_ANGLE_base_vertex_base_instance_shader_builtin
    402    int mBaseVertexLocation;
    403    int mBaseInstanceLocation;
    404    // Cached value of base vertex and base instance
    405    // need to reset them to zero if using non base vertex or base instance draw calls.
    406    GLint mCachedBaseVertex;
    407    GLuint mCachedBaseInstance;
    408 
    409    // Note that this has nothing to do with binding layout qualifiers that can be set for some
    410    // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
    411    ProgramAliasedBindings mUniformLocationBindings;
    412 
    413    std::shared_ptr<ProgramExecutable> mExecutable;
    414 };
    415 
    416 struct ProgramVaryingRef
    417 {
    418    const sh::ShaderVariable *get(ShaderType stage) const
    419    {
    420        ASSERT(stage == frontShaderStage || stage == backShaderStage);
    421        const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
    422        ASSERT(ref);
    423        return ref;
    424    }
    425 
    426    const sh::ShaderVariable *frontShader = nullptr;
    427    const sh::ShaderVariable *backShader  = nullptr;
    428    ShaderType frontShaderStage           = ShaderType::InvalidEnum;
    429    ShaderType backShaderStage            = ShaderType::InvalidEnum;
    430 };
    431 
    432 using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
    433 
    434 class Program final : public LabeledObject, public angle::Subject
    435 {
    436  public:
    437    Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle);
    438    void onDestroy(const Context *context);
    439 
    440    ShaderProgramID id() const;
    441 
    442    angle::Result setLabel(const Context *context, const std::string &label) override;
    443    const std::string &getLabel() const override;
    444 
    445    ANGLE_INLINE rx::ProgramImpl *getImplementation() const
    446    {
    447        ASSERT(!mLinkingState);
    448        return mProgram;
    449    }
    450 
    451    void attachShader(Shader *shader);
    452    void detachShader(const Context *context, Shader *shader);
    453    int getAttachedShadersCount() const;
    454 
    455    Shader *getAttachedShader(ShaderType shaderType) const;
    456 
    457    void bindAttributeLocation(GLuint index, const char *name);
    458    void bindUniformLocation(UniformLocation location, const char *name);
    459 
    460    // EXT_blend_func_extended
    461    void bindFragmentOutputLocation(GLuint index, const char *name);
    462    void bindFragmentOutputIndex(GLuint index, const char *name);
    463 
    464    // KHR_parallel_shader_compile
    465    // Try to link the program asynchronously. As a result, background threads may be launched to
    466    // execute the linking tasks concurrently.
    467    angle::Result link(const Context *context);
    468 
    469    // Peek whether there is any running linking tasks.
    470    bool isLinking() const;
    471    bool hasLinkingState() const { return mLinkingState != nullptr; }
    472 
    473    bool isLinked() const
    474    {
    475        ASSERT(!mLinkingState);
    476        return mLinked;
    477    }
    478 
    479    angle::Result loadBinary(const Context *context,
    480                             GLenum binaryFormat,
    481                             const void *binary,
    482                             GLsizei length);
    483    angle::Result saveBinary(Context *context,
    484                             GLenum *binaryFormat,
    485                             void *binary,
    486                             GLsizei bufSize,
    487                             GLsizei *length) const;
    488    GLint getBinaryLength(Context *context) const;
    489    void setBinaryRetrievableHint(bool retrievable);
    490    bool getBinaryRetrievableHint() const;
    491 
    492    void setSeparable(bool separable);
    493    bool isSeparable() const;
    494 
    495    void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const;
    496 
    497    GLuint getAttributeLocation(const std::string &name) const;
    498 
    499    void getActiveAttribute(GLuint index,
    500                            GLsizei bufsize,
    501                            GLsizei *length,
    502                            GLint *size,
    503                            GLenum *type,
    504                            GLchar *name) const;
    505    GLint getActiveAttributeCount() const;
    506    GLint getActiveAttributeMaxLength() const;
    507    const std::vector<sh::ShaderVariable> &getAttributes() const;
    508 
    509    GLint getFragDataLocation(const std::string &name) const;
    510    size_t getOutputResourceCount() const;
    511 
    512    // EXT_blend_func_extended
    513    GLint getFragDataIndex(const std::string &name) const;
    514 
    515    void getActiveUniform(GLuint index,
    516                          GLsizei bufsize,
    517                          GLsizei *length,
    518                          GLint *size,
    519                          GLenum *type,
    520                          GLchar *name) const;
    521    GLint getActiveUniformCount() const;
    522    size_t getActiveBufferVariableCount() const;
    523    GLint getActiveUniformMaxLength() const;
    524    bool isValidUniformLocation(UniformLocation location) const;
    525    const LinkedUniform &getUniformByLocation(UniformLocation location) const;
    526    const VariableLocation &getUniformLocation(UniformLocation location) const;
    527 
    528    const std::vector<VariableLocation> &getUniformLocations() const
    529    {
    530        ASSERT(!mLinkingState);
    531        return mState.mUniformLocations;
    532    }
    533 
    534    const LinkedUniform &getUniformByIndex(GLuint index) const
    535    {
    536        ASSERT(!mLinkingState);
    537        return mState.mExecutable->getUniformByIndex(index);
    538    }
    539 
    540    const BufferVariable &getBufferVariableByIndex(GLuint index) const;
    541 
    542    enum SetUniformResult
    543    {
    544        SamplerChanged,
    545        NoSamplerChange,
    546    };
    547 
    548    UniformLocation getUniformLocation(const std::string &name) const;
    549    GLuint getUniformIndex(const std::string &name) const;
    550    void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
    551    void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
    552    void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
    553    void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
    554    void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
    555    void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
    556    void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
    557    void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
    558    void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
    559    void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
    560    void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
    561    void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
    562    void setUniformMatrix2fv(UniformLocation location,
    563                             GLsizei count,
    564                             GLboolean transpose,
    565                             const GLfloat *value);
    566    void setUniformMatrix3fv(UniformLocation location,
    567                             GLsizei count,
    568                             GLboolean transpose,
    569                             const GLfloat *value);
    570    void setUniformMatrix4fv(UniformLocation location,
    571                             GLsizei count,
    572                             GLboolean transpose,
    573                             const GLfloat *value);
    574    void setUniformMatrix2x3fv(UniformLocation location,
    575                               GLsizei count,
    576                               GLboolean transpose,
    577                               const GLfloat *value);
    578    void setUniformMatrix3x2fv(UniformLocation location,
    579                               GLsizei count,
    580                               GLboolean transpose,
    581                               const GLfloat *value);
    582    void setUniformMatrix2x4fv(UniformLocation location,
    583                               GLsizei count,
    584                               GLboolean transpose,
    585                               const GLfloat *value);
    586    void setUniformMatrix4x2fv(UniformLocation location,
    587                               GLsizei count,
    588                               GLboolean transpose,
    589                               const GLfloat *value);
    590    void setUniformMatrix3x4fv(UniformLocation location,
    591                               GLsizei count,
    592                               GLboolean transpose,
    593                               const GLfloat *value);
    594    void setUniformMatrix4x3fv(UniformLocation location,
    595                               GLsizei count,
    596                               GLboolean transpose,
    597                               const GLfloat *value);
    598 
    599    void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
    600    void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
    601    void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;
    602 
    603    void getActiveUniformBlockName(const Context *context,
    604                                   const UniformBlockIndex blockIndex,
    605                                   GLsizei bufSize,
    606                                   GLsizei *length,
    607                                   GLchar *blockName) const;
    608    void getActiveShaderStorageBlockName(const GLuint blockIndex,
    609                                         GLsizei bufSize,
    610                                         GLsizei *length,
    611                                         GLchar *blockName) const;
    612 
    613    ANGLE_INLINE GLuint getActiveUniformBlockCount() const
    614    {
    615        ASSERT(!mLinkingState);
    616        return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount());
    617    }
    618 
    619    ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
    620    {
    621        ASSERT(!mLinkingState);
    622        return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount());
    623    }
    624 
    625    ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
    626    {
    627        ASSERT(!mLinkingState);
    628        return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount());
    629    }
    630 
    631    GLint getActiveUniformBlockMaxNameLength() const;
    632    GLint getActiveShaderStorageBlockMaxNameLength() const;
    633 
    634    const std::vector<LinkedUniform> &getUniforms() const { return mState.getUniforms(); }
    635    GLuint getUniformBlockIndex(const std::string &name) const;
    636    GLuint getShaderStorageBlockIndex(const std::string &name) const;
    637 
    638    void bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding);
    639    GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
    640    GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
    641 
    642    const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
    643    const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
    644 
    645    void setTransformFeedbackVaryings(GLsizei count,
    646                                      const GLchar *const *varyings,
    647                                      GLenum bufferMode);
    648    void getTransformFeedbackVarying(GLuint index,
    649                                     GLsizei bufSize,
    650                                     GLsizei *length,
    651                                     GLsizei *size,
    652                                     GLenum *type,
    653                                     GLchar *name) const;
    654    GLsizei getTransformFeedbackVaryingCount() const;
    655    GLsizei getTransformFeedbackVaryingMaxLength() const;
    656    GLenum getTransformFeedbackBufferMode() const;
    657    GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
    658    const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
    659 
    660    bool hasDrawIDUniform() const;
    661    void setDrawIDUniform(GLint drawid);
    662 
    663    bool hasBaseVertexUniform() const;
    664    void setBaseVertexUniform(GLint baseVertex);
    665    bool hasBaseInstanceUniform() const;
    666    void setBaseInstanceUniform(GLuint baseInstance);
    667 
    668    ANGLE_INLINE void addRef()
    669    {
    670        ASSERT(!mLinkingState);
    671        mRefCount++;
    672    }
    673 
    674    ANGLE_INLINE void release(const Context *context)
    675    {
    676        ASSERT(!mLinkingState);
    677        mRefCount--;
    678 
    679        if (mRefCount == 0 && mDeleteStatus)
    680        {
    681            deleteSelf(context);
    682        }
    683    }
    684 
    685    unsigned int getRefCount() const;
    686    bool isInUse() const { return getRefCount() != 0; }
    687    void flagForDeletion();
    688    bool isFlaggedForDeletion() const;
    689 
    690    void validate(const Caps &caps);
    691    bool isValidated() const;
    692 
    693    const std::vector<ImageBinding> &getImageBindings() const
    694    {
    695        ASSERT(!mLinkingState);
    696        return getExecutable().getImageBindings();
    697    }
    698    const sh::WorkGroupSize &getComputeShaderLocalSize() const;
    699    PrimitiveMode getGeometryShaderInputPrimitiveType() const;
    700    PrimitiveMode getGeometryShaderOutputPrimitiveType() const;
    701    GLint getGeometryShaderInvocations() const;
    702    GLint getGeometryShaderMaxVertices() const;
    703 
    704    GLint getTessControlShaderVertices() const;
    705    GLenum getTessGenMode() const;
    706    GLenum getTessGenPointMode() const;
    707    GLenum getTessGenSpacing() const;
    708    GLenum getTessGenVertexOrder() const;
    709 
    710    const ProgramState &getState() const
    711    {
    712        ASSERT(!mLinkingState);
    713        return mState;
    714    }
    715 
    716    GLuint getInputResourceIndex(const GLchar *name) const;
    717    GLuint getOutputResourceIndex(const GLchar *name) const;
    718    void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    719    void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    720    void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
    721    void getBufferVariableResourceName(GLuint index,
    722                                       GLsizei bufSize,
    723                                       GLsizei *length,
    724                                       GLchar *name) const;
    725    const sh::ShaderVariable &getInputResource(size_t index) const;
    726    GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const;
    727    GLuint getInputResourceMaxNameSize() const;
    728    GLuint getOutputResourceMaxNameSize() const;
    729    GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const;
    730    GLuint getInputResourceLocation(const GLchar *name) const;
    731    GLuint getOutputResourceLocation(const GLchar *name) const;
    732    const std::string getResourceName(const sh::ShaderVariable &resource) const;
    733    const std::string getInputResourceName(GLuint index) const;
    734    const std::string getOutputResourceName(GLuint index) const;
    735    const sh::ShaderVariable &getOutputResource(size_t index) const;
    736 
    737    const ProgramBindings &getAttributeBindings() const;
    738    const ProgramAliasedBindings &getUniformLocationBindings() const;
    739    const ProgramAliasedBindings &getFragmentOutputLocations() const;
    740    const ProgramAliasedBindings &getFragmentOutputIndexes() const;
    741 
    742    int getNumViews() const
    743    {
    744        ASSERT(!mLinkingState);
    745        return mState.getNumViews();
    746    }
    747 
    748    bool usesMultiview() const { return mState.usesMultiview(); }
    749 
    750    const std::vector<GLsizei> &getTransformFeedbackStrides() const;
    751 
    752    // Program dirty bits.
    753    enum DirtyBitType
    754    {
    755        DIRTY_BIT_UNIFORM_BLOCK_BINDING_0,
    756        DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX =
    757            DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS,
    758 
    759        DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX,
    760    };
    761 
    762    using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
    763 
    764    angle::Result syncState(const Context *context);
    765 
    766    // Try to resolve linking. Inlined to make sure its overhead is as low as possible.
    767    void resolveLink(const Context *context)
    768    {
    769        if (mLinkingState)
    770        {
    771            resolveLinkImpl(context);
    772        }
    773    }
    774 
    775    ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
    776 
    777    // Writes a program's binary to the output memory buffer.
    778    angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
    779 
    780    rx::Serial serial() const { return mSerial; }
    781 
    782    const ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
    783    ProgramExecutable &getExecutable() { return mState.getExecutable(); }
    784 
    785  private:
    786    struct LinkingState;
    787 
    788    ~Program() override;
    789 
    790    // Loads program state according to the specified binary blob.
    791    angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog);
    792 
    793    void unlink();
    794    void deleteSelf(const Context *context);
    795 
    796    angle::Result linkImpl(const Context *context);
    797 
    798    bool linkValidateShaders(const Context *context, InfoLog &infoLog);
    799    bool linkAttributes(const Context *context, InfoLog &infoLog);
    800    bool linkVaryings(const Context *context, InfoLog &infoLog) const;
    801 
    802    bool linkUniforms(const Context *context,
    803                      std::vector<UnusedUniform> *unusedUniformsOutOrNull,
    804                      GLuint *combinedImageUniformsOut,
    805                      InfoLog &infoLog);
    806 
    807    void updateLinkedShaderStages();
    808 
    809    void setUniformValuesFromBindingQualifiers();
    810    bool shouldIgnoreUniform(UniformLocation location) const;
    811 
    812    void initInterfaceBlockBindings();
    813 
    814    // Both these function update the cached uniform values and return a modified "count"
    815    // so that the uniform update doesn't overflow the uniform.
    816    template <typename T>
    817    GLsizei clampUniformCount(const VariableLocation &locationInfo,
    818                              GLsizei count,
    819                              int vectorSize,
    820                              const T *v);
    821    template <size_t cols, size_t rows, typename T>
    822    GLsizei clampMatrixUniformCount(UniformLocation location,
    823                                    GLsizei count,
    824                                    GLboolean transpose,
    825                                    const T *v);
    826 
    827    void updateSamplerUniform(Context *context,
    828                              const VariableLocation &locationInfo,
    829                              GLsizei clampedCount,
    830                              const GLint *v);
    831 
    832    template <typename DestT>
    833    void getUniformInternal(const Context *context,
    834                            DestT *dataOut,
    835                            UniformLocation location,
    836                            GLenum nativeType,
    837                            int components) const;
    838 
    839    void getResourceName(const std::string name,
    840                         GLsizei bufSize,
    841                         GLsizei *length,
    842                         GLchar *dest) const;
    843 
    844    template <typename T>
    845    GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const;
    846 
    847    GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
    848    GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;
    849 
    850    // Block until linking is finished and resolve it.
    851    void resolveLinkImpl(const gl::Context *context);
    852 
    853    void postResolveLink(const gl::Context *context);
    854 
    855    template <typename UniformT,
    856              GLint UniformSize,
    857              void (rx::ProgramImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
    858    void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v);
    859 
    860    template <
    861        typename UniformT,
    862        GLint MatrixC,
    863        GLint MatrixR,
    864        void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
    865    void setUniformMatrixGeneric(UniformLocation location,
    866                                 GLsizei count,
    867                                 GLboolean transpose,
    868                                 const UniformT *v);
    869 
    870    rx::Serial mSerial;
    871    ProgramState mState;
    872    rx::ProgramImpl *mProgram;
    873 
    874    bool mValidated;
    875 
    876    ProgramBindings mAttributeBindings;
    877 
    878    // EXT_blend_func_extended
    879    ProgramAliasedBindings mFragmentOutputLocations;
    880    ProgramAliasedBindings mFragmentOutputIndexes;
    881 
    882    bool mLinked;
    883    std::unique_ptr<LinkingState> mLinkingState;
    884    bool mDeleteStatus;  // Flag to indicate that the program can be deleted when no longer in use
    885 
    886    unsigned int mRefCount;
    887 
    888    ShaderProgramManager *mResourceManager;
    889    const ShaderProgramID mHandle;
    890 
    891    DirtyBits mDirtyBits;
    892 
    893    std::mutex mHistogramMutex;
    894 };
    895 }  // namespace gl
    896 
    897 #endif  // LIBANGLE_PROGRAM_H_