/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SKSL_DSL_TYPE #define SKSL_DSL_TYPE #include "include/sksl/DSLExpression.h" #include "include/sksl/DSLModifiers.h" #include namespace SkSL { class Type; namespace dsl { class DSLExpression; class DSLField; enum TypeConstant : uint8_t { kBool_Type, kBool2_Type, kBool3_Type, kBool4_Type, kHalf_Type, kHalf2_Type, kHalf3_Type, kHalf4_Type, kHalf2x2_Type, kHalf3x2_Type, kHalf4x2_Type, kHalf2x3_Type, kHalf3x3_Type, kHalf4x3_Type, kHalf2x4_Type, kHalf3x4_Type, kHalf4x4_Type, kFloat_Type, kFloat2_Type, kFloat3_Type, kFloat4_Type, kFragmentProcessor_Type, kFloat2x2_Type, kFloat3x2_Type, kFloat4x2_Type, kFloat2x3_Type, kFloat3x3_Type, kFloat4x3_Type, kFloat2x4_Type, kFloat3x4_Type, kFloat4x4_Type, kInt_Type, kInt2_Type, kInt3_Type, kInt4_Type, kShader_Type, kShort_Type, kShort2_Type, kShort3_Type, kShort4_Type, kUInt_Type, kUInt2_Type, kUInt3_Type, kUInt4_Type, kUShort_Type, kUShort2_Type, kUShort3_Type, kUShort4_Type, kVoid_Type, }; class DSLType { public: DSLType(TypeConstant tc) : fTypeConstant(tc) {} DSLType(const SkSL::Type* type) : fSkSLType(type) {} /** * Returns true if this type is a bool. */ bool isBoolean() const; /** * Returns true if this is a numeric scalar type. */ bool isNumber() const; /** * Returns true if this is a floating-point scalar type (float or half). */ bool isFloat() const; /** * Returns true if this is a signed scalar type (int or short). */ bool isSigned() const; /** * Returns true if this is an unsigned scalar type (uint or ushort). */ bool isUnsigned() const; /** * Returns true if this is a signed or unsigned integer. */ bool isInteger() const; /** * Returns true if this is a scalar type. */ bool isScalar() const; /** * Returns true if this is a vector type. */ bool isVector() const; /** * Returns true if this is a matrix type. */ bool isMatrix() const; /** * Returns true if this is a array type. */ bool isArray() const; /** * Returns true if this is a struct type. */ bool isStruct() const; template static DSLExpression Construct(DSLType type, Args&&... args) { SkTArray argArray; argArray.reserve_back(sizeof...(args)); CollectArgs(argArray, std::forward(args)...); return Construct(type, std::move(argArray)); } static DSLExpression Construct(DSLType type, SkTArray argArray); private: const SkSL::Type& skslType() const; const SkSL::Type* fSkSLType = nullptr; static void CollectArgs(SkTArray& args) {} template static void CollectArgs(SkTArray& args, DSLVar& var, RemainingArgs&&... remaining) { args.push_back(var); CollectArgs(args, std::forward(remaining)...); } template static void CollectArgs(SkTArray& args, DSLExpression expr, RemainingArgs&&... remaining) { args.push_back(std::move(expr)); CollectArgs(args, std::forward(remaining)...); } TypeConstant fTypeConstant; friend DSLType Array(const DSLType& base, int count); friend DSLType Struct(const char* name, SkTArray fields); friend class DSLFunction; friend class DSLVar; friend class DSLWriter; }; #define TYPE(T) \ template \ DSLExpression T(Args&&... args) { \ return DSLType::Construct(k ## T ## _Type, std::forward(args)...); \ } #define VECTOR_TYPE(T) \ TYPE(T) \ TYPE(T ## 2) \ TYPE(T ## 3) \ TYPE(T ## 4) #define MATRIX_TYPE(T) \ TYPE(T ## 2x2) \ TYPE(T ## 3x2) \ TYPE(T ## 4x2) \ TYPE(T ## 2x3) \ TYPE(T ## 3x3) \ TYPE(T ## 4x3) \ TYPE(T ## 2x4) \ TYPE(T ## 3x4) \ TYPE(T ## 4x4) VECTOR_TYPE(Bool) VECTOR_TYPE(Float) VECTOR_TYPE(Half) VECTOR_TYPE(Int) VECTOR_TYPE(UInt) VECTOR_TYPE(Short) VECTOR_TYPE(UShort) MATRIX_TYPE(Float) MATRIX_TYPE(Half) #undef TYPE #undef VECTOR_TYPE #undef MATRIX_TYPE DSLType Array(const DSLType& base, int count); class DSLField { public: DSLField(const DSLType type, const char* name) : DSLField(DSLModifiers(), type, name) {} private: DSLField(DSLModifiers modifiers, const DSLType type, const char* name) : fModifiers(modifiers) , fType(type) , fName(name) {} DSLModifiers fModifiers; const DSLType fType; const char* fName; friend DSLType Struct(const char* name, SkTArray fields); }; DSLType Struct(const char* name, SkTArray fields); template DSLType Struct(const char* name, Field... fields) { SkTArray fieldTypes; fieldTypes.reserve_back(sizeof...(fields)); // in C++17, we could just do: // (fieldTypes.push_back(std::move(fields)), ...); int unused[] = {0, (fieldTypes.push_back(std::move(fields)), 0)...}; static_cast(unused); return Struct(name, std::move(fieldTypes)); } } // namespace dsl } // namespace SkSL #endif