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 "SkSLContext.h" 12#include "SkSLExpression.h" 13#include "SkSLUtil.h" 14 15namespace SkSL { 16 17/** 18 * Given a type and a swizzle component count, returns the type that will result from swizzling. For 19 * instance, swizzling a vec3 with two components will result in a vec2. It is possible to swizzle 20 * with more components than the source vector, as in 'vec2(1).xxxx'. 21 */ 22static const Type& get_type(const Context& context, Expression& value, size_t count) { 23 const Type& base = value.fType.componentType(); 24 if (count == 1) { 25 return base; 26 } 27 if (base == *context.fFloat_Type) { 28 switch (count) { 29 case 2: return *context.fVec2_Type; 30 case 3: return *context.fVec3_Type; 31 case 4: return *context.fVec4_Type; 32 } 33 } else if (base == *context.fDouble_Type) { 34 switch (count) { 35 case 2: return *context.fDVec2_Type; 36 case 3: return *context.fDVec3_Type; 37 case 4: return *context.fDVec4_Type; 38 } 39 } else if (base == *context.fInt_Type) { 40 switch (count) { 41 case 2: return *context.fIVec2_Type; 42 case 3: return *context.fIVec3_Type; 43 case 4: return *context.fIVec4_Type; 44 } 45 } else if (base == *context.fUInt_Type) { 46 switch (count) { 47 case 2: return *context.fUVec2_Type; 48 case 3: return *context.fUVec3_Type; 49 case 4: return *context.fUVec4_Type; 50 } 51 } else if (base == *context.fBool_Type) { 52 switch (count) { 53 case 2: return *context.fBVec2_Type; 54 case 3: return *context.fBVec3_Type; 55 case 4: return *context.fBVec4_Type; 56 } 57 } 58 ABORT("cannot swizzle %s\n", value.description().c_str()); 59} 60 61/** 62 * Represents a vector swizzle operation such as 'vec2(1, 2, 3).zyx'. 63 */ 64struct Swizzle : public Expression { 65 Swizzle(const Context& context, std::unique_ptr<Expression> base, std::vector<int> components) 66 : INHERITED(base->fPosition, kSwizzle_Kind, get_type(context, *base, components.size())) 67 , fBase(std::move(base)) 68 , fComponents(std::move(components)) { 69 ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4); 70 } 71 72 SkString description() const override { 73 SkString result = fBase->description() + "."; 74 for (int x : fComponents) { 75 result += "xyzw"[x]; 76 } 77 return result; 78 } 79 80 std::unique_ptr<Expression> fBase; 81 const std::vector<int> fComponents; 82 83 typedef Expression INHERITED; 84}; 85 86} // namespace 87 88#endif 89