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 "src/sksl/SkSLContext.h" 12 #include "src/sksl/SkSLIRGenerator.h" 13 #include "src/sksl/SkSLUtil.h" 14 #include "src/sksl/ir/SkSLConstructor.h" 15 #include "src/sksl/ir/SkSLExpression.h" 16 17 namespace SkSL { 18 19 /** 20 * Represents a vector swizzle operation such as 'float2(1, 2, 3).zyx'. 21 */ 22 struct Swizzle final : public Expression { 23 static constexpr Kind kExpressionKind = Kind::kSwizzle; 24 Swizzlefinal25 Swizzle(const Context& context, std::unique_ptr<Expression> base, 26 const ComponentArray& components) 27 : INHERITED(base->fOffset, kExpressionKind, 28 &base->type().componentType().toCompound(context, components.size(), 1)) 29 , fBase(std::move(base)) 30 , fComponents(components) { 31 SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); 32 } 33 basefinal34 std::unique_ptr<Expression>& base() { 35 return fBase; 36 } 37 basefinal38 const std::unique_ptr<Expression>& base() const { 39 return fBase; 40 } 41 componentsfinal42 const ComponentArray& components() const { 43 return fComponents; 44 } 45 constantPropagatefinal46 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator, 47 const DefinitionMap& definitions) override { 48 if (this->base()->is<Constructor>()) { 49 Constructor& constructor = this->base()->as<Constructor>(); 50 if (constructor.isCompileTimeConstant()) { 51 // we're swizzling a constant vector, e.g. float4(1).x. Simplify it. 52 const Type& type = this->type(); 53 if (type.isInteger()) { 54 SkASSERT(this->components().size() == 1); 55 int64_t value = constructor.getIVecComponent(this->components()[0]); 56 return std::make_unique<IntLiteral>(irGenerator.fContext, constructor.fOffset, 57 value); 58 } else if (type.isFloat()) { 59 SkASSERT(this->components().size() == 1); 60 SKSL_FLOAT value = constructor.getFVecComponent(this->components()[0]); 61 return std::make_unique<FloatLiteral>(irGenerator.fContext, constructor.fOffset, 62 value); 63 } 64 } 65 } 66 return nullptr; 67 } 68 hasPropertyfinal69 bool hasProperty(Property property) const override { 70 return this->base()->hasProperty(property); 71 } 72 clonefinal73 std::unique_ptr<Expression> clone() const override { 74 return std::unique_ptr<Expression>(new Swizzle(&this->type(), this->base()->clone(), 75 this->components())); 76 } 77 descriptionfinal78 String description() const override { 79 String result = this->base()->description() + "."; 80 for (int x : this->components()) { 81 result += "xyzw"[x]; 82 } 83 return result; 84 } 85 86 private: Swizzlefinal87 Swizzle(const Type* type, std::unique_ptr<Expression> base, const ComponentArray& components) 88 : INHERITED(base->fOffset, kExpressionKind, 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