55#include " impeller/aiks/color_source.h"
66
77#include < memory>
8+ #include < variant>
89#include < vector>
910
1011#include " impeller/aiks/paint.h"
2930
3031namespace impeller {
3132
32- ColorSource::ColorSource () noexcept
33- : proc_([](const Paint& paint) -> std::shared_ptr<ColorSourceContents> {
34- auto contents = std::make_shared<SolidColorContents>();
35- contents->SetColor (paint.color );
36- return contents;
37- }){};
33+ namespace {
34+
35+ struct CreateContentsVisitor {
36+ explicit CreateContentsVisitor (const Paint& p_paint) : paint(p_paint) {}
37+
38+ const Paint& paint;
39+
40+ std::shared_ptr<ColorSourceContents> operator ()(
41+ const LinearGradientData& data) {
42+ auto contents = std::make_shared<LinearGradientContents>();
43+ contents->SetOpacityFactor (paint.color .alpha );
44+ contents->SetColors (data.colors );
45+ contents->SetStops (data.stops );
46+ contents->SetEndPoints (data.start_point , data.end_point );
47+ contents->SetTileMode (data.tile_mode );
48+ contents->SetEffectTransform (data.effect_transform );
49+
50+ std::vector<Point> bounds{data.start_point , data.end_point };
51+ auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
52+ if (intrinsic_size.has_value ()) {
53+ contents->SetColorSourceSize (intrinsic_size->GetSize ());
54+ }
55+ return contents;
56+ }
57+
58+ std::shared_ptr<ColorSourceContents> operator ()(
59+ const RadialGradientData& data) {
60+ auto contents = std::make_shared<RadialGradientContents>();
61+ contents->SetOpacityFactor (paint.color .alpha );
62+ contents->SetColors (data.colors );
63+ contents->SetStops (data.stops );
64+ contents->SetCenterAndRadius (data.center , data.radius );
65+ contents->SetTileMode (data.tile_mode );
66+ contents->SetEffectTransform (data.effect_transform );
67+
68+ auto radius_pt = Point (data.radius , data.radius );
69+ std::vector<Point> bounds{data.center + radius_pt, data.center - radius_pt};
70+ auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
71+ if (intrinsic_size.has_value ()) {
72+ contents->SetColorSourceSize (intrinsic_size->GetSize ());
73+ }
74+ return contents;
75+ }
76+
77+ std::shared_ptr<ColorSourceContents> operator ()(
78+ const ConicalGradientData& data) {
79+ std::shared_ptr<ConicalGradientContents> contents =
80+ std::make_shared<ConicalGradientContents>();
81+ contents->SetOpacityFactor (paint.color .alpha );
82+ contents->SetColors (data.colors );
83+ contents->SetStops (data.stops );
84+ contents->SetCenterAndRadius (data.center , data.radius );
85+ contents->SetTileMode (data.tile_mode );
86+ contents->SetEffectTransform (data.effect_transform );
87+ contents->SetFocus (data.focus_center , data.focus_radius );
88+
89+ auto radius_pt = Point (data.radius , data.radius );
90+ std::vector<Point> bounds{data.center + radius_pt, data.center - radius_pt};
91+ auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
92+ if (intrinsic_size.has_value ()) {
93+ contents->SetColorSourceSize (intrinsic_size->GetSize ());
94+ }
95+ return contents;
96+ }
97+
98+ std::shared_ptr<ColorSourceContents> operator ()(
99+ const SweepGradientData& data) {
100+ auto contents = std::make_shared<SweepGradientContents>();
101+ contents->SetOpacityFactor (paint.color .alpha );
102+ contents->SetCenterAndAngles (data.center , data.start_angle , data.end_angle );
103+ contents->SetColors (data.colors );
104+ contents->SetStops (data.stops );
105+ contents->SetTileMode (data.tile_mode );
106+ contents->SetEffectTransform (data.effect_transform );
107+
108+ return contents;
109+ }
110+
111+ std::shared_ptr<ColorSourceContents> operator ()(const ImageData& data) {
112+ auto contents = std::make_shared<TiledTextureContents>();
113+ contents->SetOpacityFactor (paint.color .alpha );
114+ contents->SetTexture (data.texture );
115+ contents->SetTileModes (data.x_tile_mode , data.y_tile_mode );
116+ contents->SetSamplerDescriptor (data.sampler_descriptor );
117+ contents->SetEffectTransform (data.effect_transform );
118+ if (paint.color_filter ) {
119+ TiledTextureContents::ColorFilterProc filter_proc =
120+ [color_filter = paint.color_filter ](FilterInput::Ref input) {
121+ return color_filter->WrapWithGPUColorFilter (
122+ std::move (input), ColorFilterContents::AbsorbOpacity::kNo );
123+ };
124+ contents->SetColorFilter (filter_proc);
125+ }
126+ contents->SetColorSourceSize (Size::Ceil (data.texture ->GetSize ()));
127+ return contents;
128+ }
129+
130+ std::shared_ptr<ColorSourceContents> operator ()(
131+ const RuntimeEffectData& data) {
132+ auto contents = std::make_shared<RuntimeEffectContents>();
133+ contents->SetOpacityFactor (paint.color .alpha );
134+ contents->SetRuntimeStage (data.runtime_stage );
135+ contents->SetUniformData (data.uniform_data );
136+ contents->SetTextureInputs (data.texture_inputs );
137+ return contents;
138+ }
139+
140+ std::shared_ptr<ColorSourceContents> operator ()(const std::monostate& data) {
141+ auto contents = std::make_shared<SolidColorContents>();
142+ contents->SetColor (paint.color );
143+ return contents;
144+ }
145+
146+ #if IMPELLER_ENABLE_3D
147+ std::shared_ptr<ColorSourceContents> operator ()(const SceneData& data) {
148+ auto contents = std::make_shared<SceneContents>();
149+ contents->SetOpacityFactor (paint.color .alpha );
150+ contents->SetNode (data.scene_node );
151+ contents->SetCameraTransform (data.camera_transform );
152+ return contents;
153+ }
154+ #endif // IMPELLER_ENABLE_3D
155+ };
156+ } // namespace
157+
158+ ColorSource::ColorSource () noexcept : color_source_data_(std::monostate()) {}
38159
39160ColorSource::~ColorSource () = default ;
40161
@@ -50,24 +171,9 @@ ColorSource ColorSource::MakeLinearGradient(Point start_point,
50171 Matrix effect_transform) {
51172 ColorSource result;
52173 result.type_ = Type::kLinearGradient ;
53- result.proc_ = [start_point, end_point, colors = std::move (colors),
54- stops = std::move (stops), tile_mode,
55- effect_transform](const Paint& paint) {
56- auto contents = std::make_shared<LinearGradientContents>();
57- contents->SetOpacityFactor (paint.color .alpha );
58- contents->SetColors (colors);
59- contents->SetStops (stops);
60- contents->SetEndPoints (start_point, end_point);
61- contents->SetTileMode (tile_mode);
62- contents->SetEffectTransform (effect_transform);
63-
64- std::vector<Point> bounds{start_point, end_point};
65- auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
66- if (intrinsic_size.has_value ()) {
67- contents->SetColorSourceSize (intrinsic_size->GetSize ());
68- }
69- return contents;
70- };
174+ result.color_source_data_ =
175+ LinearGradientData{start_point, end_point, std::move (colors),
176+ std::move (stops), tile_mode, effect_transform};
71177 return result;
72178}
73179
@@ -81,27 +187,9 @@ ColorSource ColorSource::MakeConicalGradient(Point center,
81187 Matrix effect_transform) {
82188 ColorSource result;
83189 result.type_ = Type::kConicalGradient ;
84- result.proc_ = [center, radius, colors = std::move (colors),
85- stops = std::move (stops), focus_center, focus_radius,
86- tile_mode, effect_transform](const Paint& paint) {
87- std::shared_ptr<ConicalGradientContents> contents =
88- std::make_shared<ConicalGradientContents>();
89- contents->SetOpacityFactor (paint.color .alpha );
90- contents->SetColors (colors);
91- contents->SetStops (stops);
92- contents->SetCenterAndRadius (center, radius);
93- contents->SetTileMode (tile_mode);
94- contents->SetEffectTransform (effect_transform);
95- contents->SetFocus (focus_center, focus_radius);
96-
97- auto radius_pt = Point (radius, radius);
98- std::vector<Point> bounds{center + radius_pt, center - radius_pt};
99- auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
100- if (intrinsic_size.has_value ()) {
101- contents->SetColorSourceSize (intrinsic_size->GetSize ());
102- }
103- return contents;
104- };
190+ result.color_source_data_ = ConicalGradientData{
191+ center, radius, std::move (colors), std::move (stops),
192+ focus_center, focus_radius, tile_mode, effect_transform};
105193 return result;
106194}
107195
@@ -113,25 +201,9 @@ ColorSource ColorSource::MakeRadialGradient(Point center,
113201 Matrix effect_transform) {
114202 ColorSource result;
115203 result.type_ = Type::kRadialGradient ;
116- result.proc_ = [center, radius, colors = std::move (colors),
117- stops = std::move (stops), tile_mode,
118- effect_transform](const Paint& paint) {
119- auto contents = std::make_shared<RadialGradientContents>();
120- contents->SetOpacityFactor (paint.color .alpha );
121- contents->SetColors (colors);
122- contents->SetStops (stops);
123- contents->SetCenterAndRadius (center, radius);
124- contents->SetTileMode (tile_mode);
125- contents->SetEffectTransform (effect_transform);
126-
127- auto radius_pt = Point (radius, radius);
128- std::vector<Point> bounds{center + radius_pt, center - radius_pt};
129- auto intrinsic_size = Rect::MakePointBounds (bounds.begin (), bounds.end ());
130- if (intrinsic_size.has_value ()) {
131- contents->SetColorSourceSize (intrinsic_size->GetSize ());
132- }
133- return contents;
134- };
204+ result.color_source_data_ =
205+ RadialGradientData{center, radius, std::move (colors),
206+ std::move (stops), tile_mode, effect_transform};
135207 return result;
136208}
137209
@@ -144,19 +216,9 @@ ColorSource ColorSource::MakeSweepGradient(Point center,
144216 Matrix effect_transform) {
145217 ColorSource result;
146218 result.type_ = Type::kSweepGradient ;
147- result.proc_ = [center, start_angle, end_angle, colors = std::move (colors),
148- stops = std::move (stops), tile_mode,
149- effect_transform](const Paint& paint) {
150- auto contents = std::make_shared<SweepGradientContents>();
151- contents->SetOpacityFactor (paint.color .alpha );
152- contents->SetCenterAndAngles (center, start_angle, end_angle);
153- contents->SetColors (colors);
154- contents->SetStops (stops);
155- contents->SetTileMode (tile_mode);
156- contents->SetEffectTransform (effect_transform);
157-
158- return contents;
159- };
219+ result.color_source_data_ = SweepGradientData{
220+ center, start_angle, end_angle, std::move (colors),
221+ std::move (stops), tile_mode, effect_transform};
160222 return result;
161223}
162224
@@ -167,26 +229,9 @@ ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture,
167229 Matrix effect_transform) {
168230 ColorSource result;
169231 result.type_ = Type::kImage ;
170- result.proc_ = [texture = std::move (texture), x_tile_mode, y_tile_mode,
171- sampler_descriptor = std::move (sampler_descriptor),
172- effect_transform](const Paint& paint) {
173- auto contents = std::make_shared<TiledTextureContents>();
174- contents->SetOpacityFactor (paint.color .alpha );
175- contents->SetTexture (texture);
176- contents->SetTileModes (x_tile_mode, y_tile_mode);
177- contents->SetSamplerDescriptor (sampler_descriptor);
178- contents->SetEffectTransform (effect_transform);
179- if (paint.color_filter ) {
180- TiledTextureContents::ColorFilterProc filter_proc =
181- [color_filter = paint.color_filter ](FilterInput::Ref input) {
182- return color_filter->WrapWithGPUColorFilter (
183- std::move (input), ColorFilterContents::AbsorbOpacity::kNo );
184- };
185- contents->SetColorFilter (filter_proc);
186- }
187- contents->SetColorSourceSize (Size::Ceil (texture->GetSize ()));
188- return contents;
189- };
232+ result.color_source_data_ =
233+ ImageData{std::move (texture), x_tile_mode, y_tile_mode,
234+ std::move (sampler_descriptor), effect_transform};
190235 return result;
191236}
192237
@@ -196,17 +241,9 @@ ColorSource ColorSource::MakeRuntimeEffect(
196241 std::vector<RuntimeEffectContents::TextureInput> texture_inputs) {
197242 ColorSource result;
198243 result.type_ = Type::kRuntimeEffect ;
199- result.proc_ = [runtime_stage = std::move (runtime_stage),
200- uniform_data = std::move (uniform_data),
201- texture_inputs =
202- std::move (texture_inputs)](const Paint& paint) {
203- auto contents = std::make_shared<RuntimeEffectContents>();
204- contents->SetOpacityFactor (paint.color .alpha );
205- contents->SetRuntimeStage (runtime_stage);
206- contents->SetUniformData (uniform_data);
207- contents->SetTextureInputs (texture_inputs);
208- return contents;
209- };
244+ result.color_source_data_ =
245+ RuntimeEffectData{std::move (runtime_stage), std::move (uniform_data),
246+ std::move (texture_inputs)};
210247 return result;
211248}
212249
@@ -215,14 +252,7 @@ ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node,
215252 Matrix camera_transform) {
216253 ColorSource result;
217254 result.type_ = Type::kScene ;
218- result.proc_ = [scene_node = std::move (scene_node),
219- camera_transform](const Paint& paint) {
220- auto contents = std::make_shared<SceneContents>();
221- contents->SetOpacityFactor (paint.color .alpha );
222- contents->SetNode (scene_node);
223- contents->SetCameraTransform (camera_transform);
224- return contents;
225- };
255+ result.color_source_data_ = SceneData{scene_node, camera_transform};
226256 return result;
227257}
228258#endif // IMPELLER_ENABLE_3D
@@ -233,7 +263,7 @@ ColorSource::Type ColorSource::GetType() const {
233263
234264std::shared_ptr<ColorSourceContents> ColorSource::GetContents (
235265 const Paint& paint) const {
236- return proc_ ( paint);
266+ return std::visit (CreateContentsVisitor{ paint}, color_source_data_ );
237267}
238268
239269} // namespace impeller
0 commit comments