Handle nested display list clips in Impeller dispatcher (#43442) (#43469)

CP issue: https://github.com/flutter/flutter/issues/130149

Fixes https://github.com/flutter/flutter/issues/130084

If a display list is drawn into another display list and the child display list establishes a small clip, subsequent drawing operations are discarded when really they should not be.

The test is expected to render both a blue and a red square; before the fix it renders only the blue square since the red square is incorrectly clipped out.

See also https://github.com/dnfield/flutter_svg/issues/938
diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc
index 88f9bc5..95558f3 100644
--- a/impeller/display_list/display_list_dispatcher.cc
+++ b/impeller/display_list/display_list_dispatcher.cc
@@ -1252,6 +1252,10 @@
   Matrix saved_initial_matrix = initial_matrix_;
   int restore_count = canvas_.GetSaveCount();
 
+  // The display list may alter the clip, which must be restored to the current
+  // clip at the end of playback.
+  canvas_.Save();
+
   // Establish a new baseline for interpreting the new DL.
   // Matrix and clip are left untouched, the current
   // transform is saved as the new base matrix, and paint
diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc
index 5164897..9364279 100644
--- a/impeller/display_list/display_list_unittests.cc
+++ b/impeller/display_list/display_list_unittests.cc
@@ -45,6 +45,21 @@
 using DisplayListTest = DisplayListPlayground;
 INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest);
 
+TEST_P(DisplayListTest, DrawPictureWithAClip) {
+  flutter::DisplayListBuilder sub_builder;
+  sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24),
+                       flutter::DlCanvas::ClipOp::kIntersect,
+                       /*is_aa=*/false);
+  sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue()));
+
+  auto display_list = sub_builder.Build();
+  flutter::DisplayListBuilder builder;
+  builder.DrawDisplayList(display_list);
+  builder.DrawRect(SkRect::MakeXYWH(30, 30, 24, 24),
+                   flutter::DlPaint(flutter::DlColor::kRed()));
+  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
+}
+
 TEST_P(DisplayListTest, CanDrawRect) {
   flutter::DisplayListBuilder builder;
   builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),