1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_THREADCONTEXT 9 #define SKSL_THREADCONTEXT 10 11 #include "include/core/SkTypes.h" 12 #include "include/sksl/SkSLErrorReporter.h" 13 #include "include/sksl/SkSLPosition.h" 14 #include "src/sksl/SkSLContext.h" 15 #include "src/sksl/SkSLProgramSettings.h" 16 #include "src/sksl/ir/SkSLProgram.h" 17 18 #include <cstdint> 19 #include <memory> 20 #include <string_view> 21 #include <vector> 22 23 namespace SkSL { 24 25 class Compiler; 26 class ModifiersPool; 27 class Pool; 28 class ProgramElement; 29 class SymbolTable; 30 class Variable; 31 enum class ProgramKind : int8_t; 32 struct Modifiers; 33 struct Module; 34 35 namespace dsl { 36 37 class DSLCore; 38 39 } // namespace dsl 40 41 /** 42 * Thread-safe class that tracks per-thread state associated with SkSL output. 43 */ 44 class ThreadContext { 45 public: 46 ThreadContext(SkSL::Compiler* compiler, 47 SkSL::ProgramKind kind, 48 const SkSL::ProgramSettings& settings, 49 const SkSL::Module* module, 50 bool isModule); 51 ~ThreadContext(); 52 53 /** 54 * Returns true if the DSL has been started. 55 */ 56 static bool IsActive(); 57 58 /** 59 * Returns the Compiler used by DSL operations in the current thread. 60 */ Compiler()61 static SkSL::Compiler& Compiler() { return *Instance().fCompiler; } 62 63 /** 64 * Returns the Context used by DSL operations in the current thread. 65 */ 66 static SkSL::Context& Context(); 67 68 /** 69 * Returns the Settings used by DSL operations in the current thread. 70 */ 71 static const SkSL::ProgramSettings& Settings(); 72 73 /** 74 * Returns the Program::Inputs used by the current thread. 75 */ Inputs()76 static SkSL::Program::Inputs& Inputs() { return Instance().fInputs; } 77 78 /** 79 * Returns the collection to which DSL program elements in this thread should be appended. 80 */ ProgramElements()81 static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() { 82 return Instance().fProgramElements; 83 } 84 SharedElements()85 static std::vector<const ProgramElement*>& SharedElements() { 86 return Instance().fSharedElements; 87 } 88 89 /** 90 * Returns the current SymbolTable. 91 */ 92 static std::shared_ptr<SkSL::SymbolTable>& SymbolTable(); 93 94 /** 95 * Returns the current memory pool. 96 */ MemoryPool()97 static std::unique_ptr<Pool>& MemoryPool() { return Instance().fPool; } 98 99 /** 100 * Returns the current modifiers pool. 101 */ GetModifiersPool()102 static std::unique_ptr<ModifiersPool>& GetModifiersPool() { return Instance().fModifiersPool; } 103 104 /** 105 * Returns the current ProgramConfig. 106 */ GetProgramConfig()107 static const std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; } 108 IsModule()109 static bool IsModule() { return GetProgramConfig()->fIsBuiltinCode; } 110 111 /** 112 * Returns the final pointer to a pooled Modifiers object that should be used to represent the 113 * given modifiers. 114 */ 115 static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers); 116 117 struct RTAdjustData { 118 // Points to a standalone sk_RTAdjust variable, if one exists. 119 const Variable* fVar = nullptr; 120 // Points to the interface block containing an sk_RTAdjust field, if one exists. 121 const Variable* fInterfaceBlock = nullptr; 122 // If fInterfaceBlock is non-null, contains the index of the sk_RTAdjust field within it. 123 int fFieldIndex = -1; 124 }; 125 126 /** 127 * Returns a struct containing information about the RTAdjust variable. 128 */ 129 static RTAdjustData& RTAdjustState(); 130 131 /** 132 * Returns the ErrorReporter associated with the current thread. This object will be notified 133 * when any DSL errors occur. 134 */ GetErrorReporter()135 static ErrorReporter& GetErrorReporter() { 136 return *Context().fErrors; 137 } 138 139 static void SetErrorReporter(ErrorReporter* errorReporter); 140 141 /** 142 * Notifies the current ErrorReporter that an error has occurred. The default error handler 143 * prints the message to stderr and aborts. 144 */ 145 static void ReportError(std::string_view msg, Position pos = Position{}); 146 147 static ThreadContext& Instance(); 148 149 static void SetInstance(std::unique_ptr<ThreadContext> instance); 150 151 private: 152 class DefaultErrorReporter : public ErrorReporter { 153 void handleError(std::string_view msg, Position pos) override; 154 }; 155 156 void setupSymbolTable(); 157 158 std::unique_ptr<SkSL::ProgramConfig> fConfig; 159 std::unique_ptr<SkSL::ModifiersPool> fModifiersPool; 160 SkSL::Compiler* fCompiler; 161 std::unique_ptr<Pool> fPool; 162 SkSL::ProgramConfig* fOldConfig; 163 SkSL::ModifiersPool* fOldModifiersPool; 164 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements; 165 std::vector<const SkSL::ProgramElement*> fSharedElements; 166 DefaultErrorReporter fDefaultErrorReporter; 167 ErrorReporter& fOldErrorReporter; 168 ProgramSettings fSettings; 169 RTAdjustData fRTAdjust; 170 Program::Inputs fInputs; 171 172 friend class dsl::DSLCore; 173 }; 174 175 } // namespace SkSL 176 177 #endif 178