1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SKSL_SWIZZLE 9cb93a386Sopenharmony_ci#define SKSL_SWIZZLE 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/private/SkSLDefines.h" 12cb93a386Sopenharmony_ci#include "src/sksl/SkSLContext.h" 13cb93a386Sopenharmony_ci#include "src/sksl/SkSLUtil.h" 14cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructor.h" 15cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLExpression.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cinamespace SkSL { 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci/** 20cb93a386Sopenharmony_ci * Represents a vector swizzle operation such as 'float3(1, 2, 3).zyx'. 21cb93a386Sopenharmony_ci */ 22cb93a386Sopenharmony_cistruct Swizzle final : public Expression { 23cb93a386Sopenharmony_ci inline static constexpr Kind kExpressionKind = Kind::kSwizzle; 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci Swizzle(const Context& context, std::unique_ptr<Expression> base, 26cb93a386Sopenharmony_ci const ComponentArray& components) 27cb93a386Sopenharmony_ci : INHERITED(base->fLine, kExpressionKind, 28cb93a386Sopenharmony_ci &base->type().componentType().toCompound(context, components.size(), 1)) 29cb93a386Sopenharmony_ci , fBase(std::move(base)) 30cb93a386Sopenharmony_ci , fComponents(components) { 31cb93a386Sopenharmony_ci SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci // Swizzle::Convert permits component arrays containing ZERO or ONE, does typechecking, reports 35cb93a386Sopenharmony_ci // errors via ErrorReporter, and returns an expression that combines constructors and native 36cb93a386Sopenharmony_ci // swizzles (comprised solely of X/Y/W/Z). 37cb93a386Sopenharmony_ci static std::unique_ptr<Expression> Convert(const Context& context, 38cb93a386Sopenharmony_ci std::unique_ptr<Expression> base, 39cb93a386Sopenharmony_ci ComponentArray inComponents); 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci static std::unique_ptr<Expression> Convert(const Context& context, 42cb93a386Sopenharmony_ci std::unique_ptr<Expression> base, 43cb93a386Sopenharmony_ci skstd::string_view maskString); 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are 46cb93a386Sopenharmony_ci // reported via ASSERT. 47cb93a386Sopenharmony_ci static std::unique_ptr<Expression> Make(const Context& context, 48cb93a386Sopenharmony_ci std::unique_ptr<Expression> expr, 49cb93a386Sopenharmony_ci ComponentArray inComponents); 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci std::unique_ptr<Expression>& base() { 52cb93a386Sopenharmony_ci return fBase; 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci const std::unique_ptr<Expression>& base() const { 56cb93a386Sopenharmony_ci return fBase; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci const ComponentArray& components() const { 60cb93a386Sopenharmony_ci return fComponents; 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci bool hasProperty(Property property) const override { 64cb93a386Sopenharmony_ci return this->base()->hasProperty(property); 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci std::unique_ptr<Expression> clone() const override { 68cb93a386Sopenharmony_ci return std::unique_ptr<Expression>(new Swizzle(&this->type(), this->base()->clone(), 69cb93a386Sopenharmony_ci this->components())); 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci String description() const override { 73cb93a386Sopenharmony_ci String result = this->base()->description() + "."; 74cb93a386Sopenharmony_ci for (int x : this->components()) { 75cb93a386Sopenharmony_ci result += "xyzw"[x]; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci return result; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ciprivate: 81cb93a386Sopenharmony_ci Swizzle(const Type* type, std::unique_ptr<Expression> base, const ComponentArray& components) 82cb93a386Sopenharmony_ci : INHERITED(base->fLine, kExpressionKind, type) 83cb93a386Sopenharmony_ci , fBase(std::move(base)) 84cb93a386Sopenharmony_ci , fComponents(components) { 85cb93a386Sopenharmony_ci SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ci std::unique_ptr<Expression> fBase; 89cb93a386Sopenharmony_ci ComponentArray fComponents; 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci using INHERITED = Expression; 92cb93a386Sopenharmony_ci}; 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci} // namespace SkSL 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci#endif 97