blob: 03258f93040cfcbdb6491693ada3c6a85eb50235 [file] [log] [blame]
Ethan Nicholasb3d4e742021-01-08 11:42:25 -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/DSLType.h"
Ethan Nicholasb3d4e742021-01-08 11:42:25 -05009
10#include "src/sksl/dsl/priv/DSLWriter.h"
11#include "src/sksl/ir/SkSLConstructor.h"
Ethan Nicholasbf79dff2021-02-11 15:18:31 -050012#include "src/sksl/ir/SkSLStructDefinition.h"
Ethan Nicholasb3d4e742021-01-08 11:42:25 -050013
14namespace SkSL {
15
16namespace dsl {
17
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040018static const Type* find_type(skstd::string_view name, PositionInfo pos) {
John Stiles4adb66f2021-08-05 10:15:16 -040019 const Symbol* symbol = (*DSLWriter::SymbolTable())[name];
20 if (!symbol) {
Ethan Nicholas32724122021-09-07 13:49:07 -040021 DSLWriter::ReportError(String::printf("no symbol named '%.*s'", (int)name.length(),
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040022 name.data()), pos);
John Stiles4adb66f2021-08-05 10:15:16 -040023 return nullptr;
Ethan Nicholasf07b4ce2021-06-08 08:57:37 -040024 }
John Stiles4adb66f2021-08-05 10:15:16 -040025 if (!symbol->is<Type>()) {
Ethan Nicholas32724122021-09-07 13:49:07 -040026 DSLWriter::ReportError(String::printf("symbol '%.*s' is not a type", (int)name.length(),
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040027 name.data()), pos);
John Stiles4adb66f2021-08-05 10:15:16 -040028 return nullptr;
29 }
Ethan Nicholas517f4ff2021-09-02 10:57:45 -040030 const Type& result = symbol->as<Type>();
31 if (!DSLWriter::IsModule()) {
32 if (result.containsPrivateFields()) {
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040033 DSLWriter::ReportError("type '" + String(name) + "' is private", pos);
Ethan Nicholas517f4ff2021-09-02 10:57:45 -040034 return nullptr;
35 }
36 if (DSLWriter::Context().fConfig->strictES2Mode() && !result.allowedInES2()) {
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040037 DSLWriter::ReportError("type '" + String(name) + "' is not supported", pos);
Ethan Nicholas517f4ff2021-09-02 10:57:45 -040038 return nullptr;
39 }
40 }
41 return &result;
Ethan Nicholasf07b4ce2021-06-08 08:57:37 -040042}
43
Ethan Nicholasa248a9a2021-09-01 16:40:25 -040044static const Type* find_type(skstd::string_view name, const Modifiers& modifiers,
45 PositionInfo pos) {
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040046 const Type* type = find_type(name, pos);
John Stiles4adb66f2021-08-05 10:15:16 -040047 if (!type) {
48 return nullptr;
49 }
Ethan Nicholasa248a9a2021-09-01 16:40:25 -040050 const Type* result = type->applyPrecisionQualifiers(DSLWriter::Context(), modifiers,
Brian Osmancc914522021-09-24 18:58:37 +000051 DSLWriter::SymbolTable().get(), /*offset=*/-1);
Ethan Nicholasa248a9a2021-09-01 16:40:25 -040052 DSLWriter::ReportErrors(pos);
53 return result;
John Stiles4adb66f2021-08-05 10:15:16 -040054}
55
56DSLType::DSLType(skstd::string_view name)
Ethan Nicholas80d2b3e2021-09-15 15:11:51 -040057 : fSkSLType(find_type(name, PositionInfo())) {}
John Stiles4adb66f2021-08-05 10:15:16 -040058
Ethan Nicholasa248a9a2021-09-01 16:40:25 -040059DSLType::DSLType(skstd::string_view name, const DSLModifiers& modifiers, PositionInfo position)
60 : fSkSLType(find_type(name, modifiers.fModifiers, position)) {}
John Stiles4adb66f2021-08-05 10:15:16 -040061
Ethan Nicholasb83199e2021-05-03 14:25:35 -040062bool DSLType::isBoolean() const {
63 return this->skslType().isBoolean();
64}
65
66bool DSLType::isNumber() const {
67 return this->skslType().isNumber();
68}
69
70bool DSLType::isFloat() const {
71 return this->skslType().isFloat();
72}
73
74bool DSLType::isSigned() const {
75 return this->skslType().isSigned();
76}
77
78bool DSLType::isUnsigned() const {
79 return this->skslType().isUnsigned();
80}
81
82bool DSLType::isInteger() const {
83 return this->skslType().isInteger();
84}
85
86bool DSLType::isScalar() const {
87 return this->skslType().isScalar();
88}
89
90bool DSLType::isVector() const {
91 return this->skslType().isVector();
92}
93
94bool DSLType::isMatrix() const {
95 return this->skslType().isMatrix();
96}
97
98bool DSLType::isArray() const {
99 return this->skslType().isArray();
100}
101
102bool DSLType::isStruct() const {
103 return this->skslType().isStruct();
104}
105
Brian Osmane76530d2021-09-09 14:31:31 -0400106bool DSLType::isEffectChild() const {
107 return this->skslType().isEffectChild();
108}
109
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500110const SkSL::Type& DSLType::skslType() const {
111 if (fSkSLType) {
112 return *fSkSLType;
113 }
114 const SkSL::Context& context = DSLWriter::Context();
115 switch (fTypeConstant) {
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400116 case kBool_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500117 return *context.fTypes.fBool;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400118 case kBool2_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500119 return *context.fTypes.fBool2;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400120 case kBool3_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500121 return *context.fTypes.fBool3;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400122 case kBool4_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500123 return *context.fTypes.fBool4;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400124 case kHalf_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500125 return *context.fTypes.fHalf;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400126 case kHalf2_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500127 return *context.fTypes.fHalf2;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400128 case kHalf3_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500129 return *context.fTypes.fHalf3;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400130 case kHalf4_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500131 return *context.fTypes.fHalf4;
Ethan Nicholas84558932021-04-12 16:56:37 -0400132 case kHalf2x2_Type:
133 return *context.fTypes.fHalf2x2;
134 case kHalf3x2_Type:
135 return *context.fTypes.fHalf3x2;
136 case kHalf4x2_Type:
137 return *context.fTypes.fHalf4x2;
138 case kHalf2x3_Type:
139 return *context.fTypes.fHalf2x3;
140 case kHalf3x3_Type:
141 return *context.fTypes.fHalf3x3;
142 case kHalf4x3_Type:
143 return *context.fTypes.fHalf4x3;
144 case kHalf2x4_Type:
145 return *context.fTypes.fHalf2x4;
146 case kHalf3x4_Type:
147 return *context.fTypes.fHalf3x4;
148 case kHalf4x4_Type:
149 return *context.fTypes.fHalf4x4;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400150 case kFloat_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500151 return *context.fTypes.fFloat;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400152 case kFloat2_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500153 return *context.fTypes.fFloat2;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400154 case kFloat3_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500155 return *context.fTypes.fFloat3;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400156 case kFloat4_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500157 return *context.fTypes.fFloat4;
Ethan Nicholas84558932021-04-12 16:56:37 -0400158 case kFloat2x2_Type:
159 return *context.fTypes.fFloat2x2;
160 case kFloat3x2_Type:
161 return *context.fTypes.fFloat3x2;
162 case kFloat4x2_Type:
163 return *context.fTypes.fFloat4x2;
164 case kFloat2x3_Type:
165 return *context.fTypes.fFloat2x3;
166 case kFloat3x3_Type:
167 return *context.fTypes.fFloat3x3;
168 case kFloat4x3_Type:
169 return *context.fTypes.fFloat4x3;
170 case kFloat2x4_Type:
171 return *context.fTypes.fFloat2x4;
172 case kFloat3x4_Type:
173 return *context.fTypes.fFloat3x4;
174 case kFloat4x4_Type:
175 return *context.fTypes.fFloat4x4;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400176 case kInt_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500177 return *context.fTypes.fInt;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400178 case kInt2_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500179 return *context.fTypes.fInt2;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400180 case kInt3_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500181 return *context.fTypes.fInt3;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400182 case kInt4_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500183 return *context.fTypes.fInt4;
Ethan Nicholas624a5292021-04-16 14:54:43 -0400184 case kShader_Type:
185 return *context.fTypes.fShader;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400186 case kShort_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500187 return *context.fTypes.fShort;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400188 case kShort2_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500189 return *context.fTypes.fShort2;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400190 case kShort3_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500191 return *context.fTypes.fShort3;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400192 case kShort4_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500193 return *context.fTypes.fShort4;
Ethan Nicholasb83199e2021-05-03 14:25:35 -0400194 case kUInt_Type:
195 return *context.fTypes.fUInt;
196 case kUInt2_Type:
197 return *context.fTypes.fUInt2;
198 case kUInt3_Type:
199 return *context.fTypes.fUInt3;
200 case kUInt4_Type:
201 return *context.fTypes.fUInt4;
202 case kUShort_Type:
203 return *context.fTypes.fUShort;
204 case kUShort2_Type:
205 return *context.fTypes.fUShort2;
206 case kUShort3_Type:
207 return *context.fTypes.fUShort3;
208 case kUShort4_Type:
209 return *context.fTypes.fUShort4;
Ethan Nicholasb14e6b92021-04-08 16:56:05 -0400210 case kVoid_Type:
John Stiles54e7c052021-01-11 14:22:36 -0500211 return *context.fTypes.fVoid;
Ethan Nicholas5c4463e2021-08-29 14:31:19 -0400212 case kPoison_Type:
213 return *context.fTypes.fPoison;
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500214 default:
215 SkUNREACHABLE;
216 }
217}
218
John Stilesd6c08c92021-08-11 11:37:51 -0400219DSLExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> argArray) {
Ethan Nicholas0cb3b822021-05-03 15:12:14 -0400220 return DSLWriter::Construct(type.skslType(), std::move(argArray));
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500221}
222
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400223DSLType Array(const DSLType& base, int count, PositionInfo pos) {
Ethan Nicholas5fad2b82021-09-27 10:39:18 -0400224 count = base.skslType().convertArraySize(DSLWriter::Context(),
225 DSLExpression(count, pos).release());
Brian Osmana909dd62021-09-24 19:00:35 +0000226 DSLWriter::ReportErrors(pos);
Ethan Nicholasfd1ff922021-08-31 16:57:53 -0400227 if (!count) {
228 return DSLType(kPoison_Type);
229 }
Ethan Nicholas04be3392021-01-26 10:07:01 -0500230 return DSLWriter::SymbolTable()->addArrayDimension(&base.skslType(), count);
231}
232
Ethan Nicholas6f20b8d2021-08-31 07:40:24 -0400233DSLType Struct(skstd::string_view name, SkSpan<DSLField> fields, PositionInfo pos) {
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500234 std::vector<SkSL::Type::Field> skslFields;
John Stilesed7b4f62021-08-11 11:42:57 -0400235 skslFields.reserve(fields.size());
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500236 for (const DSLField& field : fields) {
Ethan Nicholas0c8a5982021-08-31 11:48:54 -0400237 if (field.fModifiers.fModifiers.fFlags != Modifiers::kNo_Flag) {
238 String desc = field.fModifiers.fModifiers.description();
239 desc.pop_back(); // remove trailing space
Ethan Nicholas32724122021-09-07 13:49:07 -0400240 DSLWriter::ReportError("modifier '" + desc + "' is not permitted on a struct field",
241 field.fPosition);
Ethan Nicholas0c8a5982021-08-31 11:48:54 -0400242 }
243
Ethan Nicholas772061e2021-08-29 12:42:38 -0400244 const SkSL::Type& type = field.fType.skslType();
245 if (type.isOpaque()) {
Ethan Nicholas32724122021-09-07 13:49:07 -0400246 DSLWriter::ReportError("opaque type '" + type.displayName() +
247 "' is not permitted in a struct", field.fPosition);
Ethan Nicholas772061e2021-08-29 12:42:38 -0400248 }
249 skslFields.emplace_back(field.fModifiers.fModifiers, field.fName, &type);
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500250 }
Brian Osmancc914522021-09-24 18:58:37 +0000251 const SkSL::Type* result = DSLWriter::SymbolTable()->add(Type::MakeStructType(pos.offset(),
Ethan Nicholas27f06eb2021-07-26 16:39:40 -0400252 name,
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500253 skslFields));
Ethan Nicholas833cd202021-09-02 14:46:41 -0400254 if (result->isTooDeeplyNested()) {
Ethan Nicholas32724122021-09-07 13:49:07 -0400255 DSLWriter::ReportError("struct '" + String(name) + "' is too deeply nested", pos);
Ethan Nicholas833cd202021-09-02 14:46:41 -0400256 }
Brian Osmancc914522021-09-24 18:58:37 +0000257 DSLWriter::ProgramElements().push_back(std::make_unique<SkSL::StructDefinition>(/*offset=*/-1,
Ethan Nicholasbf79dff2021-02-11 15:18:31 -0500258 *result));
259 return result;
260}
261
Ethan Nicholasb3d4e742021-01-08 11:42:25 -0500262} // namespace dsl
263
264} // namespace SkSL