blob: 7d75e0406dd3ae5e34bba0da19af3a990f3e5293 [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 Nicholasbffe80a2021-01-11 15:42:44 -050011#include "src/sksl/SkSLMangler.h"
Ethan Nicholas95046142021-01-07 10:57:27 -050012#include "src/sksl/dsl/DSLExpression.h"
13#include "src/sksl/ir/SkSLExpressionStatement.h"
14#include "src/sksl/ir/SkSLProgram.h"
15#include "src/sksl/ir/SkSLStatement.h"
16#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
17#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
18#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
19
20#include <stack>
21
22class AutoDSLContext;
23
24namespace SkSL {
25
26class Compiler;
27class Context;
28class IRGenerator;
29class SymbolTable;
30class Type;
31
32namespace dsl {
33
34class ErrorHandler;
35
36/**
37 * Thread-safe class that tracks per-thread state associated with DSL output. This class is for
38 * internal use only.
39 */
40class DSLWriter {
41public:
42 DSLWriter(SkSL::Compiler* compiler);
43
44 /**
45 * Returns the Compiler used by DSL operations in the current thread.
46 */
47 static SkSL::Compiler& Compiler() {
48 return *Instance().fCompiler;
49 }
50
51 /**
52 * Returns the IRGenerator used by DSL operations in the current thread.
53 */
54 static SkSL::IRGenerator& IRGenerator();
55
56 /**
57 * Returns the Context used by DSL operations in the current thread.
58 */
59 static const SkSL::Context& Context();
60
61 /**
Ethan Nicholas1ff76092021-01-28 10:02:43 -050062 * Returns the collection to which DSL program elements in this thread should be appended.
63 */
64 static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
65 return Instance().fProgramElements;
66 }
67
68 /**
Ethan Nicholas95046142021-01-07 10:57:27 -050069 * Returns the SymbolTable of the current thread's IRGenerator.
70 */
71 static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
72
73 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050074 * Returns the final pointer to a pooled Modifiers object that should be used to represent the
75 * given modifiers.
76 */
77 static const SkSL::Modifiers* Modifiers(SkSL::Modifiers modifiers);
78
79 /**
Ethan Nicholasd6b26e52021-01-27 07:53:46 -050080 * Returns the SkSL variable corresponding to a DSLVar.
81 */
82 static const SkSL::Variable& Var(const DSLVar& var);
83
84 /**
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050085 * Returns the (possibly mangled) final name that should be used for an entity with the given
86 * raw name.
87 */
88 static const char* Name(const char* name);
89
90 /**
Ethan Nicholas1ff76092021-01-28 10:02:43 -050091 * Returns the current function for which we are generating nodes.
92 */
93 static const SkSL::FunctionDeclaration* CurrentFunction();
94
95 /**
96 * Specifies the function for which we are generating nodes.
97 */
98 static void SetCurrentFunction(const SkSL::FunctionDeclaration* fn);
99
100 /**
Ethan Nicholas95046142021-01-07 10:57:27 -0500101 * Reports an error if the argument is null. Returns its argument unmodified.
102 */
103 static std::unique_ptr<SkSL::Expression> Check(std::unique_ptr<SkSL::Expression> expr);
104
Ethan Nicholas92969f22021-01-13 10:38:59 -0500105 static DSLExpression Coerce(std::unique_ptr<Expression> left, const SkSL::Type& type);
106
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500107 static DSLExpression Construct(const SkSL::Type& type, std::vector<DSLExpression> rawArgs);
108
Ethan Nicholas92969f22021-01-13 10:38:59 -0500109 static DSLExpression ConvertBinary(std::unique_ptr<Expression> left, Token::Kind op,
110 std::unique_ptr<Expression> right);
111
112 static DSLExpression ConvertIndex(std::unique_ptr<Expression> base,
113 std::unique_ptr<Expression> index);
114
115 static DSLExpression ConvertPostfix(std::unique_ptr<Expression> expr, Token::Kind op);
116
117 static DSLExpression ConvertPrefix(Token::Kind op, std::unique_ptr<Expression> expr);
118
Ethan Nicholas95046142021-01-07 10:57:27 -0500119 /**
120 * Sets the ErrorHandler associated with the current thread. This object will be notified when
121 * any DSL errors occur. With a null ErrorHandler (the default), any errors will be dumped to
122 * stderr and a fatal exception will be generated.
123 */
124 static void SetErrorHandler(ErrorHandler* errorHandler) {
125 Instance().fErrorHandler = errorHandler;
126 }
127
128 /**
129 * Notifies the current ErrorHandler that a DSL error has occurred. With a null ErrorHandler
130 * (the default), any errors will be dumped to stderr and a fatal exception will be generated.
131 */
132 static void ReportError(const char* msg);
133
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500134 /**
135 * Returns whether name mangling is enabled. This should always be enabled outside of tests.
136 */
137 static bool ManglingEnabled() {
138 return Instance().fMangle;
139 }
140
Ethan Nicholas95046142021-01-07 10:57:27 -0500141 static DSLWriter& Instance();
142
143 static void SetInstance(std::unique_ptr<DSLWriter> instance);
144
145private:
146 SkSL::Program::Settings fSettings;
147 SkSL::Compiler* fCompiler;
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500148 std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
Ethan Nicholas95046142021-01-07 10:57:27 -0500149 ErrorHandler* fErrorHandler = nullptr;
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500150 bool fMangle = true;
151 Mangler fMangler;
Ethan Nicholas95046142021-01-07 10:57:27 -0500152
153 friend class DSLCore;
154 friend class ::AutoDSLContext;
155};
156
157} // namespace dsl
158
159} // namespace SkSL
160
161#endif