blob: fcb9936cada86c40fd5f160f80eac89bea6cc740 [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"
12#include "include/sksl/DSLExpression.h"
13#include "include/sksl/DSLStatement.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050014#include "src/sksl/SkSLMangler.h"
John Stiles45990502021-02-16 10:55:27 -050015#include "src/sksl/SkSLOperators.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050016#include "src/sksl/ir/SkSLExpressionStatement.h"
17#include "src/sksl/ir/SkSLProgram.h"
18#include "src/sksl/ir/SkSLStatement.h"
19#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
79 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050080 * Returns the final pointer to a pooled Modifiers object that should be used to represent the
81 * given modifiers.
82 */
83 static const SkSL::Modifiers* Modifiers(SkSL::Modifiers modifiers);
84
85 /**
Ethan Nicholasd6b26e52021-01-27 07:53:46 -050086 * Returns the SkSL variable corresponding to a DSLVar.
87 */
88 static const SkSL::Variable& Var(const DSLVar& var);
89
90 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050091 * Returns the (possibly mangled) final name that should be used for an entity with the given
92 * raw name.
93 */
94 static const char* Name(const char* name);
95
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -050096#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
97 /**
98 * Returns the fragment processor for which DSL output is being generated for the current
99 * thread.
100 */
101 static GrGLSLFragmentProcessor* CurrentProcessor() {
102 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
103 return Instance().fStack.top().fProcessor;
104 }
105
106 /**
107 * Returns the EmitArgs for fragment processor output in the current thread.
108 */
109 static GrGLSLFragmentProcessor::EmitArgs* CurrentEmitArgs() {
110 SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
111 return Instance().fStack.top().fEmitArgs;
112 }
113
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500114 static bool InFragmentProcessor() {
115 return !Instance().fStack.empty();
116 }
117
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500118 /**
119 * Pushes a new processor / emitArgs pair for the current thread.
120 */
121 static void StartFragmentProcessor(GrGLSLFragmentProcessor* processor,
122 GrGLSLFragmentProcessor::EmitArgs* emitArgs);
123
124 /**
125 * Pops the processor / emitArgs pair associated with the current thread.
126 */
127 static void EndFragmentProcessor();
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500128
129 static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLVar& var);
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500130#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
131
Ethan Nicholasdaed2592021-03-04 14:30:25 -0500132 static std::unique_ptr<SkSL::Expression> Call(const FunctionDeclaration& function,
133 ExpressionArray arguments);
134
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500135 /**
Ethan Nicholas95046142021-01-07 10:57:27 -0500136 * Reports an error if the argument is null. Returns its argument unmodified.
137 */
138 static std::unique_ptr<SkSL::Expression> Check(std::unique_ptr<SkSL::Expression> expr);
139
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500140 static DSLPossibleExpression Coerce(std::unique_ptr<Expression> left, const SkSL::Type& type);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500141
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500142 static DSLPossibleExpression Construct(const SkSL::Type& type,
143 std::vector<DSLExpression> rawArgs);
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500144
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500145 static std::unique_ptr<Expression> ConvertBinary(std::unique_ptr<Expression> left, Operator op,
146 std::unique_ptr<Expression> right);
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500147
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500148 static std::unique_ptr<SkSL::Expression> ConvertField(std::unique_ptr<Expression> base,
149 const char* name);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500150
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500151 static std::unique_ptr<Expression> ConvertIndex(std::unique_ptr<Expression> base,
152 std::unique_ptr<Expression> index);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500153
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500154 static std::unique_ptr<Expression> ConvertPostfix(std::unique_ptr<Expression> expr,
155 Operator op);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500156
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500157 static std::unique_ptr<Expression> ConvertPrefix(Operator op, std::unique_ptr<Expression> expr);
Ethan Nicholas92969f22021-01-13 10:38:59 -0500158
Ethan Nicholas34c7e112021-02-25 20:50:32 -0500159 static DSLPossibleStatement ConvertSwitch(std::unique_ptr<Expression> value,
160 ExpressionArray caseValues,
161 SkTArray<SkSL::StatementArray> caseStatements);
Ethan Nicholascfefec02021-02-09 15:22:57 -0500162
Ethan Nicholas95046142021-01-07 10:57:27 -0500163 /**
164 * Sets the ErrorHandler associated with the current thread. This object will be notified when
165 * any DSL errors occur. With a null ErrorHandler (the default), any errors will be dumped to
166 * stderr and a fatal exception will be generated.
167 */
168 static void SetErrorHandler(ErrorHandler* errorHandler) {
169 Instance().fErrorHandler = errorHandler;
170 }
171
172 /**
173 * Notifies the current ErrorHandler that a DSL error has occurred. With a null ErrorHandler
174 * (the default), any errors will be dumped to stderr and a fatal exception will be generated.
175 */
Ethan Nicholasb9563042021-02-25 09:45:49 -0500176 static void ReportError(const char* msg, PositionInfo* info = nullptr);
Ethan Nicholas95046142021-01-07 10:57:27 -0500177
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500178 /**
179 * Returns whether name mangling is enabled. This should always be enabled outside of tests.
180 */
181 static bool ManglingEnabled() {
182 return Instance().fMangle;
183 }
184
Ethan Nicholas95046142021-01-07 10:57:27 -0500185 static DSLWriter& Instance();
186
187 static void SetInstance(std::unique_ptr<DSLWriter> instance);
188
189private:
John Stilesd1204642021-02-17 16:30:02 -0500190 SkSL::ProgramConfig fConfig;
Ethan Nicholas95046142021-01-07 10:57:27 -0500191 SkSL::Compiler* fCompiler;
Ethan Nicholas0584ac02021-02-17 10:48:14 -0500192 std::shared_ptr<SkSL::SymbolTable> fOldSymbolTable;
John Stilesd1204642021-02-17 16:30:02 -0500193 SkSL::ProgramConfig* fOldConfig;
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500194 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
Ethan Nicholas95046142021-01-07 10:57:27 -0500195 ErrorHandler* fErrorHandler = nullptr;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500196 bool fMangle = true;
197 Mangler fMangler;
Ethan Nicholasc3bb9e32021-02-02 11:51:03 -0500198#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
199 struct StackFrame {
200 GrGLSLFragmentProcessor* fProcessor;
201 GrGLSLFragmentProcessor::EmitArgs* fEmitArgs;
202 };
203 std::stack<StackFrame> fStack;
204#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Ethan Nicholas95046142021-01-07 10:57:27 -0500205
206 friend class DSLCore;
207 friend class ::AutoDSLContext;
208};
209
210} // namespace dsl
211
212} // namespace SkSL
213
214#endif