ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 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 | */ |
Ethan Nicholas | 0df1b04 | 2017-03-31 13:56:23 -0400 | [diff] [blame] | 7 | |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 8 | #ifndef SKSL_SWIZZLE |
| 9 | #define SKSL_SWIZZLE |
| 10 | |
Ethan Nicholas | daed259 | 2021-03-04 14:30:25 -0500 | [diff] [blame] | 11 | #include "include/private/SkSLDefines.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 12 | #include "src/sksl/SkSLContext.h" |
| 13 | #include "src/sksl/SkSLIRGenerator.h" |
| 14 | #include "src/sksl/SkSLUtil.h" |
| 15 | #include "src/sksl/ir/SkSLConstructor.h" |
| 16 | #include "src/sksl/ir/SkSLExpression.h" |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 17 | |
| 18 | namespace SkSL { |
| 19 | |
| 20 | /** |
John Stiles | 108bbe2 | 2020-11-18 11:10:38 -0500 | [diff] [blame] | 21 | * Represents a vector swizzle operation such as 'float3(1, 2, 3).zyx'. |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 22 | */ |
John Stiles | 1cc63da | 2020-10-28 15:11:06 -0400 | [diff] [blame] | 23 | struct Swizzle final : public Expression { |
Ethan Nicholas | e659214 | 2020-09-08 10:22:09 -0400 | [diff] [blame] | 24 | static constexpr Kind kExpressionKind = Kind::kSwizzle; |
John Stiles | 81365af | 2020-08-18 09:24:00 -0400 | [diff] [blame] | 25 | |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 26 | Swizzle(const Context& context, std::unique_ptr<Expression> base, |
| 27 | const ComponentArray& components) |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 28 | : INHERITED(base->fOffset, kExpressionKind, |
| 29 | &base->type().componentType().toCompound(context, components.size(), 1)) |
| 30 | , fBase(std::move(base)) |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 31 | , fComponents(components) { |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 32 | SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 33 | } |
| 34 | |
John Stiles | 23521a8 | 2021-03-02 17:02:51 -0500 | [diff] [blame] | 35 | // Swizzle::Convert permits component arrays containing ZERO or ONE, does typechecking, reports |
| 36 | // errors via ErrorReporter, and returns an expression that combines constructors and native |
| 37 | // swizzles (comprised solely of X/Y/W/Z). |
| 38 | static std::unique_ptr<Expression> Convert(const Context& context, |
| 39 | std::unique_ptr<Expression> base, |
| 40 | ComponentArray inComponents); |
John Stiles | 6e88e04 | 2021-02-19 14:09:38 -0500 | [diff] [blame] | 41 | |
John Stiles | 23521a8 | 2021-03-02 17:02:51 -0500 | [diff] [blame] | 42 | // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are |
| 43 | // reported via ASSERT. |
John Stiles | 6e88e04 | 2021-02-19 14:09:38 -0500 | [diff] [blame] | 44 | static std::unique_ptr<Expression> Make(const Context& context, |
| 45 | std::unique_ptr<Expression> expr, |
| 46 | ComponentArray inComponents); |
| 47 | |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 48 | std::unique_ptr<Expression>& base() { |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 49 | return fBase; |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 50 | } |
| 51 | |
| 52 | const std::unique_ptr<Expression>& base() const { |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 53 | return fBase; |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 54 | } |
| 55 | |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 56 | const ComponentArray& components() const { |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 57 | return fComponents; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 58 | } |
| 59 | |
Ethan Nicholas | 2a099da | 2020-01-02 14:40:54 -0500 | [diff] [blame] | 60 | bool hasProperty(Property property) const override { |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 61 | return this->base()->hasProperty(property); |
Ethan Nicholas | cb67096 | 2017-04-20 19:31:52 -0400 | [diff] [blame] | 62 | } |
| 63 | |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 64 | std::unique_ptr<Expression> clone() const override { |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 65 | return std::unique_ptr<Expression>(new Swizzle(&this->type(), this->base()->clone(), |
| 66 | this->components())); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 67 | } |
| 68 | |
Ethan Nicholas | 0df1b04 | 2017-03-31 13:56:23 -0400 | [diff] [blame] | 69 | String description() const override { |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 70 | String result = this->base()->description() + "."; |
| 71 | for (int x : this->components()) { |
Brian Osman | 2564767 | 2020-09-15 15:16:56 -0400 | [diff] [blame] | 72 | result += "xyzw"[x]; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 73 | } |
| 74 | return result; |
| 75 | } |
| 76 | |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 77 | private: |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 78 | Swizzle(const Type* type, std::unique_ptr<Expression> base, const ComponentArray& components) |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 79 | : INHERITED(base->fOffset, kExpressionKind, type) |
| 80 | , fBase(std::move(base)) |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 81 | , fComponents(components) { |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 82 | SkASSERT(this->components().size() >= 1 && this->components().size() <= 4); |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 83 | } |
| 84 | |
John Stiles | 2d4f959 | 2020-10-30 10:29:12 -0400 | [diff] [blame] | 85 | std::unique_ptr<Expression> fBase; |
John Stiles | 750109b | 2020-10-30 13:45:46 -0400 | [diff] [blame] | 86 | ComponentArray fComponents; |
Ethan Nicholas | 0054311 | 2018-07-31 09:44:36 -0400 | [diff] [blame] | 87 | |
Ethan Nicholas | 6b4d581 | 2020-10-12 16:11:51 -0400 | [diff] [blame] | 88 | using INHERITED = Expression; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 89 | }; |
| 90 | |
John Stiles | a6841be | 2020-08-06 14:11:56 -0400 | [diff] [blame] | 91 | } // namespace SkSL |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 92 | |
| 93 | #endif |