9 #include "flutter/display_list/effects/dl_color_filter.h"
10 #include "flutter/display_list/effects/dl_color_sources.h"
11 #include "flutter/display_list/geometry/dl_path.h"
12 #include "fml/logging.h"
39 auto contents = std::make_shared<SolidColorContents>();
40 contents->SetColor(
color);
45 case flutter::DlColorSourceType::kLinearGradient: {
46 const flutter::DlLinearGradientColorSource* linear =
49 auto start_point = linear->start_point();
50 auto end_point = linear->end_point();
51 std::vector<Color> colors;
52 std::vector<float> stops;
56 auto effect_transform = linear->matrix();
58 auto contents = std::make_shared<LinearGradientContents>();
60 contents->SetColors(std::move(colors));
61 contents->SetStops(std::move(stops));
62 contents->SetEndPoints(start_point, end_point);
63 contents->SetTileMode(tile_mode);
64 contents->SetEffectTransform(effect_transform);
66 std::array<Point, 2> bounds{start_point, end_point};
68 if (intrinsic_size.has_value()) {
69 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
73 case flutter::DlColorSourceType::kRadialGradient: {
74 const flutter::DlRadialGradientColorSource* radialGradient =
76 FML_DCHECK(radialGradient);
77 auto center = radialGradient->center();
78 auto radius = radialGradient->radius();
79 std::vector<Color> colors;
80 std::vector<float> stops;
85 auto effect_transform = radialGradient->matrix();
87 auto contents = std::make_shared<RadialGradientContents>();
89 contents->SetColors(std::move(colors));
90 contents->SetStops(std::move(stops));
91 contents->SetCenterAndRadius(center, radius);
92 contents->SetTileMode(tile_mode);
93 contents->SetEffectTransform(effect_transform);
95 auto radius_pt =
Point(radius, radius);
96 std::array<Point, 2> bounds{center + radius_pt, center - radius_pt};
98 if (intrinsic_size.has_value()) {
99 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
103 case flutter::DlColorSourceType::kConicalGradient: {
104 const flutter::DlConicalGradientColorSource* conical_gradient =
106 FML_DCHECK(conical_gradient);
107 Point center = conical_gradient->end_center();
108 DlScalar radius = conical_gradient->end_radius();
109 Point focus_center = conical_gradient->start_center();
110 DlScalar focus_radius = conical_gradient->start_radius();
111 std::vector<Color> colors;
112 std::vector<float> stops;
117 auto effect_transform = conical_gradient->matrix();
119 std::shared_ptr<ConicalGradientContents> contents =
120 std::make_shared<ConicalGradientContents>();
122 contents->SetColors(std::move(colors));
123 contents->SetStops(std::move(stops));
124 contents->SetCenterAndRadius(center, radius);
125 contents->SetTileMode(tile_mode);
126 contents->SetEffectTransform(effect_transform);
127 contents->SetFocus(focus_center, focus_radius);
129 auto radius_pt =
Point(radius, radius);
130 std::array<Point, 2> bounds{center + radius_pt, center - radius_pt};
132 if (intrinsic_size.has_value()) {
133 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
137 case flutter::DlColorSourceType::kSweepGradient: {
138 const flutter::DlSweepGradientColorSource* sweepGradient =
140 FML_DCHECK(sweepGradient);
142 auto center = sweepGradient->center();
143 auto start_angle =
Degrees(sweepGradient->start());
144 auto end_angle =
Degrees(sweepGradient->end());
145 std::vector<Color> colors;
146 std::vector<float> stops;
151 auto effect_transform = sweepGradient->matrix();
153 auto contents = std::make_shared<SweepGradientContents>();
155 contents->SetCenterAndAngles(center, start_angle, end_angle);
156 contents->SetColors(std::move(colors));
157 contents->SetStops(std::move(stops));
158 contents->SetTileMode(tile_mode);
159 contents->SetEffectTransform(effect_transform);
163 case flutter::DlColorSourceType::kImage: {
164 const flutter::DlImageColorSource* image_color_source =
166 FML_DCHECK(image_color_source &&
167 image_color_source->image()->impeller_texture());
168 auto texture = image_color_source->image()->impeller_texture();
170 image_color_source->horizontal_tile_mode());
172 image_color_source->vertical_tile_mode());
173 auto sampler_descriptor =
175 auto effect_transform = image_color_source->matrix();
177 auto contents = std::make_shared<TiledTextureContents>();
179 contents->SetTexture(texture);
180 contents->SetTileModes(x_tile_mode, y_tile_mode);
181 contents->SetSamplerDescriptor(sampler_descriptor);
182 contents->SetEffectTransform(effect_transform);
188 std::shared_ptr<FilterContents> color_filter_output =
204 contents->SetColorFilter(filter_proc);
206 contents->SetColorSourceSize(
Size::Ceil(texture->GetSize()));
209 case flutter::DlColorSourceType::kRuntimeEffect: {
210 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
213 runtime_effect_color_source->runtime_effect()->runtime_stage();
214 auto uniform_data = runtime_effect_color_source->uniform_data();
215 auto samplers = runtime_effect_color_source->samplers();
217 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
219 for (
auto& sampler : samplers) {
220 if (sampler ==
nullptr) {
223 auto* image = sampler->asImage();
224 if (!sampler->asImage()) {
227 FML_DCHECK(image->image()->impeller_texture());
228 texture_inputs.push_back({
229 .sampler_descriptor =
231 .texture = image->image()->impeller_texture(),
235 auto contents = std::make_shared<RuntimeEffectContents>();
237 contents->SetRuntimeStage(std::move(runtime_stage));
238 contents->SetUniformData(std::move(uniform_data));
239 contents->SetTextureInputs(std::move(texture_inputs));
247 std::shared_ptr<Contents> input)
const {
258 std::shared_ptr<Contents> input,
259 const Matrix& effect_transform)
const {
272 const Matrix& ctm)
const {
275 is_solid_color, ctm);
282 const Matrix& effect_transform,
288 filter->SetRenderingMode(rendering_mode);
289 filter->SetEffectTransform(effect_transform);
293 std::shared_ptr<Contents> Paint::WithColorFilter(
294 std::shared_ptr<Contents> input,
299 color_source->type() == flutter::DlColorSourceType::kImage) {
310 if (input->ApplyColorFilter([&](Color
color) -> Color {
312 color = GetCPUColorFilterProc(color_filter)(color);
333 std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
334 std::shared_ptr<TextureContents> texture_contents,
336 Scalar expand_amount = GaussianBlurFilterContents::CalculateBlurRadius(
337 GaussianBlurFilterContents::ScaleSigma(sigma.sigma));
338 texture_contents->SetSourceRect(
339 texture_contents->GetSourceRect().Expand(expand_amount, expand_amount));
340 auto mask = std::make_shared<SolidColorContents>();
341 mask->SetColor(Color::White());
342 std::optional<Rect> coverage = texture_contents->GetCoverage({});
345 texture_contents->SetDestinationRect(
346 coverage.value().Expand(expand_amount, expand_amount));
348 geometry = rect_geom;
350 mask->SetGeometry(geometry);
351 auto descriptor = texture_contents->GetSamplerDescriptor();
352 texture_contents->SetSamplerDescriptor(descriptor);
353 std::shared_ptr<FilterContents> blurred_mask =
354 FilterContents::MakeGaussianBlur(FilterInput::Make(mask), sigma, sigma,
355 Entity::TileMode::kDecal, style,
358 return ColorFilterContents::MakeBlend(
359 BlendMode::kSourceIn,
360 {FilterInput::Make(blurred_mask), FilterInput::Make(texture_contents)});
363 std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
364 std::shared_ptr<ColorSourceContents> color_source_contents,
365 const flutter::DlColorFilter* color_filter,
370 if (color_source_contents->IsSolidColor()) {
371 return FilterContents::MakeGaussianBlur(
372 FilterInput::Make(color_source_contents), sigma, sigma,
373 Entity::TileMode::kDecal, style, color_source_contents->GetGeometry());
378 auto mask = std::make_shared<SolidColorContents>();
379 mask->SetColor(Color::White());
380 mask->SetGeometry(color_source_contents->GetGeometry());
384 auto blurred_mask = FilterContents::MakeGaussianBlur(
385 FilterInput::Make(mask), sigma, sigma, Entity::TileMode::kDecal, style,
386 color_source_contents->GetGeometry());
392 auto expanded_local_bounds = blurred_mask->GetCoverage({});
393 if (!expanded_local_bounds.has_value()) {
394 expanded_local_bounds =
Rect();
396 *rect_geom =
RectGeometry(expanded_local_bounds.value());
397 color_source_contents->SetGeometry(rect_geom);
398 std::shared_ptr<Contents> color_contents = color_source_contents;
404 ColorFilterContents::AbsorbOpacity::kYes);
409 ColorFilterContents::AbsorbOpacity::kYes);
414 return ColorFilterContents::MakeBlend(
415 BlendMode::kSourceIn,
416 {FilterInput::Make(blurred_mask), FilterInput::Make(color_contents)});
419 std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
422 const Matrix& ctm)
const {
423 Vector2 blur_sigma(sigma.sigma, sigma.sigma);
428 if (is_solid_color) {
429 return FilterContents::MakeGaussianBlur(input,
Sigma(blur_sigma.
x),
431 Entity::TileMode::kDecal, style);
433 return FilterContents::MakeBorderMaskBlur(input,
Sigma(blur_sigma.
x),
434 Sigma(blur_sigma.
y), style);
437 bool Paint::HasColorFilter()
const {
438 return color_filter || invert_colors;
@ kSubpassPrependSnapshotTransform
std::function< std::shared_ptr< ColorFilterContents >(FilterInput::Ref)> ColorFilterProc
void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
std::shared_ptr< ColorFilterContents > WrapWithGPUColorFilter(const flutter::DlColorFilter *filter, const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
std::shared_ptr< FilterContents > WrapInput(const flutter::DlImageFilter *filter, const FilterInput::Ref &input)
Generate a new FilterContents using this filter's configuration.
std::shared_ptr< ColorFilterContents > WrapWithInvertColors(const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
static constexpr const ColorMatrix kColorInversion
A color matrix which inverts colors.
flutter::DlScalar DlScalar
Color ApplyColorMatrix(const ColorMatrix &color_matrix) const
A color filter that transforms colors through a 4x5 color matrix.
A 4x4 matrix using column-major storage.
constexpr Vector3 GetBasisY() const
constexpr Vector3 GetBasisX() const
std::shared_ptr< Contents > WithFilters(std::shared_ptr< Contents > input) const
Wrap this paint's configured filters to the given contents.
const flutter::DlColorFilter * color_filter
const flutter::DlColorSource * color_source
const flutter::DlImageFilter * image_filter
std::shared_ptr< Contents > WithMaskBlur(std::shared_ptr< Contents > input, bool is_solid_color, const Matrix &ctm) const
std::optional< MaskBlurDescriptor > mask_blur_descriptor
std::shared_ptr< Contents > WithFiltersForSubpassTarget(std::shared_ptr< Contents > input, const Matrix &effect_transform=Matrix()) const
Wrap this paint's configured filters to the given contents of subpass target.
std::shared_ptr< FilterContents > WithImageFilter(const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
std::shared_ptr< ColorSourceContents > CreateContents() const
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
constexpr static std::optional< TRect > MakePointBounds(const U &value)
constexpr TSize Ceil() const
constexpr Scalar GetLength() const