blob: 37de47917e6c3f0588e92a78992aca46d02a482a [file] [log] [blame]
Ethan Nicholasbffe80a2021-01-11 15:42:44 -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
Ethan Nicholasdaed2592021-03-04 14:30:25 -05008#include "include/sksl/DSLVar.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -05009
Ethan Nicholasdaed2592021-03-04 14:30:25 -050010#include "include/sksl/DSLModifiers.h"
11#include "include/sksl/DSLType.h"
Ethan Nicholas624a5292021-04-16 14:54:43 -040012#include "src/sksl/SkSLCompiler.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050013#include "src/sksl/SkSLUtil.h"
Ethan Nicholasbffe80a2021-01-11 15:42:44 -050014#include "src/sksl/dsl/priv/DSLWriter.h"
15#include "src/sksl/ir/SkSLBinaryExpression.h"
16#include "src/sksl/ir/SkSLSymbolTable.h"
17#include "src/sksl/ir/SkSLVariable.h"
18#include "src/sksl/ir/SkSLVariableReference.h"
19
20namespace SkSL {
21
22namespace dsl {
23
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040024DSLVarBase::DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue,
25 PositionInfo pos)
26 : DSLVarBase(DSLModifiers(), std::move(type), name, std::move(initialValue), pos) {}
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040027
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040028DSLVarBase::DSLVarBase(DSLType type, DSLExpression initialValue, PositionInfo pos)
29 : DSLVarBase(type, "var", std::move(initialValue), pos) {}
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040030
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040031DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue,
32 PositionInfo pos)
33 : DSLVarBase(modifiers, type, "var", std::move(initialValue), pos) {}
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040034
John Stilese53c7212021-08-05 10:19:11 -040035DSLVarBase::DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::string_view name,
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040036 DSLExpression initialValue, PositionInfo pos)
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040037 : fModifiers(std::move(modifiers))
38 , fType(std::move(type))
Ethan Nicholas961d9442021-03-16 16:37:29 -040039 , fRawName(name)
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040040 , fName(fType.skslType().isOpaque() ? name : DSLWriter::Name(name))
41 , fInitialValue(std::move(initialValue))
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040042 , fDeclared(DSLWriter::MarkVarsDeclared())
43 , fPosition(pos) {
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040044 if (fModifiers.fModifiers.fFlags & Modifiers::kUniform_Flag) {
45#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
46 if (DSLWriter::InFragmentProcessor()) {
47 const SkSL::Type& skslType = type.skslType();
48 GrSLType grslType;
49 int count;
50 if (skslType.isArray()) {
51 SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(),
52 skslType.componentType(),
53 &grslType));
54 count = skslType.columns();
55 SkASSERT(count > 0);
56 } else {
57 SkAssertResult(SkSL::type_to_grsltype(DSLWriter::Context(), skslType,
58 &grslType));
59 count = 0;
60 }
John Stiles628777c2021-08-04 22:07:41 -040061 const char* uniformName;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040062 SkASSERT(DSLWriter::CurrentEmitArgs());
63 fUniformHandle = DSLWriter::CurrentEmitArgs()->fUniformHandler->addUniformArray(
64 &DSLWriter::CurrentEmitArgs()->fFp,
65 kFragment_GrShaderFlag,
66 grslType,
67 String(this->name()).c_str(),
68 count,
John Stiles628777c2021-08-04 22:07:41 -040069 &uniformName).toIndex();
70 fName = uniformName;
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040071 }
72#endif // SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
73 }
74}
75
76DSLVarBase::~DSLVarBase() {
77 if (fDeclaration && !fDeclared) {
Ethan Nicholas4a5e22a2021-08-13 17:29:51 -040078 DSLWriter::ReportError(String::printf("variable '%.*s' was destroyed without being "
79 "declared",
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040080 (int)fRawName.length(),
81 fRawName.data()).c_str());
82 }
83}
84
85void DSLVarBase::swap(DSLVarBase& other) {
86 SkASSERT(this->storage() == other.storage());
87 std::swap(fModifiers, other.fModifiers);
88 std::swap(fType, other.fType);
89 std::swap(fUniformHandle, other.fUniformHandle);
90 std::swap(fDeclaration, other.fDeclaration);
91 std::swap(fVar, other.fVar);
92 std::swap(fRawName, other.fRawName);
93 std::swap(fName, other.fName);
94 std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
95 std::swap(fDeclared, other.fDeclared);
Ethan Nicholas5c4463e2021-08-29 14:31:19 -040096 std::swap(fInitialized, other.fInitialized);
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -040097 std::swap(fPosition, other.fPosition);
Ethan Nicholasa2d22b22021-07-15 10:35:54 -040098}
99
100void DSLVar::swap(DSLVar& other) {
101 INHERITED::swap(other);
102}
103
104VariableStorage DSLVar::storage() const {
105 return VariableStorage::kLocal;
106}
107
108DSLGlobalVar::DSLGlobalVar(const char* name)
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400109 : INHERITED(kVoid_Type, name, DSLExpression(), PositionInfo()) {
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400110 fName = name;
111 DSLWriter::MarkDeclared(*this);
Ethan Nicholas8d03eb02021-02-17 15:52:09 -0500112#if SK_SUPPORT_GPU && !defined(SKSL_STANDALONE)
113 if (!strcmp(name, "sk_SampleCoord")) {
114 fName = DSLWriter::CurrentEmitArgs()->fSampleCoord;
115 // The actual sk_SampleCoord variable hasn't been created by GrGLSLFPFragmentBuilder yet, so
116 // if we attempt to look it up in the symbol table we'll get null. As we are currently
117 // converting all DSL code into strings rather than nodes, all we really need is a
118 // correctly-named variable with the right type, so we just create a placeholder for it.
119 // TODO(skia/11330): we'll need to fix this when switching over to nodes.
John Stiles10d39d92021-05-04 16:13:14 -0400120 const SkSL::Modifiers* modifiers = DSLWriter::Context().fModifiersPool->add(
121 SkSL::Modifiers(SkSL::Layout(/*flags=*/0, /*location=*/-1, /*offset=*/-1,
122 /*binding=*/-1, /*index=*/-1, /*set=*/-1,
Brian Osman99ddd2a2021-08-27 11:21:12 -0400123 SK_MAIN_COORDS_BUILTIN, /*inputAttachmentIndex=*/-1),
John Stiles10d39d92021-05-04 16:13:14 -0400124 SkSL::Modifiers::kNo_Flag));
125
126 fVar = DSLWriter::SymbolTable()->takeOwnershipOfIRNode(std::make_unique<SkSL::Variable>(
Brian Osmancc914522021-09-24 18:58:37 +0000127 /*offset=*/-1,
John Stiles10d39d92021-05-04 16:13:14 -0400128 modifiers,
129 fName,
130 DSLWriter::Context().fTypes.fFloat2.get(),
131 /*builtin=*/true,
132 SkSL::VariableStorage::kGlobal));
Ethan Nicholas5c4463e2021-08-29 14:31:19 -0400133 fInitialized = true;
Ethan Nicholas8d03eb02021-02-17 15:52:09 -0500134 return;
135 }
136#endif
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500137 const SkSL::Symbol* result = (*DSLWriter::SymbolTable())[fName];
Ethan Nicholasd0f4d0d2021-06-23 13:51:55 -0400138 SkASSERTF(result, "could not find '%.*s' in symbol table", (int)fName.length(), fName.data());
Ethan Nicholasfe5d6922021-03-05 14:23:48 -0500139 fVar = &result->as<SkSL::Variable>();
Ethan Nicholas5c4463e2021-08-29 14:31:19 -0400140 fInitialized = true;
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500141}
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500142
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400143void DSLGlobalVar::swap(DSLGlobalVar& other) {
144 INHERITED::swap(other);
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500145}
146
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400147VariableStorage DSLGlobalVar::storage() const {
148 return VariableStorage::kGlobal;
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500149}
Ethan Nicholas11a15b12021-02-11 15:56:27 -0500150
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400151void DSLParameter::swap(DSLParameter& other) {
152 INHERITED::swap(other);
John Stiles08771b02021-04-26 09:35:10 -0400153}
154
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400155VariableStorage DSLParameter::storage() const {
156 return VariableStorage::kParameter;
157}
158
159
160DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
Ethan Nicholas5fad2b82021-09-27 10:39:18 -0400161 return DSLExpression(*this, PositionInfo())[std::move(index)];
Ethan Nicholas04be3392021-01-26 10:07:01 -0500162}
163
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400164DSLPossibleExpression DSLVarBase::assign(DSLExpression expr) {
Ethan Nicholas5fad2b82021-09-27 10:39:18 -0400165 return DSLWriter::ConvertBinary(DSLExpression(*this, PositionInfo()).release(),
166 SkSL::Token::Kind::TK_EQ, expr.release());
Ethan Nicholas92969f22021-01-13 10:38:59 -0500167}
168
Ethan Nicholasa2d22b22021-07-15 10:35:54 -0400169DSLPossibleExpression DSLVar::operator=(DSLExpression expr) {
170 return this->assign(std::move(expr));
171}
172
173DSLPossibleExpression DSLGlobalVar::operator=(DSLExpression expr) {
174 return this->assign(std::move(expr));
175}
176
177DSLPossibleExpression DSLParameter::operator=(DSLExpression expr) {
178 return this->assign(std::move(expr));
179}
180
Brian Osmane76530d2021-09-09 14:31:31 -0400181std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(skstd::string_view methodName,
182 PositionInfo pos) {
183 if (!this->fType.isEffectChild()) {
184 DSLWriter::ReportError("type does not support method calls", pos);
185 return nullptr;
186 }
Ethan Nicholas5fad2b82021-09-27 10:39:18 -0400187 return DSLWriter::ConvertField(DSLExpression(*this, PositionInfo()).release(), methodName);
Brian Osmane76530d2021-09-09 14:31:31 -0400188}
189
190DSLPossibleExpression DSLGlobalVar::eval(DSLExpression x, PositionInfo pos) {
191 ExpressionArray converted;
192 converted.push_back(x.release());
193
194 auto method = this->methodCall("eval", pos);
195 return DSLPossibleExpression(
196 method ? DSLWriter::Call(std::move(method), std::move(converted), pos) : nullptr);
197}
198
199DSLPossibleExpression DSLGlobalVar::eval(DSLExpression x, DSLExpression y, PositionInfo pos) {
200 ExpressionArray converted;
201 converted.push_back(x.release());
202 converted.push_back(y.release());
203
204 auto method = this->methodCall("eval", pos);
205 return DSLPossibleExpression(
206 method ? DSLWriter::Call(std::move(method), std::move(converted), pos) : nullptr);
207}
208
Ethan Nicholasbffe80a2021-01-11 15:42:44 -0500209} // namespace dsl
210
211} // namespace SkSL