blob: 56b1db38c88c01c43be971103eebc11e31504af9 [file] [log] [blame]
Ethan Nicholas95046142021-01-07 10:57:27 -05001/*
2 * Copyright 2020 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_DSLWRITER
9#define SKSL_DSLWRITER
10
John Stilesd6c08c92021-08-11 11:37:51 -040011#include "include/core/SkSpan.h"
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -040012#include "include/core/SkStringView.h"
Ethan Nicholasdaed2592021-03-04 14:30:25 -050013#include "include/private/SkSLModifiers.h"
Ethan Nicholas24c17722021-03-09 13:10:59 -050014#include "include/private/SkSLStatement.h"
Ethan Nicholasdaed2592021-03-04 14:30:25 -050015#include "include/sksl/DSLExpression.h"
16#include "include/sksl/DSLStatement.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050017#include "src/sksl/SkSLMangler.h"
John Stiles45990502021-02-16 10:55:27 -050018#include "src/sksl/SkSLOperators.h"
Ethan Nicholas55a63af2021-05-18 10:12:58 -040019#include "src/sksl/SkSLParsedModule.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050020#include "src/sksl/ir/SkSLExpressionStatement.h"
21#include "src/sksl/ir/SkSLProgram.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050022#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Brian Salomon48959462021-08-11 13:01:06 -040023#include "src/gpu/GrFragmentProcessor.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050024#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
John Stiles3befaf22021-04-23 14:42:22 -040025#include <list>
Ethan Nicholas95046142021-01-07 10:57:27 -050026#include <stack>
27
28class AutoDSLContext;
29
30namespace SkSL {
31
32class Compiler;
33class Context;
34class IRGenerator;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050035class ProgramElement;
Ethan Nicholas95046142021-01-07 10:57:27 -050036class SymbolTable;
37class Type;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050038class Variable;
Ethan Nicholas95046142021-01-07 10:57:27 -050039
40namespace dsl {
41
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040042class DSLGlobalVar;
43class DSLParameter;
44class DSLVar;
Ethan Nicholas95046142021-01-07 10:57:27 -050045class ErrorHandler;
46
47/**
48 * Thread-safe class that tracks per-thread state associated with DSL output. This class is for
49 * internal use only.
50 */
51class DSLWriter {
52public:
Ethan Nicholas55a63af2021-05-18 10:12:58 -040053 DSLWriter(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
54 const SkSL::ProgramSettings& settings, SkSL::ParsedModule module, bool isModule);
Ethan Nicholas95046142021-01-07 10:57:27 -050055
Ethan Nicholas0584ac02021-02-17 10:48:14 -050056 ~DSLWriter();
57
Ethan Nicholas95046142021-01-07 10:57:27 -050058 /**
59 * Returns the Compiler used by DSL operations in the current thread.
60 */
61 static SkSL::Compiler& Compiler() {
62 return *Instance().fCompiler;
63 }
64
65 /**
66 * Returns the IRGenerator used by DSL operations in the current thread.
67 */
68 static SkSL::IRGenerator& IRGenerator();
69
70 /**
71 * Returns the Context used by DSL operations in the current thread.
72 */
73 static const SkSL::Context& Context();
74
75 /**
Ethan Nicholas459777a2021-07-16 11:16:27 -040076 * Returns the Settings used by DSL operations in the current thread.
77 */
78 static SkSL::ProgramSettings& Settings();
79
80 /**
Ethan Nicholas1ff76092021-01-28 10:02:43 -050081 * Returns the collection to which DSL program elements in this thread should be appended.
82 */
83 static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
84 return Instance().fProgramElements;
85 }
86
Ethan Nicholas55a63af2021-05-18 10:12:58 -040087 static std::vector<const ProgramElement*>& SharedElements() {
88 return Instance().fSharedElements;
89 }
90
Ethan Nicholas1ff76092021-01-28 10:02:43 -050091 /**
Ethan Nicholas95046142021-01-07 10:57:27 -050092 * Returns the SymbolTable of the current thread's IRGenerator.
93 */
94 static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
95
Ethan Nicholas55a63af2021-05-18 10:12:58 -040096 /**
97 * Returns the current memory pool.
98 */
99 static std::unique_ptr<Pool>& MemoryPool() { return Instance().fPool; }
100
101 /**
102 * Returns the current modifiers pool.
103 */
104 static std::unique_ptr<ModifiersPool>& GetModifiersPool() { return Instance().fModifiersPool; }
105
106 /**
107 * Returns the current ProgramConfig.
108 */
109 static std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; }
110
Ethan Nicholas292a09d2021-07-14 09:52:16 -0400111 static bool IsModule() { return Instance().fIsModule; }
112
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500113 static void Reset();
114
Ethan Nicholas95046142021-01-07 10:57:27 -0500115 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500116 * Returns the final pointer to a pooled Modifiers object that should be used to represent the
117 * given modifiers.
118 */
John Stilesf2872e62021-05-04 11:38:43 -0400119 static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers);
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500120
121 /**
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400122 * Returns the SkSL variable corresponding to a DSL var.
Ethan Nicholasd6b26e52021-01-27 07:53:46 -0500123 */
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400124 static const SkSL::Variable* Var(DSLVarBase& var);
Ethan Nicholas707d3152021-03-25 17:49:08 -0400125
126 /**
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400127 * Creates an SkSL variable corresponding to a DSLParameter.
Ethan Nicholas371f6e12021-05-04 14:30:02 -0400128 */
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400129 static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
130
Ethan Nicholas371f6e12021-05-04 14:30:02 -0400131
132 /**
Ethan Nicholas707d3152021-03-25 17:49:08 -0400133 * Returns the SkSL declaration corresponding to a DSLVar.
134 */
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400135 static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
Ethan Nicholasd6b26e52021-01-27 07:53:46 -0500136
137 /**
Ethan Nicholas961d9442021-03-16 16:37:29 -0400138 * For use in testing only: marks the variable as having been declared, so that it can be
139 * destroyed without generating errors.
140 */
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400141 static void MarkDeclared(DSLVarBase& var);
Ethan Nicholas961d9442021-03-16 16:37:29 -0400142
143 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500144 * Returns the (possibly mangled) final name that should be used for an entity with the given
145 * raw name.
146 */
Ethan Nicholasd0f4d0d2021-06-23 13:51:55 -0400147 static skstd::string_view Name(skstd::string_view name);
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500148
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500149#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
150 /**
151 * Returns the fragment processor for which DSL output is being generated for the current
152 * thread.
153 */
Brian Salomon3176e862021-08-09 11:23:04 -0400154 static GrFragmentProcessor::ProgramImpl* CurrentProcessor() {
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500155 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
156 return Instance().fStack.top().fProcessor;
157 }
158
159 /**
160 * Returns the EmitArgs for fragment processor output in the current thread.
161 */
Brian Salomon3176e862021-08-09 11:23:04 -0400162 static GrFragmentProcessor::ProgramImpl::EmitArgs* CurrentEmitArgs() {
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500163 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
164 return Instance().fStack.top().fEmitArgs;
165 }
166
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500167 static bool InFragmentProcessor() {
168 return !Instance().fStack.empty();
169 }
170
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500171 /**
172 * Pushes a new processor / emitArgs pair for the current thread.
173 */
Brian Salomon3176e862021-08-09 11:23:04 -0400174 static void StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
175 GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs);
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500176
177 /**
178 * Pops the processor / emitArgs pair associated with the current thread.
179 */
180 static void EndFragmentProcessor();
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500181
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400182 static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
Ethan Nicholasee49efc2021-04-09 15:33:53 -0400183#else
184 static bool InFragmentProcessor() {
185 return false;
186 }
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500187#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
188
Ethan Nicholasdaed2592021-03-04 14:30:25 -0500189 static std::unique_ptr<SkSL::Expression> Call(const FunctionDeclaration& function,
190 ExpressionArray arguments);
191
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500192 /**
Ethan Nicholas722cb672021-05-06 10:47:06 -0400193 * Invokes expr(arguments), where expr is a function or type reference.
194 */
195 static std::unique_ptr<SkSL::Expression> Call(std::unique_ptr<SkSL::Expression> expr,
196 ExpressionArray arguments);
197
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400198 static DSLPossibleExpression Coerce(std::unique_ptr<Expression> expr, const SkSL::Type& type);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500199
John Stilesd6c08c92021-08-11 11:37:51 -0400200 static DSLPossibleExpression Construct(const SkSL::Type& type, SkSpan<DSLExpression> rawArgs);
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500201
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500202 static std::unique_ptr<Expression> ConvertBinary(std::unique_ptr<Expression> left, Operator op,
203 std::unique_ptr<Expression> right);
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500204
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500205 static std::unique_ptr<SkSL::Expression> ConvertField(std::unique_ptr<Expression> base,
Ethan Nicholasd0f4d0d2021-06-23 13:51:55 -0400206 skstd::string_view name);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500207
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500208 static std::unique_ptr<Expression> ConvertIndex(std::unique_ptr<Expression> base,
209 std::unique_ptr<Expression> index);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500210
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500211 static std::unique_ptr<Expression> ConvertPostfix(std::unique_ptr<Expression> expr,
212 Operator op);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500213
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500214 static std::unique_ptr<Expression> ConvertPrefix(Operator op, std::unique_ptr<Expression> expr);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500215
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500216 static DSLPossibleStatement ConvertSwitch(std::unique_ptr<Expression> value,
217 ExpressionArray caseValues,
Ethan Nicholas8a6537d2021-04-30 12:44:00 -0400218 SkTArray<SkSL::StatementArray> caseStatements,
219 bool isStatic);
Ethan Nicholascfefec02021-02-09 15:22:57 -0500220
Ethan Nicholas95046142021-01-07 10:57:27 -0500221 /**
Ethan Nicholas65e368b2021-08-05 14:53:02 -0400222 * Returns the ErrorHandler associated with the current thread. This object will be notified
223 * when any DSL errors occur. With a null ErrorHandler (the default), any errors will be dumped
224 * to stderr and a fatal exception will be generated.
Ethan Nicholas95046142021-01-07 10:57:27 -0500225 */
Ethan Nicholas65e368b2021-08-05 14:53:02 -0400226 static ErrorHandler* GetErrorHandler() {
227 return Instance().fErrorHandler;
228 }
229
Ethan Nicholas95046142021-01-07 10:57:27 -0500230 static void SetErrorHandler(ErrorHandler* errorHandler) {
231 Instance().fErrorHandler = errorHandler;
232 }
233
234 /**
235 * Notifies the current ErrorHandler that a DSL error has occurred. With a null ErrorHandler
236 * (the default), any errors will be dumped to stderr and a fatal exception will be generated.
237 */
Ethan Nicholasa40ddcd2021-08-06 09:17:18 -0400238 static void ReportError(const char* msg, PositionInfo info = PositionInfo());
Ethan Nicholas95046142021-01-07 10:57:27 -0500239
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500240 /**
Ethan Nicholas55a63af2021-05-18 10:12:58 -0400241 * Returns whether name mangling is enabled. Mangling is important for the DSL because its
242 * variables normally all go into the same symbol table; for instance if you were to translate
243 * this legal (albeit silly) GLSL code:
244 * int x;
245 * {
246 * int x;
247 * }
248 *
249 * into DSL, you'd end up with:
250 * DSLVar x1(kInt_Type, "x");
251 * DSLVar x2(kInt_Type, "x");
252 * Declare(x1);
253 * Block(Declare(x2));
254 *
255 * with x1 and x2 ending up in the same symbol table. This is fine as long as their effective
256 * names are different, so mangling prevents this situation from causing problems.
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500257 */
258 static bool ManglingEnabled() {
Ethan Nicholas55a63af2021-05-18 10:12:58 -0400259 return Instance().fSettings.fDSLMangling;
260 }
261
262 /**
263 * Returns whether DSLVars should automatically be marked declared upon creation. This is used
264 * to simplify testing.
265 */
266 static bool MarkVarsDeclared() {
267 return Instance().fSettings.fDSLMarkVarsDeclared;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500268 }
269
Ethan Nicholasb4f8b7a2021-06-23 10:27:09 -0400270 /**
271 * Forwards any pending Compiler errors to the DSL ErrorHandler.
272 */
273 static void ReportErrors(PositionInfo pos = PositionInfo());
274
Ethan Nicholas95046142021-01-07 10:57:27 -0500275 static DSLWriter& Instance();
276
277 static void SetInstance(std::unique_ptr<DSLWriter> instance);
278
279private:
Ethan Nicholas624a5292021-04-16 14:54:43 -0400280 std::unique_ptr<SkSL::ProgramConfig> fConfig;
John Stiles10d39d92021-05-04 16:13:14 -0400281 std::unique_ptr<SkSL::ModifiersPool> fModifiersPool;
Ethan Nicholas95046142021-01-07 10:57:27 -0500282 SkSL::Compiler* fCompiler;
Ethan Nicholas961d9442021-03-16 16:37:29 -0400283 std::unique_ptr<Pool> fPool;
John Stilesd1204642021-02-17 16:30:02 -0500284 SkSL::ProgramConfig* fOldConfig;
John Stiles10d39d92021-05-04 16:13:14 -0400285 SkSL::ModifiersPool* fOldModifiersPool;
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500286 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
Ethan Nicholas624a5292021-04-16 14:54:43 -0400287 std::vector<const SkSL::ProgramElement*> fSharedElements;
Ethan Nicholas95046142021-01-07 10:57:27 -0500288 ErrorHandler* fErrorHandler = nullptr;
Ethan Nicholas55a63af2021-05-18 10:12:58 -0400289 ProgramSettings fSettings;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500290 Mangler fMangler;
Ethan Nicholas292a09d2021-07-14 09:52:16 -0400291 bool fIsModule;
Ethan Nicholas4f3e6a22021-06-15 09:17:05 -0400292 bool fEncounteredErrors = false;
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500293#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
294 struct StackFrame {
Brian Salomon3176e862021-08-09 11:23:04 -0400295 GrFragmentProcessor::ProgramImpl* fProcessor;
296 GrFragmentProcessor::ProgramImpl::EmitArgs* fEmitArgs;
John Stiles3befaf22021-04-23 14:42:22 -0400297 SkSL::StatementArray fSavedDeclarations;
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500298 };
John Stiles3befaf22021-04-23 14:42:22 -0400299 std::stack<StackFrame, std::list<StackFrame>> fStack;
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500300#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Ethan Nicholas95046142021-01-07 10:57:27 -0500301
302 friend class DSLCore;
Ethan Nicholas961d9442021-03-16 16:37:29 -0400303 friend class DSLVar;
Ethan Nicholas95046142021-01-07 10:57:27 -0500304};
305
306} // namespace dsl
307
308} // namespace SkSL
309
310#endif