Line data Source code
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 :
15 : namespace 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 : */
22 0 : static const Type& get_type(const Context& context, Expression& value, size_t count) {
23 0 : const Type& base = value.fType.componentType();
24 0 : if (count == 1) {
25 0 : return base;
26 : }
27 0 : if (base == *context.fFloat_Type) {
28 0 : switch (count) {
29 0 : case 2: return *context.fVec2_Type;
30 0 : case 3: return *context.fVec3_Type;
31 0 : case 4: return *context.fVec4_Type;
32 : }
33 0 : } else if (base == *context.fDouble_Type) {
34 0 : switch (count) {
35 0 : case 2: return *context.fDVec2_Type;
36 0 : case 3: return *context.fDVec3_Type;
37 0 : case 4: return *context.fDVec4_Type;
38 : }
39 0 : } else if (base == *context.fInt_Type) {
40 0 : switch (count) {
41 0 : case 2: return *context.fIVec2_Type;
42 0 : case 3: return *context.fIVec3_Type;
43 0 : case 4: return *context.fIVec4_Type;
44 : }
45 0 : } else if (base == *context.fUInt_Type) {
46 0 : switch (count) {
47 0 : case 2: return *context.fUVec2_Type;
48 0 : case 3: return *context.fUVec3_Type;
49 0 : case 4: return *context.fUVec4_Type;
50 : }
51 0 : } else if (base == *context.fBool_Type) {
52 0 : switch (count) {
53 0 : case 2: return *context.fBVec2_Type;
54 0 : case 3: return *context.fBVec3_Type;
55 0 : case 4: return *context.fBVec4_Type;
56 : }
57 : }
58 0 : 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 : */
64 0 : struct Swizzle : public Expression {
65 0 : Swizzle(const Context& context, std::unique_ptr<Expression> base, std::vector<int> components)
66 0 : : INHERITED(base->fPosition, kSwizzle_Kind, get_type(context, *base, components.size()))
67 0 : , fBase(std::move(base))
68 0 : , fComponents(std::move(components)) {
69 0 : ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
70 0 : }
71 :
72 0 : String description() const override {
73 0 : String result = fBase->description() + ".";
74 0 : for (int x : fComponents) {
75 0 : result += "xyzw"[x];
76 : }
77 0 : 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
|