blob: bcedc2bbdfbb625b92b658b783d450bb0da54566 [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_SWIZZLE
9#define SKSL_SWIZZLE
10
Ethan Nicholasdaed2592021-03-04 14:30:25 -050011#include "include/private/SkSLDefines.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#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"
ethannicholasb3058bd2016-07-01 08:22:01 -070017
18namespace SkSL {
19
20/**
John Stiles108bbe22020-11-18 11:10:38 -050021 * Represents a vector swizzle operation such as 'float3(1, 2, 3).zyx'.
ethannicholasb3058bd2016-07-01 08:22:01 -070022 */
John Stiles1cc63da2020-10-28 15:11:06 -040023struct Swizzle final : public Expression {
Ethan Nicholase6592142020-09-08 10:22:09 -040024 static constexpr Kind kExpressionKind = Kind::kSwizzle;
John Stiles81365af2020-08-18 09:24:00 -040025
John Stiles750109b2020-10-30 13:45:46 -040026 Swizzle(const Context& context, std::unique_ptr<Expression> base,
27 const ComponentArray& components)
John Stiles2d4f9592020-10-30 10:29:12 -040028 : INHERITED(base->fOffset, kExpressionKind,
29 &base->type().componentType().toCompound(context, components.size(), 1))
30 , fBase(std::move(base))
John Stiles750109b2020-10-30 13:45:46 -040031 , fComponents(components) {
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040032 SkASSERT(this->components().size() >= 1 && this->components().size() <= 4);
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040033 }
34
John Stiles23521a82021-03-02 17:02:51 -050035 // 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 Stiles6e88e042021-02-19 14:09:38 -050041
John Stiles23521a82021-03-02 17:02:51 -050042 // Swizzle::Make does not permit ZERO or ONE in the component array, just X/Y/Z/W; errors are
43 // reported via ASSERT.
John Stiles6e88e042021-02-19 14:09:38 -050044 static std::unique_ptr<Expression> Make(const Context& context,
45 std::unique_ptr<Expression> expr,
46 ComponentArray inComponents);
47
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040048 std::unique_ptr<Expression>& base() {
John Stiles2d4f9592020-10-30 10:29:12 -040049 return fBase;
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040050 }
51
52 const std::unique_ptr<Expression>& base() const {
John Stiles2d4f9592020-10-30 10:29:12 -040053 return fBase;
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040054 }
55
John Stiles750109b2020-10-30 13:45:46 -040056 const ComponentArray& components() const {
John Stiles2d4f9592020-10-30 10:29:12 -040057 return fComponents;
ethannicholasb3058bd2016-07-01 08:22:01 -070058 }
59
Ethan Nicholas2a099da2020-01-02 14:40:54 -050060 bool hasProperty(Property property) const override {
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040061 return this->base()->hasProperty(property);
Ethan Nicholascb670962017-04-20 19:31:52 -040062 }
63
Ethan Nicholas00543112018-07-31 09:44:36 -040064 std::unique_ptr<Expression> clone() const override {
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040065 return std::unique_ptr<Expression>(new Swizzle(&this->type(), this->base()->clone(),
66 this->components()));
Ethan Nicholas00543112018-07-31 09:44:36 -040067 }
68
Ethan Nicholas0df1b042017-03-31 13:56:23 -040069 String description() const override {
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040070 String result = this->base()->description() + ".";
71 for (int x : this->components()) {
Brian Osman25647672020-09-15 15:16:56 -040072 result += "xyzw"[x];
ethannicholasb3058bd2016-07-01 08:22:01 -070073 }
74 return result;
75 }
76
Ethan Nicholas00543112018-07-31 09:44:36 -040077private:
John Stiles750109b2020-10-30 13:45:46 -040078 Swizzle(const Type* type, std::unique_ptr<Expression> base, const ComponentArray& components)
John Stiles2d4f9592020-10-30 10:29:12 -040079 : INHERITED(base->fOffset, kExpressionKind, type)
80 , fBase(std::move(base))
John Stiles750109b2020-10-30 13:45:46 -040081 , fComponents(components) {
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040082 SkASSERT(this->components().size() >= 1 && this->components().size() <= 4);
Ethan Nicholas00543112018-07-31 09:44:36 -040083 }
84
John Stiles2d4f9592020-10-30 10:29:12 -040085 std::unique_ptr<Expression> fBase;
John Stiles750109b2020-10-30 13:45:46 -040086 ComponentArray fComponents;
Ethan Nicholas00543112018-07-31 09:44:36 -040087
Ethan Nicholas6b4d5812020-10-12 16:11:51 -040088 using INHERITED = Expression;
ethannicholasb3058bd2016-07-01 08:22:01 -070089};
90
John Stilesa6841be2020-08-06 14:11:56 -040091} // namespace SkSL
ethannicholasb3058bd2016-07-01 08:22:01 -070092
93#endif