• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Shader.h: Defines the abstract gl::Shader class and its concrete derived
8 // classes VertexShader and FragmentShader. Implements GL shader objects and
9 // related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section
10 // 3.8 page 84.
11 
12 #ifndef LIBANGLE_SHADER_H_
13 #define LIBANGLE_SHADER_H_
14 
15 #include <list>
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 #include <GLSLANG/ShaderLang.h>
21 #include "angle_gl.h"
22 
23 #include "common/BinaryStream.h"
24 #include "common/CompiledShaderState.h"
25 #include "common/MemoryBuffer.h"
26 #include "common/Optional.h"
27 #include "common/angleutils.h"
28 #include "libANGLE/BlobCache.h"
29 #include "libANGLE/Caps.h"
30 #include "libANGLE/Compiler.h"
31 #include "libANGLE/Debug.h"
32 #include "libANGLE/angletypes.h"
33 
34 namespace rx
35 {
36 class GLImplFactory;
37 class ShaderImpl;
38 class ShaderSh;
39 class WaitableCompileEvent;
40 }  // namespace rx
41 
42 namespace angle
43 {
44 class WaitableEvent;
45 class WorkerThreadPool;
46 }  // namespace angle
47 
48 namespace gl
49 {
50 class Context;
51 class ShaderProgramManager;
52 class State;
53 class BinaryInputStream;
54 class BinaryOutputStream;
55 
56 // We defer the compile until link time, or until properties are queried.
57 enum class CompileStatus
58 {
59     // Compilation never done, or has failed.
60     NOT_COMPILED,
61     // Compile is in progress.
62     COMPILE_REQUESTED,
63     // Compilation job is done, but is being resolved.  This enum value is there to allow access to
64     // compiled state during resolve without triggering threading-related assertions (which ensure
65     // no compile job is in progress).
66     IS_RESOLVING,
67     // Compilation was successful.
68     COMPILED,
69 };
70 
71 // A representation of the compile job.  The program's link job can wait on this while the shader is
72 // free to recompile (and generate other compile jobs).
73 struct CompileJob;
74 using SharedCompileJob = std::shared_ptr<CompileJob>;
75 
76 class ShaderState final : angle::NonCopyable
77 {
78   public:
79     ShaderState(ShaderType shaderType);
80     ~ShaderState();
81 
getLabel()82     const std::string &getLabel() const { return mLabel; }
83 
getSource()84     const std::string &getSource() const { return mSource; }
compilePending()85     bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
getCompileStatus()86     CompileStatus getCompileStatus() const { return mCompileStatus; }
87 
getShaderType()88     ShaderType getShaderType() const { return mCompiledState->shaderType; }
89 
getCompiledState()90     const SharedCompiledShaderState &getCompiledState() const
91     {
92         ASSERT(!compilePending());
93         return mCompiledState;
94     }
95 
96   private:
97     friend class Shader;
98 
99     std::string mLabel;
100     std::string mSource;
101     size_t mSourceHash = 0;
102 
103     SharedCompiledShaderState mCompiledState;
104 
105     // Indicates if this shader has been successfully compiled
106     CompileStatus mCompileStatus = CompileStatus::NOT_COMPILED;
107 };
108 
109 class Shader final : angle::NonCopyable, public LabeledObject
110 {
111   public:
112     Shader(ShaderProgramManager *manager,
113            rx::GLImplFactory *implFactory,
114            const gl::Limitations &rendererLimitations,
115            ShaderType type,
116            ShaderProgramID handle);
117 
118     void onDestroy(const Context *context);
119 
120     angle::Result setLabel(const Context *context, const std::string &label) override;
121     const std::string &getLabel() const override;
122 
getType()123     ShaderType getType() const { return mState.getShaderType(); }
124     ShaderProgramID getHandle() const;
125 
getImplementation()126     rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
127 
128     void setSource(const Context *context,
129                    GLsizei count,
130                    const char *const *string,
131                    const GLint *length);
132     int getInfoLogLength(const Context *context);
133     void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
getInfoLogString()134     std::string getInfoLogString() const { return mInfoLog; }
135     int getSourceLength() const;
getSourceString()136     const std::string &getSourceString() const { return mState.getSource(); }
137     void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
138     int getTranslatedSourceLength(const Context *context);
139     int getTranslatedSourceWithDebugInfoLength(const Context *context);
140     const std::string &getTranslatedSource(const Context *context);
141     void getTranslatedSource(const Context *context,
142                              GLsizei bufSize,
143                              GLsizei *length,
144                              char *buffer);
145     void getTranslatedSourceWithDebugInfo(const Context *context,
146                                           GLsizei bufSize,
147                                           GLsizei *length,
148                                           char *buffer);
149 
150     size_t getSourceHash() const;
151 
152     void compile(const Context *context, angle::JobResultExpectancy resultExpectancy);
153     bool isCompiled(const Context *context);
154     bool isCompleted();
155 
156     // Return the compilation job, which will be used by the program link job to wait for the
157     // completion of compilation.  If compilation has already finished, a placeholder job is
158     // returned which can be used to retrieve the status of compilation.
159     SharedCompileJob getCompileJob(SharedCompiledShaderState *compiledStateOut);
160 
161     // Return the compiled shader state for the program.  The program holds a reference to this
162     // state, so the shader is free to recompile, get deleted, etc.
getCompiledState()163     const SharedCompiledShaderState &getCompiledState() const { return mState.getCompiledState(); }
164 
165     void addRef();
166     void release(const Context *context);
167     unsigned int getRefCount() const;
168     bool isFlaggedForDeletion() const;
169     void flagForDeletion();
170 
getState()171     const ShaderState &getState() const { return mState; }
172 
hasBeenDeleted()173     bool hasBeenDeleted() const { return mDeleteStatus; }
174 
175     // Block until compilation is finished and resolve it.
176     void resolveCompile(const Context *context);
177 
178     // Writes a shader's binary to the output memory buffer.
179     angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
180     bool deserialize(BinaryInputStream &stream);
181 
182     // Load a binary from shader cache.
183     bool loadBinary(const Context *context, const void *binary, GLsizei length);
184     // Load a binary from a glShaderBinary call.
185     bool loadShaderBinary(const Context *context, const void *binary, GLsizei length);
186 
writeShaderKey(BinaryOutputStream * streamOut)187     void writeShaderKey(BinaryOutputStream *streamOut) const
188     {
189         ASSERT(streamOut && !mShaderHash.empty());
190         streamOut->writeBytes(mShaderHash.data(), egl::BlobCache::kKeyLength);
191         return;
192     }
193 
194   private:
195     ~Shader() override;
196     static std::string joinShaderSources(GLsizei count,
197                                          const char *const *string,
198                                          const GLint *length);
199     static void GetSourceImpl(const std::string &source,
200                               GLsizei bufSize,
201                               GLsizei *length,
202                               char *buffer);
203     bool loadBinaryImpl(const Context *context,
204                         const void *binary,
205                         GLsizei length,
206                         bool generatedWithOfflineCompiler);
207 
208     // Compute a key to uniquely identify the shader object in memory caches.
209     void setShaderKey(const Context *context,
210                       const ShCompileOptions &compileOptions,
211                       const ShShaderOutput &outputType,
212                       const ShBuiltInResources &resources);
213 
214     ShaderState mState;
215     std::unique_ptr<rx::ShaderImpl> mImplementation;
216     const gl::Limitations mRendererLimitations;
217     const ShaderProgramID mHandle;
218     unsigned int mRefCount;  // Number of program objects this shader is attached to
219     bool mDeleteStatus;  // Flag to indicate that the shader can be deleted when no longer in use
220     std::string mInfoLog;
221 
222     // We keep a reference to the translator in order to defer compiles while preserving settings.
223     BindingPointer<Compiler> mBoundCompiler;
224     SharedCompileJob mCompileJob;
225     egl::BlobCache::Key mShaderHash;
226 
227     ShaderProgramManager *mResourceManager;
228 };
229 
230 const char *GetShaderTypeString(ShaderType type);
231 std::string GetShaderDumpFileDirectory();
232 std::string GetShaderDumpFileName(size_t shaderHash);
233 
234 // Block until the compilation job is finished.  This can be used by the program link job to wait
235 // for shader compilation.  As such, it may be called by multiple threads without holding a lock and
236 // must therefore be thread-safe.  It returns true if shader compilation has succeeded.
237 bool WaitCompileJobUnlocked(const SharedCompileJob &compileJob);
238 }  // namespace gl
239 
240 #endif  // LIBANGLE_SHADER_H_
241