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