• 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/core/SkTypes.h"
12 #include "include/private/SkSLDefines.h"
13 #include "include/private/SkSLIRNode.h"
14 #include "include/sksl/SkSLPosition.h"
15 #include "src/sksl/ir/SkSLExpression.h"
16 #include "src/sksl/ir/SkSLType.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <string_view>
22 #include <utility>
23 
24 namespace SkSL {
25 
26 class Context;
27 enum class OperatorPrecedence : uint8_t;
28 
29 /**
30  * Represents a vector swizzle operation such as 'float3(1, 2, 3).zyx'.
31  */
32 struct Swizzle final : public Expression {
33     inline static constexpr Kind kIRNodeKind = Kind::kSwizzle;
34 
Swizzlefinal35     Swizzle(const Context& context, Position pos, std::unique_ptr<Expression> base,
36             const ComponentArray& components)
37             : INHERITED(pos, kIRNodeKind,
38                         &base->type().componentType().toCompound(context, components.size(), 1))
39             , fBase(std::move(base))
40             , fComponents(components) {
41         SkASSERT(this->components().size() >= 1 && this->components().size() <= 4);
42     }
43 
44     // Swizzle::Convert permits component arrays containing ZERO or ONE, does typechecking, reports
45     // errors via ErrorReporter, and returns an expression that combines constructors and native
46     // swizzles (comprised solely of X/Y/W/Z).
47     static std::unique_ptr<Expression> Convert(const Context& context,
48                                                Position pos,
49                                                Position maskPos,
50                                                std::unique_ptr<Expression> base,
51                                                ComponentArray inComponents);
52 
53     static std::unique_ptr<Expression> Convert(const Context& context,
54                                                Position pos,
55                                                Position maskPos,
56                                                std::unique_ptr<Expression> base,
57                                                std::string_view maskString);
58 
59     // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are
60     // reported via ASSERT.
61     static std::unique_ptr<Expression> Make(const Context& context,
62                                             Position pos,
63                                             std::unique_ptr<Expression> expr,
64                                             ComponentArray inComponents);
65 
basefinal66     std::unique_ptr<Expression>& base() {
67         return fBase;
68     }
69 
basefinal70     const std::unique_ptr<Expression>& base() const {
71         return fBase;
72     }
73 
componentsfinal74     const ComponentArray& components() const {
75         return fComponents;
76     }
77 
clonefinal78     std::unique_ptr<Expression> clone(Position pos) const override {
79         return std::unique_ptr<Expression>(new Swizzle(pos, &this->type(), this->base()->clone(),
80                                                        this->components()));
81     }
82 
83     std::string description(OperatorPrecedence) const override;
84 
85 private:
Swizzlefinal86     Swizzle(Position pos, const Type* type, std::unique_ptr<Expression> base,
87             const ComponentArray& components)
88         : INHERITED(pos, kIRNodeKind, 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