Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / sksl / ir / SkSLType.h
1 /*
2  * Copyright 2016 Google Inc.
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_TYPE
9 #define SKSL_TYPE
10
11 #include "include/private/SkSLModifiers.h"
12 #include "include/private/SkSLSymbol.h"
13 #include "src/sksl/SkSLUtil.h"
14 #include "src/sksl/spirv.h"
15 #include <algorithm>
16 #include <climits>
17 #include <string_view>
18 #include <vector>
19 #include <memory>
20
21 namespace SkSL {
22
23 class Context;
24 class SymbolTable;
25
26 struct CoercionCost {
27     static CoercionCost Free()              { return {    0,    0, false }; }
28     static CoercionCost Normal(int cost)    { return { cost,    0, false }; }
29     static CoercionCost Narrowing(int cost) { return {    0, cost, false }; }
30     static CoercionCost Impossible()        { return {    0,    0,  true }; }
31
32     bool isPossible(bool allowNarrowing) const {
33         return !fImpossible && (fNarrowingCost == 0 || allowNarrowing);
34     }
35
36     // Addition of two costs. Saturates at Impossible().
37     CoercionCost operator+(CoercionCost rhs) const {
38         if (fImpossible || rhs.fImpossible) {
39             return Impossible();
40         }
41         return { fNormalCost + rhs.fNormalCost, fNarrowingCost + rhs.fNarrowingCost, false };
42     }
43
44     bool operator<(CoercionCost rhs) const {
45         return std::tie(    fImpossible,     fNarrowingCost,     fNormalCost) <
46                std::tie(rhs.fImpossible, rhs.fNarrowingCost, rhs.fNormalCost);
47     }
48
49     int  fNormalCost;
50     int  fNarrowingCost;
51     bool fImpossible;
52 };
53
54 /**
55  * Represents a type, such as int or float4.
56  */
57 class Type : public Symbol {
58 public:
59     inline static constexpr Kind kSymbolKind = Kind::kType;
60     inline static constexpr int kMaxAbbrevLength = 3;
61
62     struct Field {
63         Field(Position pos, Modifiers modifiers, std::string_view name, const Type* type)
64         : fPosition(pos)
65         , fModifiers(modifiers)
66         , fName(name)
67         , fType(std::move(type)) {}
68
69         std::string description() const {
70             return fType->displayName() + " " + std::string(fName) + ";";
71         }
72
73         Position fPosition;
74         Modifiers fModifiers;
75         std::string_view fName;
76         const Type* fType;
77     };
78
79     enum class TypeKind : int8_t {
80         kArray,
81         kGeneric,
82         kLiteral,
83         kMatrix,
84         kOther,
85         kSampler,
86         kSeparateSampler,
87         kScalar,
88         kStruct,
89         kTexture,
90         kVector,
91         kVoid,
92
93         // Types that represent stages in the Skia pipeline
94         kColorFilter,
95         kShader,
96         kBlender,
97     };
98
99     enum class NumberKind : int8_t {
100         kFloat,
101         kSigned,
102         kUnsigned,
103         kBoolean,
104         kNonnumeric
105     };
106
107     Type(const Type& other) = delete;
108
109     /** Creates an array type. */
110     static std::unique_ptr<Type> MakeArrayType(std::string_view name, const Type& componentType,
111                                                int columns);
112
113     /** Converts a component type and a size (float, 10) into an array name ("float[10]"). */
114     std::string getArrayName(int arraySize) const;
115
116     /**
117      * Creates an alias which maps to another type.
118      */
119     static std::unique_ptr<Type> MakeAliasType(std::string_view name, const Type& targetType);
120
121     /**
122      * Create a generic type which maps to the listed types--e.g. $genType is a generic type which
123      * can match float, float2, float3 or float4.
124      */
125     static std::unique_ptr<Type> MakeGenericType(const char* name, std::vector<const Type*> types);
126
127     /** Create a type for literal scalars. */
128     static std::unique_ptr<Type> MakeLiteralType(const char* name, const Type& scalarType,
129                                                  int8_t priority);
130
131     /** Create a matrix type. */
132     static std::unique_ptr<Type> MakeMatrixType(std::string_view name, const char* abbrev,
133                                                 const Type& componentType, int columns,
134                                                 int8_t rows);
135
136     /** Create a sampler type. */
137     static std::unique_ptr<Type> MakeSamplerType(const char* name, const Type& textureType);
138
139     /** Create a scalar type. */
140     static std::unique_ptr<Type> MakeScalarType(std::string_view name, const char* abbrev,
141                                                 Type::NumberKind numberKind, int8_t priority,
142                                                 int8_t bitWidth);
143
144     /**
145      * Create a "special" type with the given name, abbreviation, and TypeKind.
146      */
147     static std::unique_ptr<Type> MakeSpecialType(const char* name, const char* abbrev,
148                                                  Type::TypeKind typeKind);
149
150     /** Creates a struct type with the given fields. */
151     static std::unique_ptr<Type> MakeStructType(Position pos,
152                                                 std::string_view name,
153                                                 std::vector<Field> fields,
154                                                 bool interfaceBlock = false);
155
156     /** Create a texture type. */
157     static std::unique_ptr<Type> MakeTextureType(const char* name, SpvDim_ dimensions,
158                                                  bool isDepth, bool isArrayedTexture,
159                                                  bool isMultisampled, bool isSampled);
160
161     /** Create a vector type. */
162     static std::unique_ptr<Type> MakeVectorType(std::string_view name, const char* abbrev,
163                                                 const Type& componentType, int columns);
164
165     template <typename T>
166     bool is() const {
167         return this->typeKind() == T::kTypeKind;
168     }
169
170     template <typename T>
171     const T& as() const {
172         SkASSERT(this->is<T>());
173         return static_cast<const T&>(*this);
174     }
175
176     template <typename T>
177     T& as() {
178         SkASSERT(this->is<T>());
179         return static_cast<T&>(*this);
180     }
181
182     /** Creates a clone of this Type, if needed, and inserts it into a different symbol table. */
183     const Type* clone(SymbolTable* symbolTable) const;
184
185     /**
186      * Returns true if this type is known to come from BuiltinTypes. If this returns true, the Type
187      * will always be available in the root SymbolTable and never needs to be copied to migrate an
188      * Expression from one location to another. If it returns false, the Type might not exist in a
189      * separate SymbolTable and you'll need to consider copying it.
190      */
191     bool isInBuiltinTypes() const {
192         return !(this->isArray() || this->isStruct());
193     }
194
195     std::string displayName() const {
196         return std::string(this->scalarTypeForLiteral().name());
197     }
198
199     std::string description() const override {
200         return this->displayName();
201     }
202
203     /** Returns true if the program supports this type. Strict ES2 programs can't use ES3 types. */
204     bool isAllowedInES2(const Context& context) const;
205
206     /** Returns true if this type is legal to use in a strict-ES2 program. */
207     virtual bool isAllowedInES2() const {
208         return true;
209     }
210
211     /** Returns true if this type is either private, or contains a private field (recursively). */
212     virtual bool isPrivate() const;
213
214     /** If this is an alias, returns the underlying type, otherwise returns this. */
215     virtual const Type& resolve() const {
216         return *this;
217     }
218
219     /** Returns true if these types are equal after alias resolution. */
220     bool matches(const Type& other) const {
221         return this->resolve().name() == other.resolve().name();
222     }
223
224     /**
225      * Returns an abbreviated name of the type, meant for name-mangling. (e.g. float4x4 -> f44)
226      */
227     const char* abbreviatedName() const {
228         return fAbbreviatedName;
229     }
230
231     /**
232      * Returns the category (scalar, vector, matrix, etc.) of this type.
233      */
234     TypeKind typeKind() const {
235         return fTypeKind;
236     }
237
238     /**
239      * Returns the NumberKind of this type (always kNonnumeric for non-scalar values).
240      */
241     virtual NumberKind numberKind() const {
242         return NumberKind::kNonnumeric;
243     }
244
245     /**
246      * Returns true if this type is a bool.
247      */
248     bool isBoolean() const {
249         return this->numberKind() == NumberKind::kBoolean;
250     }
251
252     /**
253      * Returns true if this is a numeric scalar type.
254      */
255     bool isNumber() const {
256         switch (this->numberKind()) {
257             case NumberKind::kFloat:
258             case NumberKind::kSigned:
259             case NumberKind::kUnsigned:
260                 return true;
261             default:
262                 return false;
263         }
264     }
265
266     /**
267      * Returns true if this is a floating-point scalar type (float or half).
268      */
269     bool isFloat() const {
270         return this->numberKind() == NumberKind::kFloat;
271     }
272
273     /**
274      * Returns true if this is a signed scalar type (int or short).
275      */
276     bool isSigned() const {
277         return this->numberKind() == NumberKind::kSigned;
278     }
279
280     /**
281      * Returns true if this is an unsigned scalar type (uint or ushort).
282      */
283     bool isUnsigned() const {
284         return this->numberKind() == NumberKind::kUnsigned;
285     }
286
287     /**
288      * Returns true if this is a signed or unsigned integer.
289      */
290     bool isInteger() const {
291         switch (this->numberKind()) {
292             case NumberKind::kSigned:
293             case NumberKind::kUnsigned:
294                 return true;
295             default:
296                 return false;
297         }
298     }
299
300     /**
301      * Returns true if this is an "opaque type" (an external object which the shader references in
302      * some fashion). https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Opaque_types
303      */
304     bool isOpaque() const {
305         switch (fTypeKind) {
306             case TypeKind::kBlender:
307             case TypeKind::kColorFilter:
308             case TypeKind::kSampler:
309             case TypeKind::kSeparateSampler:
310             case TypeKind::kShader:
311             case TypeKind::kTexture:
312                 return true;
313             default:
314                 return false;
315         }
316     }
317
318     /**
319      * Returns the "priority" of a number type, in order of float > half > int > short.
320      * When operating on two number types, the result is the higher-priority type.
321      */
322     virtual int priority() const {
323         SkDEBUGFAIL("not a number type");
324         return -1;
325     }
326
327     /**
328      * Returns true if an instance of this type can be freely coerced (implicitly converted) to
329      * another type.
330      */
331     bool canCoerceTo(const Type& other, bool allowNarrowing) const {
332         return this->coercionCost(other).isPossible(allowNarrowing);
333     }
334
335     /**
336      * Determines the "cost" of coercing (implicitly converting) this type to another type. The cost
337      * is a number with no particular meaning other than that lower costs are preferable to higher
338      * costs. Returns INT_MAX if the coercion is not possible.
339      */
340     CoercionCost coercionCost(const Type& other) const;
341
342     /**
343      * For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component
344      * type of Float). For arrays, returns the base type. For all other types, returns the type
345      * itself.
346      */
347     virtual const Type& componentType() const {
348         return *this;
349     }
350
351     /**
352      * For texturesamplers, returns the type of texture it samples (e.g., sampler2D has
353      * a texture type of texture2D).
354      */
355     virtual const Type& textureType() const {
356         SkDEBUGFAIL("not a texture type");
357         return *this;
358     }
359
360     /**
361      * For matrices and vectors, returns the number of columns (e.g. both mat3 and float3 return 3).
362      * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1.
363      * For all other types, causes an assertion failure.
364      */
365     virtual int columns() const {
366         SkDEBUGFAIL("type does not have columns");
367         return -1;
368     }
369
370     /**
371      * For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vectors and scalars,
372      * returns 1. For all other types, causes an assertion failure.
373      */
374     virtual int rows() const {
375         SkDEBUGFAIL("type does not have rows");
376         return -1;
377     }
378
379     /** For integer types, returns the minimum value that can fit in the type. */
380     int64_t minimumValue() const {
381         SkASSERT(this->isInteger());
382         constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
383         return this->isUnsigned() ? 0 : -(k1 << (this->bitWidth() - 1));
384     }
385
386     /** For integer types, returns the maximum value that can fit in the type. */
387     int64_t maximumValue() const {
388         SkASSERT(this->isInteger());
389         constexpr int64_t k1 = 1;  // ensures that `1 << n` is evaluated as 64-bit
390         return (this->isUnsigned() ? (k1 << this->bitWidth())
391                                    : (k1 << (this->bitWidth() - 1))) - 1;
392     }
393
394     /**
395      * Returns the number of scalars needed to hold this type.
396      */
397     virtual size_t slotCount() const {
398         return 0;
399     }
400
401     virtual const std::vector<Field>& fields() const {
402         SK_ABORT("Internal error: not a struct");
403     }
404
405     /**
406      * For generic types, returns the types that this generic type can substitute for.
407      */
408     virtual const std::vector<const Type*>& coercibleTypes() const {
409         SK_ABORT("Internal error: not a generic type");
410     }
411
412     virtual SpvDim_ dimensions() const {
413         SkASSERT(false);
414         return SpvDim1D;
415     }
416
417     virtual bool isDepth() const {
418         SkASSERT(false);
419         return false;
420     }
421
422     virtual bool isArrayedTexture() const {
423         SkASSERT(false);
424         return false;
425     }
426
427     bool isVoid() const {
428         return fTypeKind == TypeKind::kVoid;
429     }
430
431     virtual bool isScalar() const {
432         return false;
433     }
434
435     virtual bool isLiteral() const {
436         return false;
437     }
438
439     virtual const Type& scalarTypeForLiteral() const {
440         return *this;
441     }
442
443     virtual bool isVector() const {
444         return false;
445     }
446
447     virtual bool isMatrix() const {
448         return false;
449     }
450
451     virtual bool isArray() const {
452         return false;
453     }
454
455     virtual bool isStruct() const {
456         return false;
457     }
458
459     virtual bool isInterfaceBlock() const {
460         return false;
461     }
462
463     // Is this type something that can be bound & sampled from an SkRuntimeEffect?
464     // Includes types that represent stages of the Skia pipeline (colorFilter, shader, blender).
465     bool isEffectChild() const {
466         return fTypeKind == TypeKind::kColorFilter ||
467                fTypeKind == TypeKind::kShader ||
468                fTypeKind == TypeKind::kBlender;
469     }
470
471     virtual bool isMultisampled() const {
472         SkASSERT(false);
473         return false;
474     }
475
476     virtual bool isSampled() const {
477         SkASSERT(false);
478         return false;
479     }
480
481     bool hasPrecision() const {
482         return this->componentType().isNumber() || fTypeKind == TypeKind::kSampler;
483     }
484
485     bool highPrecision() const {
486         return this->bitWidth() >= 32;
487     }
488
489     virtual int bitWidth() const {
490         return 0;
491     }
492
493     bool isOrContainsArray() const;
494
495     /**
496      * Returns true if this type is a struct that is too deeply nested.
497      */
498     bool isTooDeeplyNested() const;
499
500     /**
501      * Returns the corresponding vector or matrix type with the specified number of columns and
502      * rows.
503      */
504     const Type& toCompound(const Context& context, int columns, int rows) const;
505
506     /**
507      * Returns a type which honors the precision qualifiers set in Modifiers. e.g., kMediump_Flag
508      * when applied to `float2` will return `half2`. Generates an error if the precision qualifiers
509      * don't make sense, e.g. `highp bool` or `mediump MyStruct`.
510      */
511     const Type* applyPrecisionQualifiers(const Context& context,
512                                          Modifiers* modifiers,
513                                          SymbolTable* symbols,
514                                          Position pos) const;
515
516     /**
517      * Coerces the passed-in expression to this type. If the types are incompatible, reports an
518      * error and returns null.
519      */
520     std::unique_ptr<Expression> coerceExpression(std::unique_ptr<Expression> expr,
521                                                  const Context& context) const;
522
523     /** Detects any IntLiterals in the expression which can't fit in this type. */
524     bool checkForOutOfRangeLiteral(const Context& context, const Expression& expr) const;
525
526     /** Checks if `value` can fit in this type. The type must be scalar. */
527     bool checkForOutOfRangeLiteral(const Context& context, double value, Position pos) const;
528
529     /**
530      * Verifies that the expression is a valid constant array size for this type. Returns the array
531      * size, or zero if the expression isn't a valid literal value.
532      */
533     SKSL_INT convertArraySize(const Context& context, Position arrayPos,
534             std::unique_ptr<Expression> size) const;
535
536 protected:
537     Type(std::string_view name, const char* abbrev, TypeKind kind,
538             Position pos = Position())
539         : INHERITED(pos, kSymbolKind, name)
540         , fTypeKind(kind) {
541         SkASSERT(strlen(abbrev) <= kMaxAbbrevLength);
542         strcpy(fAbbreviatedName, abbrev);
543     }
544
545 private:
546     bool isTooDeeplyNested(int limit) const;
547
548     using INHERITED = Symbol;
549
550     char fAbbreviatedName[kMaxAbbrevLength + 1] = {};
551     TypeKind fTypeKind;
552 };
553
554 }  // namespace SkSL
555
556 #endif