[Impeller] Do not apply mask filters to a DrawPaint cover geometry (#51670)

The DisplayListBuilder only updates the paint attributes that are relevant to a given operation.  DrawPaint does not support mask filters, so DisplayListBuilder::DrawPaint will not modify the mask filter state. So a call to DrawPaint in the display list dispatcher may receive a paint containing a mask filter set by a previous call.

Aiks Canvas::DrawPaint should ignore any mask filter set on the paint (matching the spec for Skia's SkCanvas::drawPaint)

Fixes https://github.com/flutter/flutter/issues/145442
diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc
index 1e3fe38..22a6984 100644
--- a/impeller/aiks/canvas.cc
+++ b/impeller/aiks/canvas.cc
@@ -44,8 +44,10 @@
     }
   }
 
+  bool can_apply_mask_filter = geometry->CanApplyMaskFilter();
   contents->SetGeometry(std::move(geometry));
-  if (paint.mask_blur_descriptor.has_value()) {
+
+  if (can_apply_mask_filter && paint.mask_blur_descriptor.has_value()) {
     // If there's a mask blur and we need to apply the color filter on the GPU,
     // we need to be careful to only apply the color filter to the source
     // colors. CreateMaskBlur is able to handle this case.
diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc
index 5da4606..b10f554 100644
--- a/impeller/display_list/dl_unittests.cc
+++ b/impeller/display_list/dl_unittests.cc
@@ -1834,5 +1834,28 @@
 }
 #endif
 
+TEST_P(DisplayListTest, DrawPaintIgnoresMaskFilter) {
+  flutter::DisplayListBuilder builder;
+  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
+
+  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
+  builder.DrawCircle({300, 300}, 200,
+                     flutter::DlPaint().setMaskFilter(&filter));
+
+  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
+                                          flutter::DlColor::kGreen()};
+  const float stops[2] = {0.0, 1.0};
+  auto linear = flutter::DlColorSource::MakeLinear(
+      {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
+      flutter::DlTileMode::kRepeat);
+  flutter::DlPaint blend_paint =
+      flutter::DlPaint()           //
+          .setColorSource(linear)  //
+          .setBlendMode(flutter::DlBlendMode::kScreen);
+  builder.DrawPaint(blend_paint);
+
+  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
+}
+
 }  // namespace testing
 }  // namespace impeller
diff --git a/impeller/entity/geometry/cover_geometry.cc b/impeller/entity/geometry/cover_geometry.cc
index 62c97c0..488976e 100644
--- a/impeller/entity/geometry/cover_geometry.cc
+++ b/impeller/entity/geometry/cover_geometry.cc
@@ -58,4 +58,8 @@
   return true;
 }
 
+bool CoverGeometry::CanApplyMaskFilter() const {
+  return false;
+}
+
 }  // namespace impeller
diff --git a/impeller/entity/geometry/cover_geometry.h b/impeller/entity/geometry/cover_geometry.h
index 3d76756..e9f5653 100644
--- a/impeller/entity/geometry/cover_geometry.h
+++ b/impeller/entity/geometry/cover_geometry.h
@@ -20,6 +20,8 @@
   // |Geometry|
   bool CoversArea(const Matrix& transform, const Rect& rect) const override;
 
+  bool CanApplyMaskFilter() const override;
+
  private:
   // |Geometry|
   GeometryResult GetPositionBuffer(const ContentContext& renderer,
diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc
index 772c0cb..ce4b72d 100644
--- a/impeller/entity/geometry/geometry.cc
+++ b/impeller/entity/geometry/geometry.cc
@@ -240,4 +240,8 @@
   return false;
 }
 
+bool Geometry::CanApplyMaskFilter() const {
+  return true;
+}
+
 }  // namespace impeller
diff --git a/impeller/entity/geometry/geometry.h b/impeller/entity/geometry/geometry.h
index ae30159..5144ead 100644
--- a/impeller/entity/geometry/geometry.h
+++ b/impeller/entity/geometry/geometry.h
@@ -148,6 +148,8 @@
 
   virtual bool IsAxisAlignedRect() const;
 
+  virtual bool CanApplyMaskFilter() const;
+
  protected:
   static GeometryResult ComputePositionGeometry(
       const ContentContext& renderer,