11 #include "flutter/display_list/effects/dl_color_filter.h"
12 #include "flutter/display_list/effects/dl_color_sources.h"
13 #include "flutter/display_list/geometry/dl_path.h"
14 #include "fml/logging.h"
40 std::vector<Color>& colors,
41 std::vector<float>& stops) {
42 FML_DCHECK(gradient->stop_count() >= 2)
43 <<
"stop_count:" << gradient->stop_count();
45 auto* dl_colors = gradient->colors();
46 auto* dl_stops = gradient->stops();
47 if (dl_stops[0] != 0.0) {
49 stops.emplace_back(0);
51 for (
auto i = 0; i < gradient->stop_count(); i++) {
53 stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
55 if (dl_stops[gradient->stop_count() - 1] != 1.0) {
56 colors.emplace_back(colors.back());
57 stops.emplace_back(1.0);
59 for (
auto i = 1; i < gradient->stop_count(); i++) {
60 stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
67 const std::optional<Matrix>& geometry_transform)
const {
69 auto contents = std::make_shared<SolidColorContents>(geometry);
70 contents->SetColor(
color);
74 Matrix inverted_geometry_transform =
75 geometry_transform.has_value() ? geometry_transform->
Invert() :
Matrix();
78 case flutter::DlColorSourceType::kLinearGradient: {
79 const flutter::DlLinearGradientColorSource* linear =
82 auto start_point = linear->start_point();
83 auto end_point = linear->end_point();
84 std::vector<Color> colors;
85 std::vector<float> stops;
89 auto effect_transform = linear->matrix();
91 auto contents = std::make_shared<LinearGradientContents>(geometry);
93 contents->SetColors(std::move(colors));
94 contents->SetStops(std::move(stops));
95 contents->SetEndPoints(start_point, end_point);
96 contents->SetTileMode(tile_mode);
97 contents->SetEffectTransform(inverted_geometry_transform *
100 std::array<Point, 2> bounds{start_point, end_point};
102 if (intrinsic_size.has_value()) {
103 contents->SetColorSourceSize(intrinsic_size->GetSize().Max({1, 1}));
107 case flutter::DlColorSourceType::kRadialGradient: {
108 const flutter::DlRadialGradientColorSource* radialGradient =
110 FML_DCHECK(radialGradient);
111 auto center = radialGradient->center();
112 auto radius = radialGradient->radius();
113 std::vector<Color> colors;
114 std::vector<float> stops;
119 auto effect_transform = radialGradient->matrix();
121 auto contents = std::make_shared<RadialGradientContents>(geometry);
123 contents->SetColors(std::move(colors));
124 contents->SetStops(std::move(stops));
125 contents->SetCenterAndRadius(center, radius);
126 contents->SetTileMode(tile_mode);
127 contents->SetEffectTransform(inverted_geometry_transform *
131 contents->SetColorSourceSize(intrinsic_size.GetSize().Max({1, 1}));
134 case flutter::DlColorSourceType::kConicalGradient: {
135 const flutter::DlConicalGradientColorSource* conical_gradient =
137 FML_DCHECK(conical_gradient);
138 Point center = conical_gradient->end_center();
139 DlScalar radius = conical_gradient->end_radius();
140 Point focus_center = conical_gradient->start_center();
141 DlScalar focus_radius = conical_gradient->start_radius();
142 std::vector<Color> colors;
143 std::vector<float> stops;
148 auto effect_transform = conical_gradient->matrix();
150 auto contents = std::make_shared<ConicalGradientContents>(geometry);
152 contents->SetColors(std::move(colors));
153 contents->SetStops(std::move(stops));
154 contents->SetCenterAndRadius(center, radius);
155 contents->SetTileMode(tile_mode);
156 contents->SetEffectTransform(inverted_geometry_transform *
158 contents->SetFocus(focus_center, focus_radius);
161 contents->SetColorSourceSize(intrinsic_size.GetSize().Max({1, 1}));
164 case flutter::DlColorSourceType::kSweepGradient: {
165 const flutter::DlSweepGradientColorSource* sweepGradient =
167 FML_DCHECK(sweepGradient);
169 auto center = sweepGradient->center();
170 auto start_angle =
Degrees(sweepGradient->start());
171 auto end_angle =
Degrees(sweepGradient->end());
172 std::vector<Color> colors;
173 std::vector<float> stops;
178 auto effect_transform = sweepGradient->matrix();
180 auto contents = std::make_shared<SweepGradientContents>(geometry);
182 contents->SetCenterAndAngles(center, start_angle, end_angle);
183 contents->SetColors(std::move(colors));
184 contents->SetStops(std::move(stops));
185 contents->SetTileMode(tile_mode);
186 contents->SetEffectTransform(inverted_geometry_transform *
191 case flutter::DlColorSourceType::kImage: {
192 const flutter::DlImageColorSource* image_color_source =
194 FML_DCHECK(image_color_source);
196 image_color_source->image()->asImpellerImage()->GetCachedTexture(
200 image_color_source->horizontal_tile_mode());
202 image_color_source->vertical_tile_mode());
203 auto sampler_descriptor =
206 flutter::DlMatrix effect_transform = image_color_source->matrix().To3x3();
208 auto contents = std::make_shared<TiledTextureContents>(geometry);
210 contents->SetTexture(texture);
211 contents->SetTileModes(x_tile_mode, y_tile_mode);
212 contents->SetSamplerDescriptor(sampler_descriptor);
213 contents->SetEffectTransform(inverted_geometry_transform *
220 std::shared_ptr<FilterContents> color_filter_output =
236 contents->SetColorFilter(filter_proc);
238 contents->SetColorSourceSize(
Size::Ceil(texture->GetSize()));
241 case flutter::DlColorSourceType::kRuntimeEffect: {
242 const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
245 runtime_effect_color_source->runtime_effect()->runtime_stage();
246 auto uniform_data = runtime_effect_color_source->uniform_data();
247 auto samplers = runtime_effect_color_source->samplers();
249 std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
251 for (
auto& sampler : samplers) {
252 if (sampler ==
nullptr) {
254 auto contents = std::make_shared<SolidColorContents>(geometry);
258 auto* image = sampler->asImage();
259 if (!sampler->asImage()) {
261 auto contents = std::make_shared<SolidColorContents>(geometry);
266 image->image()->asImpellerImage()->GetCachedTexture(renderer);
268 texture_inputs.push_back({
269 .sampler_descriptor =
271 .texture = std::move(texture),
275 auto contents = std::make_shared<RuntimeEffectContents>(geometry);
277 contents->SetRuntimeStage(std::move(runtime_stage));
278 contents->SetUniformData(std::move(uniform_data));
279 contents->SetTextureInputs(std::move(texture_inputs));
288 std::shared_ptr<Contents> input)
const {
300 std::shared_ptr<Contents> input,
301 const Matrix& effect_transform)
const {
314 const Matrix& ctm)
const {
317 is_solid_color, ctm);
325 const Matrix& effect_transform,
331 filter->SetRenderingMode(rendering_mode);
332 filter->SetEffectTransform(effect_transform);
336 std::shared_ptr<Contents> Paint::WithColorFilter(
337 std::shared_ptr<Contents> input,
342 color_source->type() == flutter::DlColorSourceType::kImage) {
353 if (input->ApplyColorFilter([&](Color
color) -> Color {
355 color = GetCPUColorFilterProc(color_filter)(color);
376 std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
377 std::shared_ptr<TextureContents> texture_contents,
379 Scalar expand_amount = GaussianBlurFilterContents::CalculateBlurRadius(
380 GaussianBlurFilterContents::ScaleSigma(sigma.sigma));
381 texture_contents->SetSourceRect(
382 texture_contents->GetSourceRect().Expand(expand_amount, expand_amount));
383 std::optional<Rect> coverage = texture_contents->GetCoverage({});
386 texture_contents->SetDestinationRect(
387 coverage.value().Expand(expand_amount, expand_amount));
389 geometry = rect_geom;
391 auto mask = std::make_shared<SolidColorContents>(geometry);
392 mask->SetColor(Color::White());
393 auto descriptor = texture_contents->GetSamplerDescriptor();
394 texture_contents->SetSamplerDescriptor(descriptor);
395 std::shared_ptr<FilterContents> blurred_mask =
396 FilterContents::MakeGaussianBlur(
397 FilterInput::Make(mask), sigma, sigma, Entity::TileMode::kDecal,
398 std::nullopt, style, geometry);
400 return ColorFilterContents::MakeBlend(
402 {FilterInput::Make(blurred_mask), FilterInput::Make(texture_contents)});
405 std::shared_ptr<Contents> Paint::MaskBlurDescriptor::CreateMaskBlur(
409 std::shared_ptr<ColorSourceContents> contents,
410 bool needs_color_filter,
414 if (contents->IsSolidColor()) {
415 return FilterContents::MakeGaussianBlur(
416 FilterInput::Make(contents), sigma, sigma, Entity::TileMode::kDecal,
417 std::nullopt, style, geometry);
421 auto mask = std::make_shared<SolidColorContents>(geometry);
422 mask->SetColor(Color::White());
425 auto blurred_mask = FilterContents::MakeGaussianBlur(
426 FilterInput::Make(mask), sigma, sigma, Entity::TileMode::kDecal,
427 std::nullopt, style, geometry);
432 std::optional<Rect> expanded_local_bounds = blurred_mask->GetCoverage({});
433 if (!expanded_local_bounds.has_value()) {
434 expanded_local_bounds =
Rect();
438 std::shared_ptr<ColorSourceContents> expanded_contents =
440 std::shared_ptr<Contents> final_contents = expanded_contents;
443 if (needs_color_filter) {
446 paint.
color_filter, FilterInput::Make(std::move(final_contents)),
447 ColorFilterContents::AbsorbOpacity::kYes);
452 ColorFilterContents::AbsorbOpacity::kYes);
457 return ColorFilterContents::MakeBlend(
459 {FilterInput::Make(blurred_mask), FilterInput::Make(final_contents)});
462 std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
465 const Matrix& ctm)
const {
466 Vector2 blur_sigma(sigma.sigma, sigma.sigma);
471 if (is_solid_color) {
472 return FilterContents::MakeGaussianBlur(
474 Entity::TileMode::kDecal, std::nullopt, style);
476 return FilterContents::MakeBorderMaskBlur(input,
Sigma(blur_sigma.
x),
477 Sigma(blur_sigma.
y), style);
480 bool Paint::HasColorFilter()
const {
481 return color_filter || invert_colors;
@ kSubpassPrependSnapshotTransform
std::function< std::shared_ptr< ColorFilterContents >(FilterInput::Ref)> ColorFilterProc
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Color ToColor(const flutter::DlColor &color)
std::shared_ptr< ColorFilterContents > WrapWithGPUColorFilter(const flutter::DlColorFilter *filter, const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
std::shared_ptr< ColorFilterContents > WrapWithInvertColors(const std::shared_ptr< FilterInput > &input, ColorFilterContents::AbsorbOpacity absorb_opacity)
std::shared_ptr< FilterContents > WrapInput(const ContentContext &renderer, const flutter::DlImageFilter *filter, const FilterInput::Ref &input)
Generate a new FilterContents using this filter's configuration.
static constexpr const ColorMatrix kColorInversion
A color matrix which inverts colors.
flutter::DlScalar DlScalar
static constexpr Color BlackTransparent()
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< FilterContents > WithImageFilter(const ContentContext &renderer, const FilterInput::Variant &input, const Matrix &effect_transform, Entity::RenderingMode rendering_mode) const
const flutter::DlColorFilter * color_filter
std::shared_ptr< Contents > WithFiltersForSubpassTarget(const ContentContext &renderer, std::shared_ptr< Contents > input, const Matrix &effect_transform=Matrix()) const
Wrap this paint's configured filters to the given contents of subpass target.
const flutter::DlColorSource * color_source
static 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...
const flutter::DlImageFilter * image_filter
std::shared_ptr< Contents > WithFilters(const ContentContext &renderer, std::shared_ptr< Contents > input) const
Wrap this paint's configured filters to the given contents.
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< ColorSourceContents > CreateContents(const ContentContext &renderer, const Geometry *geometry, const std::optional< Matrix > &geometry_transform=std::nullopt) const
Create a ColorSourceContents representing this paint's shader/colors.
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
constexpr static TRect MakeCircleBounds(const TPoint< Type > ¢er, Type radius)
constexpr static std::optional< TRect > MakePointBounds(const U &value)
constexpr TSize Ceil() const