[impeller] dont apply opacity peephole on image/color filters (#40551)

[impeller] dont apply opacity peephole on image/color filters
diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc
index 50d09c9..5f6ea34 100644
--- a/impeller/aiks/aiks_unittests.cc
+++ b/impeller/aiks/aiks_unittests.cc
@@ -15,9 +15,11 @@
 #include "impeller/aiks/aiks_playground.h"
 #include "impeller/aiks/canvas.h"
 #include "impeller/aiks/image.h"
+#include "impeller/aiks/paint_pass_delegate.h"
 #include "impeller/entity/contents/color_source_contents.h"
 #include "impeller/entity/contents/filters/inputs/filter_input.h"
 #include "impeller/entity/contents/scene_contents.h"
+#include "impeller/entity/contents/solid_color_contents.h"
 #include "impeller/entity/contents/tiled_texture_contents.h"
 #include "impeller/geometry/color.h"
 #include "impeller/geometry/constants.h"
@@ -1947,5 +1949,49 @@
   ASSERT_FALSE(paint.HasColorFilter());
 }
 
+TEST_P(AiksTest, OpacityPeepHoleApplicationTest) {
+  auto entity_pass = std::make_shared<EntityPass>();
+  auto rect = Rect::MakeLTRB(0, 0, 100, 100);
+  Paint paint;
+  paint.color = Color::White().WithAlpha(0.5);
+  paint.color_filter = [](FilterInput::Ref input) {
+    return ColorFilterContents::MakeBlend(BlendMode::kSourceOver,
+                                          {std::move(input)}, Color::Blue());
+  };
+
+  // Paint has color filter, can't elide.
+  auto delegate = std::make_shared<OpacityPeepholePassDelegate>(paint, rect);
+  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
+
+  paint.color_filter = std::nullopt;
+  paint.image_filter = [](const FilterInput::Ref& input,
+                          const Matrix& effect_transform, bool is_subpass) {
+    return FilterContents::MakeGaussianBlur(
+        input, Sigma(1.0), Sigma(1.0), FilterContents::BlurStyle::kNormal,
+        Entity::TileMode::kClamp, effect_transform);
+  };
+
+  // Paint has image filter, can't elide.
+  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint, rect);
+  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
+
+  paint.image_filter = std::nullopt;
+  paint.color = Color::Red();
+
+  // Paint has no alpha, can't elide;
+  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint, rect);
+  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
+
+  // Positive test.
+  Entity entity;
+  entity.SetContents(SolidColorContents::Make(
+      PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
+  entity_pass->AddEntity(entity);
+  paint.color = Color::Red().WithAlpha(0.5);
+
+  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint, rect);
+  ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
+}
+
 }  // namespace testing
 }  // namespace impeller
diff --git a/impeller/aiks/paint_pass_delegate.cc b/impeller/aiks/paint_pass_delegate.cc
index cbe66f7..c308a7f 100644
--- a/impeller/aiks/paint_pass_delegate.cc
+++ b/impeller/aiks/paint_pass_delegate.cc
@@ -72,6 +72,11 @@
 // |EntityPassDelgate|
 bool OpacityPeepholePassDelegate::CanCollapseIntoParentPass(
     EntityPass* entity_pass) {
+  if (paint_.color.alpha <= 0.0 || paint_.color.alpha >= 1.0 ||
+      paint_.image_filter.has_value() || paint_.color_filter.has_value()) {
+    return false;
+  }
+
   // Note: determing whether any coverage intersects has quadradic complexity in
   // the number of rectangles, and depending on whether or not we cache at
   // different levels of the entity tree may end up cubic. In the interest of