8
8
#include < initializer_list>
9
9
#include < memory>
10
10
#include < optional>
11
+ #include < variant>
11
12
13
+ #include " fml/logging.h"
14
+ #include " impeller/entity/contents/filters/filter_contents.h"
12
15
#include " impeller/entity/contents/snapshot.h"
13
16
#include " impeller/entity/entity.h"
14
17
15
18
namespace impeller {
16
19
20
+ /* ******************************************************************************
21
+ ******* FilterInput
22
+ ******************************************************************************/
23
+
17
24
FilterInput::Ref FilterInput::Make (Variant input) {
18
- return std::shared_ptr<FilterInput>(new FilterInput (input));
25
+ if (auto filter = std::get_if<std::shared_ptr<FilterContents>>(&input)) {
26
+ return std::static_pointer_cast<FilterInput>(
27
+ std::shared_ptr<FilterContentsFilterInput>(
28
+ new FilterContentsFilterInput (*filter)));
29
+ }
30
+
31
+ if (auto contents = std::get_if<std::shared_ptr<Contents>>(&input)) {
32
+ return std::static_pointer_cast<FilterInput>(
33
+ std::shared_ptr<ContentsFilterInput>(
34
+ new ContentsFilterInput (*contents)));
35
+ }
36
+
37
+ if (auto texture = std::get_if<std::shared_ptr<Texture>>(&input)) {
38
+ return std::static_pointer_cast<FilterInput>(
39
+ std::shared_ptr<TextureFilterInput>(new TextureFilterInput (*texture)));
40
+ }
41
+
42
+ FML_UNREACHABLE ();
19
43
}
20
44
21
45
FilterInput::Vector FilterInput::Make (std::initializer_list<Variant> inputs) {
@@ -27,63 +51,118 @@ FilterInput::Vector FilterInput::Make(std::initializer_list<Variant> inputs) {
27
51
return result;
28
52
}
29
53
30
- FilterInput::Variant FilterInput::GetInput ( ) const {
31
- return input_ ;
54
+ Matrix FilterInput::GetLocalTransform ( const Entity& entity ) const {
55
+ return Matrix () ;
32
56
}
33
57
34
- std::optional<Rect > FilterInput::GetCoverage (const Entity& entity) const {
35
- if (snapshot_) {
36
- return snapshot_->GetCoverage ();
37
- }
58
+ Matrix FilterInput::GetTransform (const Entity& entity) const {
59
+ return entity.GetTransformation () * GetLocalTransform (entity);
60
+ }
38
61
39
- if (auto contents = std::get_if<std::shared_ptr<Contents>>(&input_)) {
40
- return contents->get ()->GetCoverage (entity);
41
- }
62
+ FilterInput::~FilterInput () = default ;
42
63
43
- if ( auto texture = std::get_if<std::shared_ptr<Texture>>(&input_)) {
44
- return entity. GetPathCoverage ();
45
- }
64
+ /* ******************************************************************************
65
+ ******* FilterContentsFilterInput
66
+ ***************************************************************************** */
46
67
47
- FML_UNREACHABLE ();
68
+ FilterContentsFilterInput::FilterContentsFilterInput (
69
+ std::shared_ptr<FilterContents> filter)
70
+ : filter_(filter) {}
71
+
72
+ FilterContentsFilterInput::~FilterContentsFilterInput () = default ;
73
+
74
+ FilterInput::Variant FilterContentsFilterInput::GetInput () const {
75
+ return filter_;
48
76
}
49
77
50
- std::optional<Snapshot> FilterInput::GetSnapshot (const ContentContext& renderer,
51
- const Entity& entity) const {
52
- if (snapshot_) {
53
- return snapshot_;
78
+ std::optional<Snapshot> FilterContentsFilterInput::GetSnapshot (
79
+ const ContentContext& renderer,
80
+ const Entity& entity) const {
81
+ if (!snapshot_.has_value ()) {
82
+ snapshot_ = filter_->RenderToSnapshot (renderer, entity);
54
83
}
55
- snapshot_ = MakeSnapshot (renderer, entity);
56
-
57
84
return snapshot_;
58
85
}
59
86
60
- FilterInput::FilterInput (Variant input) : input_(input) {}
87
+ std::optional<Rect > FilterContentsFilterInput::GetCoverage (
88
+ const Entity& entity) const {
89
+ return filter_->GetCoverage (entity);
90
+ }
61
91
62
- FilterInput::~FilterInput () = default ;
92
+ Matrix FilterContentsFilterInput::GetLocalTransform (
93
+ const Entity& entity) const {
94
+ return filter_->GetLocalTransform ();
95
+ }
63
96
64
- std::optional<Snapshot> FilterInput::MakeSnapshot (
97
+ Matrix FilterContentsFilterInput::GetTransform (const Entity& entity) const {
98
+ return filter_->GetTransform (entity.GetTransformation ());
99
+ }
100
+
101
+ /* ******************************************************************************
102
+ ******* ContentsFilterInput
103
+ ******************************************************************************/
104
+
105
+ ContentsFilterInput::ContentsFilterInput (std::shared_ptr<Contents> contents)
106
+ : contents_(contents) {}
107
+
108
+ ContentsFilterInput::~ContentsFilterInput () = default ;
109
+
110
+ FilterInput::Variant ContentsFilterInput::GetInput () const {
111
+ return contents_;
112
+ }
113
+
114
+ std::optional<Snapshot> ContentsFilterInput::GetSnapshot (
65
115
const ContentContext& renderer,
66
116
const Entity& entity) const {
67
- if (auto contents = std::get_if<std::shared_ptr<Contents>>(&input_ )) {
68
- return contents-> get () ->RenderToSnapshot (renderer, entity);
117
+ if (!snapshot_. has_value ( )) {
118
+ snapshot_ = contents_ ->RenderToSnapshot (renderer, entity);
69
119
}
120
+ return snapshot_;
121
+ }
122
+
123
+ std::optional<Rect > ContentsFilterInput::GetCoverage (
124
+ const Entity& entity) const {
125
+ return contents_->GetCoverage (entity);
126
+ }
127
+
128
+ /* ******************************************************************************
129
+ ******* TextureFilterInput
130
+ ******************************************************************************/
70
131
71
- if (auto texture = std::get_if<std::shared_ptr<Texture>>(&input_)) {
72
- // Rendered textures stretch to fit the entity path coverage, so we
73
- // incorporate this behavior by translating and scaling the snapshot
74
- // transform.
75
- auto path_bounds = entity.GetPath ().GetBoundingBox ();
76
- if (!path_bounds.has_value ()) {
77
- return std::nullopt;
78
- }
79
- auto transform = entity.GetTransformation () *
80
- Matrix::MakeTranslation (path_bounds->origin ) *
81
- Matrix::MakeScale (Vector2 (path_bounds->size ) /
82
- texture->get ()->GetSize ());
83
- return Snapshot{.texture = *texture, .transform = transform};
132
+ TextureFilterInput::TextureFilterInput (std::shared_ptr<Texture> texture)
133
+ : texture_(texture) {}
134
+
135
+ TextureFilterInput::~TextureFilterInput () = default ;
136
+
137
+ FilterInput::Variant TextureFilterInput::GetInput () const {
138
+ return texture_;
139
+ }
140
+
141
+ std::optional<Snapshot> TextureFilterInput::GetSnapshot (
142
+ const ContentContext& renderer,
143
+ const Entity& entity) const {
144
+ return Snapshot{.texture = texture_, .transform = GetTransform (entity)};
145
+ }
146
+
147
+ std::optional<Rect > TextureFilterInput::GetCoverage (
148
+ const Entity& entity) const {
149
+ auto path_bounds = entity.GetPath ().GetBoundingBox ();
150
+ if (!path_bounds.has_value ()) {
151
+ return std::nullopt;
84
152
}
153
+ return Rect::MakeSize (Size (texture_->GetSize ()))
154
+ .TransformBounds (GetTransform (entity));
155
+ }
85
156
86
- FML_UNREACHABLE ();
157
+ Matrix TextureFilterInput::GetLocalTransform (const Entity& entity) const {
158
+ // Compute the local transform such that the texture will cover the entity
159
+ // path bounding box.
160
+ auto path_bounds = entity.GetPath ().GetBoundingBox ();
161
+ if (!path_bounds.has_value ()) {
162
+ return Matrix ();
163
+ }
164
+ return Matrix::MakeTranslation (path_bounds->origin ) *
165
+ Matrix::MakeScale (Vector2 (path_bounds->size ) / texture_->GetSize ());
87
166
}
88
167
89
168
} // namespace impeller
0 commit comments