blob: b51905cfac421d86e266c59ef83dfccdb100a593 [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
Ethan Nicholasdaed2592021-03-04 14:30:25 -050011#include "include/private/SkSLModifiers.h"
Ethan Nicholas24c17722021-03-09 13:10:59 -050012#include "include/private/SkSLStatement.h"
Ethan Nicholasdaed2592021-03-04 14:30:25 -050013#include "include/sksl/DSLExpression.h"
14#include "include/sksl/DSLStatement.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050015#include "src/sksl/SkSLMangler.h"
John Stiles45990502021-02-16 10:55:27 -050016#include "src/sksl/SkSLOperators.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050017#include "src/sksl/ir/SkSLExpressionStatement.h"
18#include "src/sksl/ir/SkSLProgram.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050019#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
20#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
21#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Ethan Nicholas95046142021-01-07 10:57:27 -050022#include <stack>
23
24class AutoDSLContext;
25
26namespace SkSL {
27
28class Compiler;
29class Context;
30class IRGenerator;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050031class ProgramElement;
Ethan Nicholas95046142021-01-07 10:57:27 -050032class SymbolTable;
33class Type;
Ethan Nicholasdaed2592021-03-04 14:30:25 -050034class Variable;
Ethan Nicholas95046142021-01-07 10:57:27 -050035
36namespace dsl {
37
38class ErrorHandler;
39
40/**
41 * Thread-safe class that tracks per-thread state associated with DSL output. This class is for
42 * internal use only.
43 */
44class DSLWriter {
45public:
46 DSLWriter(SkSL::Compiler* compiler);
47
Ethan Nicholas0584ac02021-02-17 10:48:14 -050048 ~DSLWriter();
49
Ethan Nicholas95046142021-01-07 10:57:27 -050050 /**
51 * Returns the Compiler used by DSL operations in the current thread.
52 */
53 static SkSL::Compiler& Compiler() {
54 return *Instance().fCompiler;
55 }
56
57 /**
58 * Returns the IRGenerator used by DSL operations in the current thread.
59 */
60 static SkSL::IRGenerator& IRGenerator();
61
62 /**
63 * Returns the Context used by DSL operations in the current thread.
64 */
65 static const SkSL::Context& Context();
66
67 /**
Ethan Nicholas1ff76092021-01-28 10:02:43 -050068 * Returns the collection to which DSL program elements in this thread should be appended.
69 */
70 static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
71 return Instance().fProgramElements;
72 }
73
74 /**
Ethan Nicholas95046142021-01-07 10:57:27 -050075 * Returns the SymbolTable of the current thread's IRGenerator.
76 */
77 static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
78
Ethan Nicholasfe5d6922021-03-05 14:23:48 -050079 static void Reset();
80
Ethan Nicholas95046142021-01-07 10:57:27 -050081 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050082 * Returns the final pointer to a pooled Modifiers object that should be used to represent the
83 * given modifiers.
84 */
85 static const SkSL::Modifiers* Modifiers(SkSL::Modifiers modifiers);
86
87 /**
Ethan Nicholasd6b26e52021-01-27 07:53:46 -050088 * Returns the SkSL variable corresponding to a DSLVar.
89 */
90 static const SkSL::Variable& Var(const DSLVar& var);
91
92 /**
Ethan Nicholas961d9442021-03-16 16:37:29 -040093 * For use in testing only: marks the variable as having been declared, so that it can be
94 * destroyed without generating errors.
95 */
96 static void MarkDeclared(DSLVar& var);
97
98 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050099 * Returns the (possibly mangled) final name that should be used for an entity with the given
100 * raw name.
101 */
102 static const char* Name(const char* name);
103
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500104#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
105 /**
106 * Returns the fragment processor for which DSL output is being generated for the current
107 * thread.
108 */
109 static GrGLSLFragmentProcessor* CurrentProcessor() {
110 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
111 return Instance().fStack.top().fProcessor;
112 }
113
114 /**
115 * Returns the EmitArgs for fragment processor output in the current thread.
116 */
117 static GrGLSLFragmentProcessor::EmitArgs* CurrentEmitArgs() {
118 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
119 return Instance().fStack.top().fEmitArgs;
120 }
121
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500122 static bool InFragmentProcessor() {
123 return !Instance().fStack.empty();
124 }
125
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500126 /**
127 * Pushes a new processor / emitArgs pair for the current thread.
128 */
129 static void StartFragmentProcessor(GrGLSLFragmentProcessor* processor,
130 GrGLSLFragmentProcessor::EmitArgs* emitArgs);
131
132 /**
133 * Pops the processor / emitArgs pair associated with the current thread.
134 */
135 static void EndFragmentProcessor();
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500136
137 static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var);
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500138#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
139
Ethan Nicholasdaed2592021-03-04 14:30:25 -0500140 static std::unique_ptr<SkSL::Expression> Call(const FunctionDeclaration& function,
141 ExpressionArray arguments);
142
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500143 /**
Ethan Nicholas95046142021-01-07 10:57:27 -0500144 * Reports an error if the argument is null. Returns its argument unmodified.
145 */
146 static std::unique_ptr<SkSL::Expression> Check(std::unique_ptr<SkSL::Expression> expr);
147
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500148 static DSLPossibleExpression Coerce(std::unique_ptr<Expression> left, const SkSL::Type& type);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500149
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500150 static DSLPossibleExpression Construct(const SkSL::Type& type,
151 std::vector<DSLExpression> rawArgs);
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500152
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500153 static std::unique_ptr<Expression> ConvertBinary(std::unique_ptr<Expression> left, Operator op,
154 std::unique_ptr<Expression> right);
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500155
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500156 static std::unique_ptr<SkSL::Expression> ConvertField(std::unique_ptr<Expression> base,
157 const char* name);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500158
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500159 static std::unique_ptr<Expression> ConvertIndex(std::unique_ptr<Expression> base,
160 std::unique_ptr<Expression> index);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500161
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500162 static std::unique_ptr<Expression> ConvertPostfix(std::unique_ptr<Expression> expr,
163 Operator op);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500164
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500165 static std::unique_ptr<Expression> ConvertPrefix(Operator op, std::unique_ptr<Expression> expr);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500166
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500167 static DSLPossibleStatement ConvertSwitch(std::unique_ptr<Expression> value,
168 ExpressionArray caseValues,
169 SkTArray<SkSL::StatementArray> caseStatements);
Ethan Nicholascfefec02021-02-09 15:22:57 -0500170
Ethan Nicholas95046142021-01-07 10:57:27 -0500171 /**
172 * Sets the ErrorHandler associated with the current thread. This object will be notified when
173 * any DSL errors occur. With a null ErrorHandler (the default), any errors will be dumped to
174 * stderr and a fatal exception will be generated.
175 */
176 static void SetErrorHandler(ErrorHandler* errorHandler) {
177 Instance().fErrorHandler = errorHandler;
178 }
179
180 /**
181 * Notifies the current ErrorHandler that a DSL error has occurred. With a null ErrorHandler
182 * (the default), any errors will be dumped to stderr and a fatal exception will be generated.
183 */
Ethan Nicholasb9563042021-02-25 09:45:49 -0500184 static void ReportError(const char* msg, PositionInfo* info = nullptr);
Ethan Nicholas95046142021-01-07 10:57:27 -0500185
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500186 /**
187 * Returns whether name mangling is enabled. This should always be enabled outside of tests.
188 */
189 static bool ManglingEnabled() {
190 return Instance().fMangle;
191 }
192
Ethan Nicholas95046142021-01-07 10:57:27 -0500193 static DSLWriter& Instance();
194
195 static void SetInstance(std::unique_ptr<DSLWriter> instance);
196
197private:
John Stilesd1204642021-02-17 16:30:02 -0500198 SkSL::ProgramConfig fConfig;
Ethan Nicholas95046142021-01-07 10:57:27 -0500199 SkSL::Compiler* fCompiler;
Ethan Nicholas961d9442021-03-16 16:37:29 -0400200 std::unique_ptr<Pool> fPool;
Ethan Nicholas0584ac02021-02-17 10:48:14 -0500201 std::shared_ptr<SkSL::SymbolTable> fOldSymbolTable;
John Stilesd1204642021-02-17 16:30:02 -0500202 SkSL::ProgramConfig* fOldConfig;
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500203 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
Ethan Nicholas95046142021-01-07 10:57:27 -0500204 ErrorHandler* fErrorHandler = nullptr;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500205 bool fMangle = true;
Ethan Nicholas961d9442021-03-16 16:37:29 -0400206 bool fMarkVarsDeclared = false;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500207 Mangler fMangler;
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500208#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
209 struct StackFrame {
210 GrGLSLFragmentProcessor* fProcessor;
211 GrGLSLFragmentProcessor::EmitArgs* fEmitArgs;
212 };
213 std::stack<StackFrame> fStack;
214#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Ethan Nicholas95046142021-01-07 10:57:27 -0500215
216 friend class DSLCore;
Ethan Nicholas961d9442021-03-16 16:37:29 -0400217 friend class DSLVar;
Ethan Nicholas95046142021-01-07 10:57:27 -0500218 friend class ::AutoDSLContext;
219};
220
221} // namespace dsl
222
223} // namespace SkSL
224
225#endif