1 /*
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_DSL_TYPE
9 #define SKSL_DSL_TYPE
10
11 #include "include/core/SkSpan.h"
12 #include "include/core/SkTypes.h"
13 #include "include/sksl/DSLExpression.h"
14 #include "include/sksl/DSLModifiers.h"
15 #include "include/sksl/SkSLPosition.h"
16
17 #include <cstdint>
18 #include <string_view>
19 #include <utility>
20
21 namespace SkSL {
22
23 class Compiler;
24 class Type;
25
26 namespace dsl {
27
28 class DSLField;
29 class DSLVarBase;
30
31 enum TypeConstant : uint8_t {
32 kBool_Type,
33 kBool2_Type,
34 kBool3_Type,
35 kBool4_Type,
36 kHalf_Type,
37 kHalf2_Type,
38 kHalf3_Type,
39 kHalf4_Type,
40 kHalf2x2_Type,
41 kHalf3x2_Type,
42 kHalf4x2_Type,
43 kHalf2x3_Type,
44 kHalf3x3_Type,
45 kHalf4x3_Type,
46 kHalf2x4_Type,
47 kHalf3x4_Type,
48 kHalf4x4_Type,
49 kFloat_Type,
50 kFloat2_Type,
51 kFloat3_Type,
52 kFloat4_Type,
53 kFragmentProcessor_Type,
54 kFloat2x2_Type,
55 kFloat3x2_Type,
56 kFloat4x2_Type,
57 kFloat2x3_Type,
58 kFloat3x3_Type,
59 kFloat4x3_Type,
60 kFloat2x4_Type,
61 kFloat3x4_Type,
62 kFloat4x4_Type,
63 kInt_Type,
64 kInt2_Type,
65 kInt3_Type,
66 kInt4_Type,
67 kShader_Type,
68 kShort_Type,
69 kShort2_Type,
70 kShort3_Type,
71 kShort4_Type,
72 kUInt_Type,
73 kUInt2_Type,
74 kUInt3_Type,
75 kUInt4_Type,
76 kUShort_Type,
77 kUShort2_Type,
78 kUShort3_Type,
79 kUShort4_Type,
80 kVoid_Type,
81 kPoison_Type,
82 };
83
84 class DSLType {
85 public:
86 DSLType(TypeConstant tc, Position pos = {});
87
88 DSLType(const SkSL::Type* type, Position pos = {});
89
90 DSLType(std::string_view name, Position pos = {});
91
92 DSLType(std::string_view name,
93 DSLModifiers* modifiers,
94 Position pos = {});
95
96 static DSLType Invalid();
97
98 /**
99 * Returns true if the SkSL type is non-null.
100 */
hasValue()101 bool hasValue() const { return fSkSLType != nullptr; }
102
103 /**
104 * Returns true if this type is a bool.
105 */
106 bool isBoolean() const;
107
108 /**
109 * Returns true if this is a numeric scalar type.
110 */
111 bool isNumber() const;
112
113 /**
114 * Returns true if this is a floating-point scalar type (float or half).
115 */
116 bool isFloat() const;
117
118 /**
119 * Returns true if this is a signed scalar type (int or short).
120 */
121 bool isSigned() const;
122
123 /**
124 * Returns true if this is an unsigned scalar type (uint or ushort).
125 */
126 bool isUnsigned() const;
127
128 /**
129 * Returns true if this is a signed or unsigned integer.
130 */
131 bool isInteger() const;
132
133 /**
134 * Returns true if this is a scalar type.
135 */
136 bool isScalar() const;
137
138 /**
139 * Returns true if this is a vector type.
140 */
141 bool isVector() const;
142
143 /**
144 * Returns true if this is a matrix type.
145 */
146 bool isMatrix() const;
147
148 /**
149 * Returns true if this is a array type.
150 */
151 bool isArray() const;
152
153 /**
154 * Returns true if this is a struct type.
155 */
156 bool isStruct() const;
157
158 /**
159 * Returns true if this is a Skia object type (shader, colorFilter, blender).
160 */
161 bool isEffectChild() const;
162
163 template<typename... Args>
Construct(DSLType type,DSLVarBase & var,Args &&...args)164 static DSLExpression Construct(DSLType type, DSLVarBase& var, Args&&... args) {
165 DSLExpression argArray[] = {var, args...};
166 return Construct(type, SkSpan(argArray));
167 }
168
169 template<typename... Args>
Construct(DSLType type,DSLExpression expr,Args &&...args)170 static DSLExpression Construct(DSLType type, DSLExpression expr, Args&&... args) {
171 DSLExpression argArray[] = {std::move(expr), std::move(args)...};
172 return Construct(type, SkSpan(argArray));
173 }
174
175 static DSLExpression Construct(DSLType type, SkSpan<DSLExpression> argArray);
176
177 private:
skslType()178 const SkSL::Type& skslType() const {
179 SkASSERT(fSkSLType);
180 return *fSkSLType;
181 }
182
183 const SkSL::Type* fSkSLType = nullptr;
184
185 friend DSLType Array(const DSLType& base, int count, Position pos);
186 friend DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos);
187 friend DSLType StructType(std::string_view name,
188 SkSpan<DSLField> fields,
189 bool interfaceBlock,
190 Position pos);
191 friend DSLType UnsizedArray(const DSLType& base, Position pos);
192 friend class DSLCore;
193 friend class DSLFunction;
194 friend class DSLVarBase;
195 friend class DSLWriter;
196 friend class SkSL::Compiler;
197 };
198
199 #define TYPE(T) \
200 template<typename... Args> \
201 DSLExpression T(Args&&... args) { \
202 return DSLType::Construct(k ## T ## _Type, std::forward<Args>(args)...); \
203 }
204
205 #define VECTOR_TYPE(T) \
206 TYPE(T) \
207 TYPE(T ## 2) \
208 TYPE(T ## 3) \
209 TYPE(T ## 4)
210
211 #define MATRIX_TYPE(T) \
212 TYPE(T ## 2x2) \
213 TYPE(T ## 3x2) \
214 TYPE(T ## 4x2) \
215 TYPE(T ## 2x3) \
216 TYPE(T ## 3x3) \
217 TYPE(T ## 4x3) \
218 TYPE(T ## 2x4) \
219 TYPE(T ## 3x4) \
220 TYPE(T ## 4x4)
221
222 VECTOR_TYPE(Bool)
223 VECTOR_TYPE(Float)
224 VECTOR_TYPE(Half)
225 VECTOR_TYPE(Int)
226 VECTOR_TYPE(UInt)
227 VECTOR_TYPE(Short)
228 VECTOR_TYPE(UShort)
229
230 MATRIX_TYPE(Float)
231 MATRIX_TYPE(Half)
232
233 #undef TYPE
234 #undef VECTOR_TYPE
235 #undef MATRIX_TYPE
236
237 DSLType Array(const DSLType& base, int count, Position pos = {});
238
239 DSLType UnsizedArray(const DSLType& base, Position pos = {});
240
241 class DSLField {
242 public:
243 DSLField(const DSLType type, std::string_view name,
244 Position pos = {})
DSLField(DSLModifiers (),type,name,pos)245 : DSLField(DSLModifiers(), type, name, pos) {}
246
247 DSLField(const DSLModifiers& modifiers, const DSLType type, std::string_view name,
248 Position pos = {})
fModifiers(modifiers)249 : fModifiers(modifiers)
250 , fType(type)
251 , fName(name)
252 , fPosition(pos) {}
253
254 private:
255 DSLModifiers fModifiers;
256 const DSLType fType;
257 std::string_view fName;
258 Position fPosition;
259
260 friend class DSLCore;
261 friend DSLType StructType(std::string_view name,
262 SkSpan<DSLField> fields,
263 bool interfaceBlock,
264 Position pos);
265 };
266
267 /**
268 * Creates a StructDefinition at the top level and returns the associated type.
269 */
270 DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos = {});
271
272 template<typename... Field>
Struct(std::string_view name,Field...fields)273 DSLType Struct(std::string_view name, Field... fields) {
274 DSLField fieldTypes[] = {std::move(fields)...};
275 return Struct(name, SkSpan(fieldTypes), Position());
276 }
277
278 /**
279 * Creates a struct type and adds it to the current symbol table. Does _not_ create a ProgramElement
280 * at the top level, so the type will exist, but won't be represented anywhere in the output.
281 * (Use Struct or InterfaceBlock to add a top-level program element.)
282 */
283 DSLType StructType(std::string_view name,
284 SkSpan<DSLField> fields,
285 bool interfaceBlock,
286 Position pos);
287
288 } // namespace dsl
289
290 } // namespace SkSL
291
292 #endif
293