• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/private/SkSLDefines.h"
12 #include "src/sksl/SkSLContext.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 'float3(1, 2, 3).zyx'.
21  */
22 struct Swizzle final : public Expression {
23     inline static constexpr Kind kExpressionKind = Kind::kSwizzle;
24 
Swizzlefinal25     Swizzle(const Context& context, std::unique_ptr<Expression> base,
26             const ComponentArray& components)
27             : INHERITED(base->fLine, 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 
34     // Swizzle::Convert permits component arrays containing ZERO or ONE, does typechecking, reports
35     // errors via ErrorReporter, and returns an expression that combines constructors and native
36     // swizzles (comprised solely of X/Y/W/Z).
37     static std::unique_ptr<Expression> Convert(const Context& context,
38                                                std::unique_ptr<Expression> base,
39                                                ComponentArray inComponents);
40 
41     static std::unique_ptr<Expression> Convert(const Context& context,
42                                                std::unique_ptr<Expression> base,
43                                                skstd::string_view maskString);
44 
45     // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are
46     // reported via ASSERT.
47     static std::unique_ptr<Expression> Make(const Context& context,
48                                             std::unique_ptr<Expression> expr,
49                                             ComponentArray inComponents);
50 
basefinal51     std::unique_ptr<Expression>& base() {
52         return fBase;
53     }
54 
basefinal55     const std::unique_ptr<Expression>& base() const {
56         return fBase;
57     }
58 
componentsfinal59     const ComponentArray& components() const {
60         return fComponents;
61     }
62 
hasPropertyfinal63     bool hasProperty(Property property) const override {
64         return this->base()->hasProperty(property);
65     }
66 
clonefinal67     std::unique_ptr<Expression> clone() const override {
68         return std::unique_ptr<Expression>(new Swizzle(&this->type(), this->base()->clone(),
69                                                        this->components()));
70     }
71 
descriptionfinal72     String description() const override {
73         String result = this->base()->description() + ".";
74         for (int x : this->components()) {
75             result += "xyzw"[x];
76         }
77         return result;
78     }
79 
80 private:
Swizzlefinal81     Swizzle(const Type* type, std::unique_ptr<Expression> base, const ComponentArray& components)
82         : INHERITED(base->fLine, kExpressionKind, type)
83         , fBase(std::move(base))
84         , fComponents(components) {
85         SkASSERT(this->components().size() >= 1 && this->components().size() <= 4);
86     }
87 
88     std::unique_ptr<Expression> fBase;
89     ComponentArray fComponents;
90 
91     using INHERITED = Expression;
92 };
93 
94 }  // namespace SkSL
95 
96 #endif
97