1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // Program.h: Defines the gl::Program class. Implements GL program objects 8*8975f5c5SAndroid Build Coastguard Worker // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28. 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_PROGRAM_H_ 11*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_PROGRAM_H_ 12*8975f5c5SAndroid Build Coastguard Worker 13*8975f5c5SAndroid Build Coastguard Worker #include <GLES2/gl2.h> 14*8975f5c5SAndroid Build Coastguard Worker #include <GLSLANG/ShaderVars.h> 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker #include <array> 17*8975f5c5SAndroid Build Coastguard Worker #include <map> 18*8975f5c5SAndroid Build Coastguard Worker #include <memory> 19*8975f5c5SAndroid Build Coastguard Worker #include <set> 20*8975f5c5SAndroid Build Coastguard Worker #include <sstream> 21*8975f5c5SAndroid Build Coastguard Worker #include <string> 22*8975f5c5SAndroid Build Coastguard Worker #include <vector> 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker #include "common/Optional.h" 25*8975f5c5SAndroid Build Coastguard Worker #include "common/SimpleMutex.h" 26*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h" 27*8975f5c5SAndroid Build Coastguard Worker #include "common/hash_containers.h" 28*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h" 29*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h" 30*8975f5c5SAndroid Build Coastguard Worker 31*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Constants.h" 32*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Debug.h" 33*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h" 34*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/InfoLog.h" 35*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ProgramExecutable.h" 36*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ProgramLinkedResources.h" 37*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/RefCountObject.h" 38*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Shader.h" 39*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Uniform.h" 40*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h" 41*8975f5c5SAndroid Build Coastguard Worker 42*8975f5c5SAndroid Build Coastguard Worker namespace rx 43*8975f5c5SAndroid Build Coastguard Worker { 44*8975f5c5SAndroid Build Coastguard Worker class GLImplFactory; 45*8975f5c5SAndroid Build Coastguard Worker class ProgramImpl; 46*8975f5c5SAndroid Build Coastguard Worker class LinkSubTask; 47*8975f5c5SAndroid Build Coastguard Worker struct TranslatedAttribute; 48*8975f5c5SAndroid Build Coastguard Worker } // namespace rx 49*8975f5c5SAndroid Build Coastguard Worker 50*8975f5c5SAndroid Build Coastguard Worker namespace gl 51*8975f5c5SAndroid Build Coastguard Worker { 52*8975f5c5SAndroid Build Coastguard Worker class Buffer; 53*8975f5c5SAndroid Build Coastguard Worker class BinaryInputStream; 54*8975f5c5SAndroid Build Coastguard Worker class BinaryOutputStream; 55*8975f5c5SAndroid Build Coastguard Worker struct Caps; 56*8975f5c5SAndroid Build Coastguard Worker class Context; 57*8975f5c5SAndroid Build Coastguard Worker struct Extensions; 58*8975f5c5SAndroid Build Coastguard Worker class Framebuffer; 59*8975f5c5SAndroid Build Coastguard Worker class ProgramExecutable; 60*8975f5c5SAndroid Build Coastguard Worker class ShaderProgramManager; 61*8975f5c5SAndroid Build Coastguard Worker class State; 62*8975f5c5SAndroid Build Coastguard Worker struct UnusedUniform; 63*8975f5c5SAndroid Build Coastguard Worker struct Version; 64*8975f5c5SAndroid Build Coastguard Worker 65*8975f5c5SAndroid Build Coastguard Worker extern const char *const g_fakepath; 66*8975f5c5SAndroid Build Coastguard Worker 67*8975f5c5SAndroid Build Coastguard Worker enum class LinkMismatchError 68*8975f5c5SAndroid Build Coastguard Worker { 69*8975f5c5SAndroid Build Coastguard Worker // Shared 70*8975f5c5SAndroid Build Coastguard Worker NO_MISMATCH, 71*8975f5c5SAndroid Build Coastguard Worker TYPE_MISMATCH, 72*8975f5c5SAndroid Build Coastguard Worker ARRAYNESS_MISMATCH, 73*8975f5c5SAndroid Build Coastguard Worker ARRAY_SIZE_MISMATCH, 74*8975f5c5SAndroid Build Coastguard Worker PRECISION_MISMATCH, 75*8975f5c5SAndroid Build Coastguard Worker STRUCT_NAME_MISMATCH, 76*8975f5c5SAndroid Build Coastguard Worker FIELD_NUMBER_MISMATCH, 77*8975f5c5SAndroid Build Coastguard Worker FIELD_NAME_MISMATCH, 78*8975f5c5SAndroid Build Coastguard Worker 79*8975f5c5SAndroid Build Coastguard Worker // Varying specific 80*8975f5c5SAndroid Build Coastguard Worker INTERPOLATION_TYPE_MISMATCH, 81*8975f5c5SAndroid Build Coastguard Worker INVARIANCE_MISMATCH, 82*8975f5c5SAndroid Build Coastguard Worker 83*8975f5c5SAndroid Build Coastguard Worker // Uniform specific 84*8975f5c5SAndroid Build Coastguard Worker BINDING_MISMATCH, 85*8975f5c5SAndroid Build Coastguard Worker LOCATION_MISMATCH, 86*8975f5c5SAndroid Build Coastguard Worker OFFSET_MISMATCH, 87*8975f5c5SAndroid Build Coastguard Worker INSTANCE_NAME_MISMATCH, 88*8975f5c5SAndroid Build Coastguard Worker FORMAT_MISMATCH, 89*8975f5c5SAndroid Build Coastguard Worker 90*8975f5c5SAndroid Build Coastguard Worker // Interface block specific 91*8975f5c5SAndroid Build Coastguard Worker LAYOUT_QUALIFIER_MISMATCH, 92*8975f5c5SAndroid Build Coastguard Worker MATRIX_PACKING_MISMATCH, 93*8975f5c5SAndroid Build Coastguard Worker 94*8975f5c5SAndroid Build Coastguard Worker // I/O block specific 95*8975f5c5SAndroid Build Coastguard Worker FIELD_LOCATION_MISMATCH, 96*8975f5c5SAndroid Build Coastguard Worker FIELD_STRUCT_NAME_MISMATCH, 97*8975f5c5SAndroid Build Coastguard Worker }; 98*8975f5c5SAndroid Build Coastguard Worker 99*8975f5c5SAndroid Build Coastguard Worker void LogLinkMismatch(InfoLog &infoLog, 100*8975f5c5SAndroid Build Coastguard Worker const std::string &variableName, 101*8975f5c5SAndroid Build Coastguard Worker const char *variableType, 102*8975f5c5SAndroid Build Coastguard Worker LinkMismatchError linkError, 103*8975f5c5SAndroid Build Coastguard Worker const std::string &mismatchedStructOrBlockFieldName, 104*8975f5c5SAndroid Build Coastguard Worker ShaderType shaderType1, 105*8975f5c5SAndroid Build Coastguard Worker ShaderType shaderType2); 106*8975f5c5SAndroid Build Coastguard Worker 107*8975f5c5SAndroid Build Coastguard Worker bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock); 108*8975f5c5SAndroid Build Coastguard Worker 109*8975f5c5SAndroid Build Coastguard Worker // Struct used for correlating uniforms/elements of uniform arrays to handles 110*8975f5c5SAndroid Build Coastguard Worker ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 111*8975f5c5SAndroid Build Coastguard Worker struct VariableLocation 112*8975f5c5SAndroid Build Coastguard Worker { 113*8975f5c5SAndroid Build Coastguard Worker static constexpr unsigned int kUnused = GL_INVALID_INDEX; 114*8975f5c5SAndroid Build Coastguard Worker 115*8975f5c5SAndroid Build Coastguard Worker VariableLocation(); 116*8975f5c5SAndroid Build Coastguard Worker VariableLocation(unsigned int arrayIndex, unsigned int index); 117*8975f5c5SAndroid Build Coastguard Worker 118*8975f5c5SAndroid Build Coastguard Worker // If used is false, it means this location is only used to fill an empty space in an array, 119*8975f5c5SAndroid Build Coastguard Worker // and there is no corresponding uniform variable for this location. It can also mean the 120*8975f5c5SAndroid Build Coastguard Worker // uniform was optimized out by the implementation. usedVariableLocation121*8975f5c5SAndroid Build Coastguard Worker bool used() const { return (index != kUnused); } markUnusedVariableLocation122*8975f5c5SAndroid Build Coastguard Worker void markUnused() { index = kUnused; } markIgnoredVariableLocation123*8975f5c5SAndroid Build Coastguard Worker void markIgnored() { ignored = true; } 124*8975f5c5SAndroid Build Coastguard Worker 125*8975f5c5SAndroid Build Coastguard Worker bool operator==(const VariableLocation &other) const 126*8975f5c5SAndroid Build Coastguard Worker { 127*8975f5c5SAndroid Build Coastguard Worker return arrayIndex == other.arrayIndex && index == other.index; 128*8975f5c5SAndroid Build Coastguard Worker } 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard Worker // "index" is an index of the variable. The variable contains the indices for other than the 131*8975f5c5SAndroid Build Coastguard Worker // innermost GLSL arrays. 132*8975f5c5SAndroid Build Coastguard Worker uint32_t index; 133*8975f5c5SAndroid Build Coastguard Worker 134*8975f5c5SAndroid Build Coastguard Worker // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. 135*8975f5c5SAndroid Build Coastguard Worker uint32_t arrayIndex : 31; 136*8975f5c5SAndroid Build Coastguard Worker // If this location was bound to an unreferenced uniform. Setting data on this uniform is a 137*8975f5c5SAndroid Build Coastguard Worker // no-op. 138*8975f5c5SAndroid Build Coastguard Worker uint32_t ignored : 1; 139*8975f5c5SAndroid Build Coastguard Worker }; 140*8975f5c5SAndroid Build Coastguard Worker ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 141*8975f5c5SAndroid Build Coastguard Worker 142*8975f5c5SAndroid Build Coastguard Worker // Information about a variable binding. 143*8975f5c5SAndroid Build Coastguard Worker // Currently used by CHROMIUM_path_rendering 144*8975f5c5SAndroid Build Coastguard Worker struct BindingInfo 145*8975f5c5SAndroid Build Coastguard Worker { 146*8975f5c5SAndroid Build Coastguard Worker // The type of binding, for example GL_FLOAT_VEC3. 147*8975f5c5SAndroid Build Coastguard Worker // This can be GL_NONE if the variable is optimized away. 148*8975f5c5SAndroid Build Coastguard Worker GLenum type; 149*8975f5c5SAndroid Build Coastguard Worker 150*8975f5c5SAndroid Build Coastguard Worker // This is the name of the variable in 151*8975f5c5SAndroid Build Coastguard Worker // the translated shader program. Note that 152*8975f5c5SAndroid Build Coastguard Worker // this can be empty in the case where the 153*8975f5c5SAndroid Build Coastguard Worker // variable has been optimized away. 154*8975f5c5SAndroid Build Coastguard Worker std::string name; 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker // True if the binding is valid, otherwise false. 157*8975f5c5SAndroid Build Coastguard Worker bool valid; 158*8975f5c5SAndroid Build Coastguard Worker }; 159*8975f5c5SAndroid Build Coastguard Worker 160*8975f5c5SAndroid Build Coastguard Worker struct ProgramBinding 161*8975f5c5SAndroid Build Coastguard Worker { ProgramBindingProgramBinding162*8975f5c5SAndroid Build Coastguard Worker ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {} ProgramBindingProgramBinding163*8975f5c5SAndroid Build Coastguard Worker ProgramBinding(GLuint index) : location(index), aliased(false) {} 164*8975f5c5SAndroid Build Coastguard Worker 165*8975f5c5SAndroid Build Coastguard Worker GLuint location; 166*8975f5c5SAndroid Build Coastguard Worker // Whether another binding was set that may potentially alias this. 167*8975f5c5SAndroid Build Coastguard Worker bool aliased; 168*8975f5c5SAndroid Build Coastguard Worker }; 169*8975f5c5SAndroid Build Coastguard Worker 170*8975f5c5SAndroid Build Coastguard Worker class ProgramBindings final : angle::NonCopyable 171*8975f5c5SAndroid Build Coastguard Worker { 172*8975f5c5SAndroid Build Coastguard Worker public: 173*8975f5c5SAndroid Build Coastguard Worker ProgramBindings(); 174*8975f5c5SAndroid Build Coastguard Worker ~ProgramBindings(); 175*8975f5c5SAndroid Build Coastguard Worker 176*8975f5c5SAndroid Build Coastguard Worker void bindLocation(GLuint index, const std::string &name); 177*8975f5c5SAndroid Build Coastguard Worker int getBindingByName(const std::string &name) const; 178*8975f5c5SAndroid Build Coastguard Worker template <typename T> 179*8975f5c5SAndroid Build Coastguard Worker int getBinding(const T &variable) const; 180*8975f5c5SAndroid Build Coastguard Worker 181*8975f5c5SAndroid Build Coastguard Worker using const_iterator = angle::HashMap<std::string, GLuint>::const_iterator; 182*8975f5c5SAndroid Build Coastguard Worker const_iterator begin() const; 183*8975f5c5SAndroid Build Coastguard Worker const_iterator end() const; 184*8975f5c5SAndroid Build Coastguard Worker 185*8975f5c5SAndroid Build Coastguard Worker std::map<std::string, GLuint> getStableIterationMap() const; 186*8975f5c5SAndroid Build Coastguard Worker 187*8975f5c5SAndroid Build Coastguard Worker private: 188*8975f5c5SAndroid Build Coastguard Worker angle::HashMap<std::string, GLuint> mBindings; 189*8975f5c5SAndroid Build Coastguard Worker }; 190*8975f5c5SAndroid Build Coastguard Worker 191*8975f5c5SAndroid Build Coastguard Worker // Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]") 192*8975f5c5SAndroid Build Coastguard Worker class ProgramAliasedBindings final : angle::NonCopyable 193*8975f5c5SAndroid Build Coastguard Worker { 194*8975f5c5SAndroid Build Coastguard Worker public: 195*8975f5c5SAndroid Build Coastguard Worker ProgramAliasedBindings(); 196*8975f5c5SAndroid Build Coastguard Worker ~ProgramAliasedBindings(); 197*8975f5c5SAndroid Build Coastguard Worker 198*8975f5c5SAndroid Build Coastguard Worker void bindLocation(GLuint index, const std::string &name); 199*8975f5c5SAndroid Build Coastguard Worker int getBindingByName(const std::string &name) const; 200*8975f5c5SAndroid Build Coastguard Worker int getBindingByLocation(GLuint location) const; 201*8975f5c5SAndroid Build Coastguard Worker template <typename T> 202*8975f5c5SAndroid Build Coastguard Worker int getBinding(const T &variable) const; 203*8975f5c5SAndroid Build Coastguard Worker 204*8975f5c5SAndroid Build Coastguard Worker using const_iterator = angle::HashMap<std::string, ProgramBinding>::const_iterator; 205*8975f5c5SAndroid Build Coastguard Worker const_iterator begin() const; 206*8975f5c5SAndroid Build Coastguard Worker const_iterator end() const; 207*8975f5c5SAndroid Build Coastguard Worker 208*8975f5c5SAndroid Build Coastguard Worker std::map<std::string, ProgramBinding> getStableIterationMap() const; 209*8975f5c5SAndroid Build Coastguard Worker 210*8975f5c5SAndroid Build Coastguard Worker private: 211*8975f5c5SAndroid Build Coastguard Worker angle::HashMap<std::string, ProgramBinding> mBindings; 212*8975f5c5SAndroid Build Coastguard Worker }; 213*8975f5c5SAndroid Build Coastguard Worker 214*8975f5c5SAndroid Build Coastguard Worker class ProgramState final : angle::NonCopyable 215*8975f5c5SAndroid Build Coastguard Worker { 216*8975f5c5SAndroid Build Coastguard Worker public: 217*8975f5c5SAndroid Build Coastguard Worker ProgramState(rx::GLImplFactory *factory); 218*8975f5c5SAndroid Build Coastguard Worker ~ProgramState(); 219*8975f5c5SAndroid Build Coastguard Worker 220*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel(); 221*8975f5c5SAndroid Build Coastguard Worker 222*8975f5c5SAndroid Build Coastguard Worker SharedCompiledShaderState getAttachedShader(ShaderType shaderType) const; getAttachedShaders()223*8975f5c5SAndroid Build Coastguard Worker const ShaderMap<SharedCompiledShaderState> &getAttachedShaders() const 224*8975f5c5SAndroid Build Coastguard Worker { 225*8975f5c5SAndroid Build Coastguard Worker return mAttachedShaders; 226*8975f5c5SAndroid Build Coastguard Worker } getTransformFeedbackVaryingNames()227*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::string> &getTransformFeedbackVaryingNames() const 228*8975f5c5SAndroid Build Coastguard Worker { 229*8975f5c5SAndroid Build Coastguard Worker return mTransformFeedbackVaryingNames; 230*8975f5c5SAndroid Build Coastguard Worker } getTransformFeedbackBufferMode()231*8975f5c5SAndroid Build Coastguard Worker GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } 232*8975f5c5SAndroid Build Coastguard Worker 233*8975f5c5SAndroid Build Coastguard Worker bool hasAnyAttachedShader() const; 234*8975f5c5SAndroid Build Coastguard Worker getAttributeBindings()235*8975f5c5SAndroid Build Coastguard Worker const ProgramBindings &getAttributeBindings() const { return mAttributeBindings; } getUniformLocationBindings()236*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getUniformLocationBindings() const 237*8975f5c5SAndroid Build Coastguard Worker { 238*8975f5c5SAndroid Build Coastguard Worker return mUniformLocationBindings; 239*8975f5c5SAndroid Build Coastguard Worker } getFragmentOutputLocations()240*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getFragmentOutputLocations() const 241*8975f5c5SAndroid Build Coastguard Worker { 242*8975f5c5SAndroid Build Coastguard Worker return mFragmentOutputLocations; 243*8975f5c5SAndroid Build Coastguard Worker } getFragmentOutputIndexes()244*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getFragmentOutputIndexes() const 245*8975f5c5SAndroid Build Coastguard Worker { 246*8975f5c5SAndroid Build Coastguard Worker return mFragmentOutputIndexes; 247*8975f5c5SAndroid Build Coastguard Worker } 248*8975f5c5SAndroid Build Coastguard Worker getExecutable()249*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &getExecutable() const 250*8975f5c5SAndroid Build Coastguard Worker { 251*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable); 252*8975f5c5SAndroid Build Coastguard Worker return *mExecutable; 253*8975f5c5SAndroid Build Coastguard Worker } getExecutable()254*8975f5c5SAndroid Build Coastguard Worker ProgramExecutable &getExecutable() 255*8975f5c5SAndroid Build Coastguard Worker { 256*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable); 257*8975f5c5SAndroid Build Coastguard Worker return *mExecutable; 258*8975f5c5SAndroid Build Coastguard Worker } 259*8975f5c5SAndroid Build Coastguard Worker getSharedExecutable()260*8975f5c5SAndroid Build Coastguard Worker const SharedProgramExecutable &getSharedExecutable() const 261*8975f5c5SAndroid Build Coastguard Worker { 262*8975f5c5SAndroid Build Coastguard Worker ASSERT(mExecutable); 263*8975f5c5SAndroid Build Coastguard Worker return mExecutable; 264*8975f5c5SAndroid Build Coastguard Worker } 265*8975f5c5SAndroid Build Coastguard Worker getLabel()266*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel() const { return mLabel; } 267*8975f5c5SAndroid Build Coastguard Worker hasBinaryRetrieveableHint()268*8975f5c5SAndroid Build Coastguard Worker bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; } 269*8975f5c5SAndroid Build Coastguard Worker isSeparable()270*8975f5c5SAndroid Build Coastguard Worker bool isSeparable() const { return mSeparable; } 271*8975f5c5SAndroid Build Coastguard Worker 272*8975f5c5SAndroid Build Coastguard Worker ShaderType getAttachedTransformFeedbackStage() const; 273*8975f5c5SAndroid Build Coastguard Worker 274*8975f5c5SAndroid Build Coastguard Worker private: 275*8975f5c5SAndroid Build Coastguard Worker friend class MemoryProgramCache; 276*8975f5c5SAndroid Build Coastguard Worker friend class Program; 277*8975f5c5SAndroid Build Coastguard Worker 278*8975f5c5SAndroid Build Coastguard Worker void updateActiveSamplers(); 279*8975f5c5SAndroid Build Coastguard Worker void updateProgramInterfaceInputs(); 280*8975f5c5SAndroid Build Coastguard Worker void updateProgramInterfaceOutputs(); 281*8975f5c5SAndroid Build Coastguard Worker 282*8975f5c5SAndroid Build Coastguard Worker // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'. 283*8975f5c5SAndroid Build Coastguard Worker void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex); 284*8975f5c5SAndroid Build Coastguard Worker 285*8975f5c5SAndroid Build Coastguard Worker std::string mLabel; 286*8975f5c5SAndroid Build Coastguard Worker 287*8975f5c5SAndroid Build Coastguard Worker ShaderMap<SharedCompileJob> mShaderCompileJobs; 288*8975f5c5SAndroid Build Coastguard Worker ShaderMap<SharedCompiledShaderState> mAttachedShaders; 289*8975f5c5SAndroid Build Coastguard Worker 290*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> mTransformFeedbackVaryingNames; 291*8975f5c5SAndroid Build Coastguard Worker GLenum mTransformFeedbackBufferMode; 292*8975f5c5SAndroid Build Coastguard Worker 293*8975f5c5SAndroid Build Coastguard Worker bool mBinaryRetrieveableHint; 294*8975f5c5SAndroid Build Coastguard Worker bool mSeparable; 295*8975f5c5SAndroid Build Coastguard Worker 296*8975f5c5SAndroid Build Coastguard Worker ProgramBindings mAttributeBindings; 297*8975f5c5SAndroid Build Coastguard Worker 298*8975f5c5SAndroid Build Coastguard Worker // Note that this has nothing to do with binding layout qualifiers that can be set for some 299*8975f5c5SAndroid Build Coastguard Worker // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. 300*8975f5c5SAndroid Build Coastguard Worker ProgramAliasedBindings mUniformLocationBindings; 301*8975f5c5SAndroid Build Coastguard Worker 302*8975f5c5SAndroid Build Coastguard Worker // EXT_blend_func_extended 303*8975f5c5SAndroid Build Coastguard Worker ProgramAliasedBindings mFragmentOutputLocations; 304*8975f5c5SAndroid Build Coastguard Worker ProgramAliasedBindings mFragmentOutputIndexes; 305*8975f5c5SAndroid Build Coastguard Worker 306*8975f5c5SAndroid Build Coastguard Worker InfoLog mInfoLog; 307*8975f5c5SAndroid Build Coastguard Worker 308*8975f5c5SAndroid Build Coastguard Worker // The result of the link. State that is not the link output should remain in ProgramState, 309*8975f5c5SAndroid Build Coastguard Worker // while the link output should be placed in ProgramExecutable. 310*8975f5c5SAndroid Build Coastguard Worker // 311*8975f5c5SAndroid Build Coastguard Worker // This is a shared_ptr because it can be "installed" in the context as part of the rendering 312*8975f5c5SAndroid Build Coastguard Worker // context. Similarly, it can be installed in a program pipeline. Once the executable is 313*8975f5c5SAndroid Build Coastguard Worker // installed, the actual Program should not be referenced; it may have been unsuccessfully 314*8975f5c5SAndroid Build Coastguard Worker // relinked and its executable in an unusable state. 315*8975f5c5SAndroid Build Coastguard Worker SharedProgramExecutable mExecutable; 316*8975f5c5SAndroid Build Coastguard Worker }; 317*8975f5c5SAndroid Build Coastguard Worker 318*8975f5c5SAndroid Build Coastguard Worker struct ProgramVaryingRef 319*8975f5c5SAndroid Build Coastguard Worker { getProgramVaryingRef320*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable *get(ShaderType stage) const 321*8975f5c5SAndroid Build Coastguard Worker { 322*8975f5c5SAndroid Build Coastguard Worker ASSERT(stage == frontShaderStage || stage == backShaderStage); 323*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader; 324*8975f5c5SAndroid Build Coastguard Worker ASSERT(ref); 325*8975f5c5SAndroid Build Coastguard Worker return ref; 326*8975f5c5SAndroid Build Coastguard Worker } 327*8975f5c5SAndroid Build Coastguard Worker 328*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable *frontShader = nullptr; 329*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable *backShader = nullptr; 330*8975f5c5SAndroid Build Coastguard Worker ShaderType frontShaderStage = ShaderType::InvalidEnum; 331*8975f5c5SAndroid Build Coastguard Worker ShaderType backShaderStage = ShaderType::InvalidEnum; 332*8975f5c5SAndroid Build Coastguard Worker }; 333*8975f5c5SAndroid Build Coastguard Worker 334*8975f5c5SAndroid Build Coastguard Worker using ProgramMergedVaryings = std::vector<ProgramVaryingRef>; 335*8975f5c5SAndroid Build Coastguard Worker 336*8975f5c5SAndroid Build Coastguard Worker class Program final : public LabeledObject, public angle::Subject 337*8975f5c5SAndroid Build Coastguard Worker { 338*8975f5c5SAndroid Build Coastguard Worker public: 339*8975f5c5SAndroid Build Coastguard Worker Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle); 340*8975f5c5SAndroid Build Coastguard Worker void onDestroy(const Context *context); 341*8975f5c5SAndroid Build Coastguard Worker 342*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID id() const; 343*8975f5c5SAndroid Build Coastguard Worker 344*8975f5c5SAndroid Build Coastguard Worker angle::Result setLabel(const Context *context, const std::string &label) override; 345*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel() const override; 346*8975f5c5SAndroid Build Coastguard Worker getImplementation()347*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE rx::ProgramImpl *getImplementation() const 348*8975f5c5SAndroid Build Coastguard Worker { 349*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mLinkingState); 350*8975f5c5SAndroid Build Coastguard Worker return mProgram; 351*8975f5c5SAndroid Build Coastguard Worker } 352*8975f5c5SAndroid Build Coastguard Worker 353*8975f5c5SAndroid Build Coastguard Worker void attachShader(const Context *context, Shader *shader); 354*8975f5c5SAndroid Build Coastguard Worker void detachShader(const Context *context, Shader *shader); 355*8975f5c5SAndroid Build Coastguard Worker int getAttachedShadersCount() const; 356*8975f5c5SAndroid Build Coastguard Worker 357*8975f5c5SAndroid Build Coastguard Worker Shader *getAttachedShader(ShaderType shaderType) const; 358*8975f5c5SAndroid Build Coastguard Worker 359*8975f5c5SAndroid Build Coastguard Worker void bindAttributeLocation(const Context *context, GLuint index, const char *name); 360*8975f5c5SAndroid Build Coastguard Worker void bindUniformLocation(const Context *context, UniformLocation location, const char *name); 361*8975f5c5SAndroid Build Coastguard Worker 362*8975f5c5SAndroid Build Coastguard Worker // EXT_blend_func_extended 363*8975f5c5SAndroid Build Coastguard Worker void bindFragmentOutputLocation(const Context *context, GLuint index, const char *name); 364*8975f5c5SAndroid Build Coastguard Worker void bindFragmentOutputIndex(const Context *context, GLuint index, const char *name); 365*8975f5c5SAndroid Build Coastguard Worker 366*8975f5c5SAndroid Build Coastguard Worker // KHR_parallel_shader_compile 367*8975f5c5SAndroid Build Coastguard Worker // Try to link the program asynchronously. As a result, background threads may be launched to 368*8975f5c5SAndroid Build Coastguard Worker // execute the linking tasks concurrently. 369*8975f5c5SAndroid Build Coastguard Worker angle::Result link(const Context *context, angle::JobResultExpectancy resultExpectancy); 370*8975f5c5SAndroid Build Coastguard Worker 371*8975f5c5SAndroid Build Coastguard Worker // Peek whether there is any running linking tasks. 372*8975f5c5SAndroid Build Coastguard Worker bool isLinking() const; hasLinkingState()373*8975f5c5SAndroid Build Coastguard Worker bool hasLinkingState() const { return mLinkingState != nullptr; } 374*8975f5c5SAndroid Build Coastguard Worker isLinked()375*8975f5c5SAndroid Build Coastguard Worker bool isLinked() const 376*8975f5c5SAndroid Build Coastguard Worker { 377*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mLinkingState); 378*8975f5c5SAndroid Build Coastguard Worker return mLinked; 379*8975f5c5SAndroid Build Coastguard Worker } 380*8975f5c5SAndroid Build Coastguard Worker bool isBinaryReady(const Context *context); cacheProgramBinaryIfNecessary(const Context * context)381*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void cacheProgramBinaryIfNecessary(const Context *context) 382*8975f5c5SAndroid Build Coastguard Worker { 383*8975f5c5SAndroid Build Coastguard Worker // This function helps ensure the program binary is cached, even if the backend waits for 384*8975f5c5SAndroid Build Coastguard Worker // post-link tasks without the knowledge of the front-end. 385*8975f5c5SAndroid Build Coastguard Worker if (!mIsBinaryCached && !mState.mBinaryRetrieveableHint && 386*8975f5c5SAndroid Build Coastguard Worker mState.mExecutable->mPostLinkSubTasks.empty()) 387*8975f5c5SAndroid Build Coastguard Worker { 388*8975f5c5SAndroid Build Coastguard Worker cacheProgramBinaryIfNotAlready(context); 389*8975f5c5SAndroid Build Coastguard Worker } 390*8975f5c5SAndroid Build Coastguard Worker } 391*8975f5c5SAndroid Build Coastguard Worker 392*8975f5c5SAndroid Build Coastguard Worker angle::Result setBinary(const Context *context, 393*8975f5c5SAndroid Build Coastguard Worker GLenum binaryFormat, 394*8975f5c5SAndroid Build Coastguard Worker const void *binary, 395*8975f5c5SAndroid Build Coastguard Worker GLsizei length); 396*8975f5c5SAndroid Build Coastguard Worker angle::Result getBinary(Context *context, 397*8975f5c5SAndroid Build Coastguard Worker GLenum *binaryFormat, 398*8975f5c5SAndroid Build Coastguard Worker void *binary, 399*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize, 400*8975f5c5SAndroid Build Coastguard Worker GLsizei *length); 401*8975f5c5SAndroid Build Coastguard Worker GLint getBinaryLength(Context *context); 402*8975f5c5SAndroid Build Coastguard Worker void setBinaryRetrievableHint(bool retrievable); 403*8975f5c5SAndroid Build Coastguard Worker bool getBinaryRetrievableHint() const; 404*8975f5c5SAndroid Build Coastguard Worker 405*8975f5c5SAndroid Build Coastguard Worker angle::Result loadBinary(const Context *context, 406*8975f5c5SAndroid Build Coastguard Worker const void *binary, 407*8975f5c5SAndroid Build Coastguard Worker GLsizei length, 408*8975f5c5SAndroid Build Coastguard Worker egl::CacheGetResult *resultOut); 409*8975f5c5SAndroid Build Coastguard Worker getInfoLog()410*8975f5c5SAndroid Build Coastguard Worker InfoLog &getInfoLog() { return mState.mInfoLog; } 411*8975f5c5SAndroid Build Coastguard Worker int getInfoLogLength() const; 412*8975f5c5SAndroid Build Coastguard Worker void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; 413*8975f5c5SAndroid Build Coastguard Worker 414*8975f5c5SAndroid Build Coastguard Worker void setSeparable(const Context *context, bool separable); isSeparable()415*8975f5c5SAndroid Build Coastguard Worker bool isSeparable() const { return mState.mSeparable; } 416*8975f5c5SAndroid Build Coastguard Worker 417*8975f5c5SAndroid Build Coastguard Worker void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const; 418*8975f5c5SAndroid Build Coastguard Worker 419*8975f5c5SAndroid Build Coastguard Worker void bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding); 420*8975f5c5SAndroid Build Coastguard Worker 421*8975f5c5SAndroid Build Coastguard Worker void setTransformFeedbackVaryings(const Context *context, 422*8975f5c5SAndroid Build Coastguard Worker GLsizei count, 423*8975f5c5SAndroid Build Coastguard Worker const GLchar *const *varyings, 424*8975f5c5SAndroid Build Coastguard Worker GLenum bufferMode); getTransformFeedbackBufferMode()425*8975f5c5SAndroid Build Coastguard Worker GLenum getTransformFeedbackBufferMode() const { return mState.mTransformFeedbackBufferMode; } 426*8975f5c5SAndroid Build Coastguard Worker addRef()427*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void addRef() { mRefCount++; } 428*8975f5c5SAndroid Build Coastguard Worker release(const Context * context)429*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void release(const Context *context) 430*8975f5c5SAndroid Build Coastguard Worker { 431*8975f5c5SAndroid Build Coastguard Worker mRefCount--; 432*8975f5c5SAndroid Build Coastguard Worker 433*8975f5c5SAndroid Build Coastguard Worker if (mRefCount == 0 && mDeleteStatus) 434*8975f5c5SAndroid Build Coastguard Worker { 435*8975f5c5SAndroid Build Coastguard Worker deleteSelf(context); 436*8975f5c5SAndroid Build Coastguard Worker } 437*8975f5c5SAndroid Build Coastguard Worker } 438*8975f5c5SAndroid Build Coastguard Worker 439*8975f5c5SAndroid Build Coastguard Worker unsigned int getRefCount() const; isInUse()440*8975f5c5SAndroid Build Coastguard Worker bool isInUse() const { return getRefCount() != 0; } 441*8975f5c5SAndroid Build Coastguard Worker void flagForDeletion(); 442*8975f5c5SAndroid Build Coastguard Worker bool isFlaggedForDeletion() const; 443*8975f5c5SAndroid Build Coastguard Worker 444*8975f5c5SAndroid Build Coastguard Worker void validate(const Caps &caps); 445*8975f5c5SAndroid Build Coastguard Worker bool isValidated() const; 446*8975f5c5SAndroid Build Coastguard Worker getState()447*8975f5c5SAndroid Build Coastguard Worker const ProgramState &getState() const { return mState; } 448*8975f5c5SAndroid Build Coastguard Worker getAttributeBindings()449*8975f5c5SAndroid Build Coastguard Worker const ProgramBindings &getAttributeBindings() const { return mState.getAttributeBindings(); } getUniformLocationBindings()450*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getUniformLocationBindings() const 451*8975f5c5SAndroid Build Coastguard Worker { 452*8975f5c5SAndroid Build Coastguard Worker return mState.getUniformLocationBindings(); 453*8975f5c5SAndroid Build Coastguard Worker } getFragmentOutputLocations()454*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getFragmentOutputLocations() const 455*8975f5c5SAndroid Build Coastguard Worker { 456*8975f5c5SAndroid Build Coastguard Worker return mState.getFragmentOutputLocations(); 457*8975f5c5SAndroid Build Coastguard Worker } getFragmentOutputIndexes()458*8975f5c5SAndroid Build Coastguard Worker const ProgramAliasedBindings &getFragmentOutputIndexes() const 459*8975f5c5SAndroid Build Coastguard Worker { 460*8975f5c5SAndroid Build Coastguard Worker return mState.getFragmentOutputIndexes(); 461*8975f5c5SAndroid Build Coastguard Worker } 462*8975f5c5SAndroid Build Coastguard Worker 463*8975f5c5SAndroid Build Coastguard Worker // Try to resolve linking. Inlined to make sure its overhead is as low as possible. resolveLink(const Context * context)464*8975f5c5SAndroid Build Coastguard Worker void resolveLink(const Context *context) 465*8975f5c5SAndroid Build Coastguard Worker { 466*8975f5c5SAndroid Build Coastguard Worker if (mLinkingState) 467*8975f5c5SAndroid Build Coastguard Worker { 468*8975f5c5SAndroid Build Coastguard Worker resolveLinkImpl(context); 469*8975f5c5SAndroid Build Coastguard Worker } 470*8975f5c5SAndroid Build Coastguard Worker } 471*8975f5c5SAndroid Build Coastguard Worker 472*8975f5c5SAndroid Build Coastguard Worker // Writes a program's binary to |mBinary|. 473*8975f5c5SAndroid Build Coastguard Worker angle::Result serialize(const Context *context); getSerializedBinary()474*8975f5c5SAndroid Build Coastguard Worker const angle::MemoryBuffer &getSerializedBinary() const { return mBinary; } 475*8975f5c5SAndroid Build Coastguard Worker serial()476*8975f5c5SAndroid Build Coastguard Worker rx::UniqueSerial serial() const { return mSerial; } 477*8975f5c5SAndroid Build Coastguard Worker getExecutable()478*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &getExecutable() const { return mState.getExecutable(); } getExecutable()479*8975f5c5SAndroid Build Coastguard Worker ProgramExecutable &getExecutable() { return mState.getExecutable(); } getSharedExecutable()480*8975f5c5SAndroid Build Coastguard Worker const SharedProgramExecutable &getSharedExecutable() const 481*8975f5c5SAndroid Build Coastguard Worker { 482*8975f5c5SAndroid Build Coastguard Worker return mState.getSharedExecutable(); 483*8975f5c5SAndroid Build Coastguard Worker } 484*8975f5c5SAndroid Build Coastguard Worker 485*8975f5c5SAndroid Build Coastguard Worker private: 486*8975f5c5SAndroid Build Coastguard Worker class MainLinkLoadTask; 487*8975f5c5SAndroid Build Coastguard Worker class MainLoadTask; 488*8975f5c5SAndroid Build Coastguard Worker class MainLinkTask; 489*8975f5c5SAndroid Build Coastguard Worker class MainLinkLoadEvent; 490*8975f5c5SAndroid Build Coastguard Worker 491*8975f5c5SAndroid Build Coastguard Worker friend class ProgramPipeline; 492*8975f5c5SAndroid Build Coastguard Worker friend class MainLinkLoadTask; 493*8975f5c5SAndroid Build Coastguard Worker friend class MainLoadTask; 494*8975f5c5SAndroid Build Coastguard Worker friend class MainLinkTask; 495*8975f5c5SAndroid Build Coastguard Worker 496*8975f5c5SAndroid Build Coastguard Worker struct LinkingState; 497*8975f5c5SAndroid Build Coastguard Worker ~Program() override; 498*8975f5c5SAndroid Build Coastguard Worker 499*8975f5c5SAndroid Build Coastguard Worker // Loads program state according to the specified binary blob. Returns true on success. 500*8975f5c5SAndroid Build Coastguard Worker bool deserialize(const Context *context, BinaryInputStream &stream); 501*8975f5c5SAndroid Build Coastguard Worker 502*8975f5c5SAndroid Build Coastguard Worker void unlink(); 503*8975f5c5SAndroid Build Coastguard Worker void setupExecutableForLink(const Context *context); 504*8975f5c5SAndroid Build Coastguard Worker void deleteSelf(const Context *context); 505*8975f5c5SAndroid Build Coastguard Worker 506*8975f5c5SAndroid Build Coastguard Worker angle::Result linkJobImpl(const Caps &caps, 507*8975f5c5SAndroid Build Coastguard Worker const Limitations &limitations, 508*8975f5c5SAndroid Build Coastguard Worker const Version &clientVersion, 509*8975f5c5SAndroid Build Coastguard Worker bool isWebGL, 510*8975f5c5SAndroid Build Coastguard Worker LinkingVariables *linkingVariables, 511*8975f5c5SAndroid Build Coastguard Worker ProgramLinkedResources *resources, 512*8975f5c5SAndroid Build Coastguard Worker ProgramMergedVaryings *mergedVaryingsOut); 513*8975f5c5SAndroid Build Coastguard Worker 514*8975f5c5SAndroid Build Coastguard Worker void makeNewExecutable(const Context *context); 515*8975f5c5SAndroid Build Coastguard Worker 516*8975f5c5SAndroid Build Coastguard Worker bool linkValidateShaders(); 517*8975f5c5SAndroid Build Coastguard Worker void linkShaders(); 518*8975f5c5SAndroid Build Coastguard Worker bool linkAttributes(const Caps &caps, const Limitations &limitations, bool webglCompatibility); 519*8975f5c5SAndroid Build Coastguard Worker bool linkVaryings(); 520*8975f5c5SAndroid Build Coastguard Worker 521*8975f5c5SAndroid Build Coastguard Worker bool linkUniforms(const Caps &caps, 522*8975f5c5SAndroid Build Coastguard Worker const Version &clientVersion, 523*8975f5c5SAndroid Build Coastguard Worker std::vector<UnusedUniform> *unusedUniformsOutOrNull, 524*8975f5c5SAndroid Build Coastguard Worker GLuint *combinedImageUniformsOut); 525*8975f5c5SAndroid Build Coastguard Worker 526*8975f5c5SAndroid Build Coastguard Worker void updateLinkedShaderStages(); 527*8975f5c5SAndroid Build Coastguard Worker 528*8975f5c5SAndroid Build Coastguard Worker // Block until linking is finished and resolve it. 529*8975f5c5SAndroid Build Coastguard Worker void resolveLinkImpl(const Context *context); 530*8975f5c5SAndroid Build Coastguard Worker // Block until post-link tasks are finished. 531*8975f5c5SAndroid Build Coastguard Worker void waitForPostLinkTasks(const Context *context); 532*8975f5c5SAndroid Build Coastguard Worker 533*8975f5c5SAndroid Build Coastguard Worker void postResolveLink(const Context *context); 534*8975f5c5SAndroid Build Coastguard Worker void cacheProgramBinaryIfNotAlready(const Context *context); 535*8975f5c5SAndroid Build Coastguard Worker 536*8975f5c5SAndroid Build Coastguard Worker void dumpProgramInfo(const Context *context) const; 537*8975f5c5SAndroid Build Coastguard Worker 538*8975f5c5SAndroid Build Coastguard Worker rx::UniqueSerial mSerial; 539*8975f5c5SAndroid Build Coastguard Worker ProgramState mState; 540*8975f5c5SAndroid Build Coastguard Worker rx::ProgramImpl *mProgram; 541*8975f5c5SAndroid Build Coastguard Worker 542*8975f5c5SAndroid Build Coastguard Worker bool mValidated; 543*8975f5c5SAndroid Build Coastguard Worker // Flag to indicate that the program can be deleted when no longer in use 544*8975f5c5SAndroid Build Coastguard Worker bool mDeleteStatus; 545*8975f5c5SAndroid Build Coastguard Worker // Whether the program binary is implicitly cached yet. This is usually done in 546*8975f5c5SAndroid Build Coastguard Worker // |resolveLinkImpl|, but may be deferred in the presence of post-link tasks. In that case, 547*8975f5c5SAndroid Build Coastguard Worker // |waitForPostLinkTasks| would cache the binary. However, if the wait on the tasks is done by 548*8975f5c5SAndroid Build Coastguard Worker // the backend itself, this caching will not be done. This flag is used to make sure the binary 549*8975f5c5SAndroid Build Coastguard Worker // is eventually cached at some point in the future. 550*8975f5c5SAndroid Build Coastguard Worker bool mIsBinaryCached; 551*8975f5c5SAndroid Build Coastguard Worker 552*8975f5c5SAndroid Build Coastguard Worker bool mLinked; 553*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<LinkingState> mLinkingState; 554*8975f5c5SAndroid Build Coastguard Worker 555*8975f5c5SAndroid Build Coastguard Worker egl::BlobCache::Key mProgramHash; 556*8975f5c5SAndroid Build Coastguard Worker 557*8975f5c5SAndroid Build Coastguard Worker unsigned int mRefCount; 558*8975f5c5SAndroid Build Coastguard Worker 559*8975f5c5SAndroid Build Coastguard Worker ShaderProgramManager *mResourceManager; 560*8975f5c5SAndroid Build Coastguard Worker const ShaderProgramID mHandle; 561*8975f5c5SAndroid Build Coastguard Worker 562*8975f5c5SAndroid Build Coastguard Worker // ProgramState::mAttachedShaders holds a reference to shaders' compiled state, which is all the 563*8975f5c5SAndroid Build Coastguard Worker // program and the backends require after link. The actual shaders linked to the program are 564*8975f5c5SAndroid Build Coastguard Worker // stored here to support shader attach/detach and link without providing access to them in the 565*8975f5c5SAndroid Build Coastguard Worker // backends. 566*8975f5c5SAndroid Build Coastguard Worker ShaderMap<Shader *> mAttachedShaders; 567*8975f5c5SAndroid Build Coastguard Worker 568*8975f5c5SAndroid Build Coastguard Worker // A cache of the program binary, prepared by |serialize()|. OpenGL requires the application to 569*8975f5c5SAndroid Build Coastguard Worker // query the length of the binary first (requiring a call to |serialize()|), and then get the 570*8975f5c5SAndroid Build Coastguard Worker // actual binary. This cache ensures the second call does not need to call |serialize()| again. 571*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer mBinary; 572*8975f5c5SAndroid Build Coastguard Worker 573*8975f5c5SAndroid Build Coastguard Worker angle::SimpleMutex mHistogramMutex; 574*8975f5c5SAndroid Build Coastguard Worker }; 575*8975f5c5SAndroid Build Coastguard Worker } // namespace gl 576*8975f5c5SAndroid Build Coastguard Worker 577*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_PROGRAM_H_ 578