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, 184 const void *binary, 185 GLsizei length, 186 angle::JobResultExpectancy resultExpectancy); 187 // Load a binary from a glShaderBinary call. 188 bool loadShaderBinary(const Context *context, 189 const void *binary, 190 GLsizei length, 191 angle::JobResultExpectancy resultExpectancy); 192 writeShaderKey(BinaryOutputStream * streamOut)193 void writeShaderKey(BinaryOutputStream *streamOut) const 194 { 195 ASSERT(streamOut && !mShaderHash.empty()); 196 streamOut->writeBytes(mShaderHash.data(), egl::BlobCache::kKeyLength); 197 return; 198 } 199 200 private: 201 ~Shader() override; 202 static std::string joinShaderSources(GLsizei count, 203 const char *const *string, 204 const GLint *length); 205 static void GetSourceImpl(const std::string &source, 206 GLsizei bufSize, 207 GLsizei *length, 208 char *buffer); 209 bool loadBinaryImpl(const Context *context, 210 const void *binary, 211 GLsizei length, 212 angle::JobResultExpectancy resultExpectancy, 213 bool generatedWithOfflineCompiler); 214 215 // Compute a key to uniquely identify the shader object in memory caches. 216 void setShaderKey(const Context *context, 217 const ShCompileOptions &compileOptions, 218 const ShShaderOutput &outputType, 219 const ShBuiltInResources &resources); 220 221 ShaderState mState; 222 std::unique_ptr<rx::ShaderImpl> mImplementation; 223 const gl::Limitations mRendererLimitations; 224 const ShaderProgramID mHandle; 225 unsigned int mRefCount; // Number of program objects this shader is attached to 226 bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use 227 std::string mInfoLog; 228 229 // We keep a reference to the translator in order to defer compiles while preserving settings. 230 BindingPointer<Compiler> mBoundCompiler; 231 SharedCompileJob mCompileJob; 232 egl::BlobCache::Key mShaderHash; 233 234 ShaderProgramManager *mResourceManager; 235 }; 236 237 const char *GetShaderTypeString(ShaderType type); 238 std::string GetShaderDumpFileDirectory(); 239 std::string GetShaderDumpFileName(size_t shaderHash); 240 241 // Block until the compilation job is finished. This can be used by the program link job to wait 242 // for shader compilation. As such, it may be called by multiple threads without holding a lock and 243 // must therefore be thread-safe. It returns true if shader compilation has succeeded. 244 bool WaitCompileJobUnlocked(const SharedCompileJob &compileJob); 245 } // namespace gl 246 247 #endif // LIBANGLE_SHADER_H_ 248