@@ -34,21 +34,32 @@ std::shared_ptr<Contents> Paint::CreateContentsForEntity(const Path& path,
3434std::shared_ptr<Contents> Paint::CreateContentsForGeometry (
3535 std::shared_ptr<Geometry> geometry) const {
3636 auto contents = color_source.GetContents (*this );
37+
38+ // Attempt to apply the color filter on the CPU first.
39+ // Note: This is not just an optimization; some color sources rely on
40+ // CPU-applied color filters to behave properly.
41+ bool needs_color_filter = !!color_filter;
42+ if (color_filter &&
43+ contents->ApplyColorFilter (color_filter->GetCPUColorFilterProc ())) {
44+ needs_color_filter = false ;
45+ }
46+
3747 contents->SetGeometry (std::move (geometry));
3848 if (mask_blur_descriptor.has_value ()) {
39- return mask_blur_descriptor->CreateMaskBlur (contents);
49+ // If there's a mask blur and we need to apply the color filter on the GPU,
50+ // we need to be careful to only apply the color filter to the source
51+ // colors. CreateMaskBlur is able to handle this case.
52+ return mask_blur_descriptor->CreateMaskBlur (
53+ contents, needs_color_filter ? color_filter : nullptr );
4054 }
55+
4156 return contents;
4257}
4358
4459std::shared_ptr<Contents> Paint::WithFilters (
45- std::shared_ptr<Contents> input,
46- std::optional<bool > is_solid_color) const {
47- bool is_solid_color_val = is_solid_color.value_or (color_source.GetType () ==
48- ColorSource::Type::kColor );
60+ std::shared_ptr<Contents> input) const {
4961 input = WithColorFilter (input, /* absorb_opacity=*/ true );
5062 input = WithInvertFilter (input);
51- input = WithMaskBlur (input, is_solid_color_val);
5263 input = WithImageFilter (input, Matrix (), /* is_subpass=*/ false );
5364 return input;
5465}
@@ -128,7 +139,16 @@ std::shared_ptr<Contents> Paint::WithInvertFilter(
128139}
129140
130141std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur (
131- std::shared_ptr<ColorSourceContents> color_source_contents) const {
142+ std::shared_ptr<ColorSourceContents> color_source_contents,
143+ const std::shared_ptr<ColorFilter>& color_filter) const {
144+ // If it's a solid color and there is no color filter, then we can just get
145+ // away with doing one Gaussian blur.
146+ if (color_source_contents->IsSolidColor () && !color_filter) {
147+ return FilterContents::MakeGaussianBlur (
148+ FilterInput::Make (color_source_contents), sigma, sigma, style,
149+ Entity::TileMode::kDecal , Matrix ());
150+ }
151+
132152 // / 1. Create an opaque white mask of the original geometry.
133153
134154 auto mask = std::make_shared<SolidColorContents>();
@@ -152,11 +172,20 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
152172 color_source_contents->SetGeometry (
153173 Geometry::MakeRect (*expanded_local_bounds));
154174
155- // / 4. Composite the color source and mask together.
175+ std::shared_ptr<Contents> color_contents = color_source_contents;
176+
177+ // / 4. Apply the user set color filter on the GPU, if applicable.
178+
179+ if (color_filter) {
180+ color_contents = color_filter.WrapWithGPUColorFilter (
181+ FilterInput::Make (color_source_contents), true );
182+ }
183+
184+ // / 5. Composite the color source with the blurred mask.
156185
157186 return ColorFilterContents::MakeBlend (
158- BlendMode::kSourceIn , { FilterInput::Make (blurred_mask),
159- FilterInput::Make (color_source_contents )});
187+ BlendMode::kSourceIn ,
188+ { FilterInput::Make (blurred_mask), FilterInput::Make (color_contents )});
160189}
161190
162191std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur (
0 commit comments