xref: /aosp_15_r20/external/angle/src/libANGLE/Program.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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