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_SWIZZLE 9 #define SKSL_SWIZZLE 10 11 #include "include/core/SkTypes.h" 12 #include "include/private/SkSLDefines.h" 13 #include "include/private/SkSLIRNode.h" 14 #include "include/sksl/SkSLPosition.h" 15 #include "src/sksl/ir/SkSLExpression.h" 16 #include "src/sksl/ir/SkSLType.h" 17 18 #include <cstdint> 19 #include <memory> 20 #include <string> 21 #include <string_view> 22 #include <utility> 23 24 namespace SkSL { 25 26 class Context; 27 enum class OperatorPrecedence : uint8_t; 28 29 /** 30 * Represents a vector swizzle operation such as 'float3(1, 2, 3).zyx'. 31 */ 32 struct Swizzle final : public Expression { 33 inline static constexpr Kind kIRNodeKind = Kind::kSwizzle; 34 Swizzlefinal35 Swizzle(const Context& context, Position pos, std::unique_ptr<Expression> base, 36 const ComponentArray& components) 37 : INHERITED(pos, kIRNodeKind, 38 &base->type().componentType().toCompound(context, components.size(), 1)) 39 , fBase(std::move(base)) 40 , fComponents(components) { 41 SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); 42 } 43 44 // Swizzle::Convert permits component arrays containing ZERO or ONE, does typechecking, reports 45 // errors via ErrorReporter, and returns an expression that combines constructors and native 46 // swizzles (comprised solely of X/Y/W/Z). 47 static std::unique_ptr<Expression> Convert(const Context& context, 48 Position pos, 49 Position maskPos, 50 std::unique_ptr<Expression> base, 51 ComponentArray inComponents); 52 53 static std::unique_ptr<Expression> Convert(const Context& context, 54 Position pos, 55 Position maskPos, 56 std::unique_ptr<Expression> base, 57 std::string_view maskString); 58 59 // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are 60 // reported via ASSERT. 61 static std::unique_ptr<Expression> Make(const Context& context, 62 Position pos, 63 std::unique_ptr<Expression> expr, 64 ComponentArray inComponents); 65 basefinal66 std::unique_ptr<Expression>& base() { 67 return fBase; 68 } 69 basefinal70 const std::unique_ptr<Expression>& base() const { 71 return fBase; 72 } 73 componentsfinal74 const ComponentArray& components() const { 75 return fComponents; 76 } 77 clonefinal78 std::unique_ptr<Expression> clone(Position pos) const override { 79 return std::unique_ptr<Expression>(new Swizzle(pos, &this->type(), this->base()->clone(), 80 this->components())); 81 } 82 83 std::string description(OperatorPrecedence) const override; 84 85 private: Swizzlefinal86 Swizzle(Position pos, const Type* type, std::unique_ptr<Expression> base, 87 const ComponentArray& components) 88 : INHERITED(pos, kIRNodeKind, type) 89 , fBase(std::move(base)) 90 , fComponents(components) { 91 SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); 92 } 93 94 std::unique_ptr<Expression> fBase; 95 ComponentArray fComponents; 96 97 using INHERITED = Expression; 98 }; 99 100 } // namespace SkSL 101 102 #endif 103