From 701313987f2cea675cc9be41d79154493ab42f9d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 6 Jul 2023 12:47:55 -0700 Subject: [PATCH 1/4] Handle nested display list clips in Impeller dispatcher (#43442) 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 --- impeller/display_list/display_list_dispatcher.cc | 4 ++++ impeller/display_list/display_list_unittests.cc | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 88f9bc593c30a..95558f3f23004 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -1252,6 +1252,10 @@ void DisplayListDispatcher::drawDisplayList( 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 5164897af68fa..67d1417bbe14c 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -45,6 +45,19 @@ flutter::DlColor toColor(const float* components) { using DisplayListTest = DisplayListPlayground; INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); +TEST_P(DisplayListTest, DrawPictureWithAClip) { + flutter::DisplayListBuilder sub_builder; + sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24)); + 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), From eab90216807a1b84a186886ebcf080610c4e41cf Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 7 Jul 2023 14:07:05 -0700 Subject: [PATCH 2/4] provide arguments --- impeller/display_list/display_list_unittests.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 67d1417bbe14c..3a87257d7d138 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -47,7 +47,8 @@ INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); TEST_P(DisplayListTest, DrawPictureWithAClip) { flutter::DisplayListBuilder sub_builder; - sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24)); + sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24), ClipOp::kIntersect, + /*is_aa=*/false); sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue())); auto display_list = sub_builder.Build(); From 4e51810b6cdc082dcae98157add198ecccadbdf5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jul 2023 11:13:34 -0700 Subject: [PATCH 3/4] missing ns --- impeller/display_list/display_list_unittests.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 3a87257d7d138..23ae8cd2360ae 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -47,7 +47,8 @@ INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); TEST_P(DisplayListTest, DrawPictureWithAClip) { flutter::DisplayListBuilder sub_builder; - sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24), ClipOp::kIntersect, + sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24), + flutter::ClipOp::kIntersect, /*is_aa=*/false); sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue())); From 74af468968814d0b1bb714ba36fbf69f87e9c82b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jul 2023 11:25:47 -0700 Subject: [PATCH 4/4] Update display_list_unittests.cc --- impeller/display_list/display_list_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 23ae8cd2360ae..9364279fc6597 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -48,7 +48,7 @@ INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); TEST_P(DisplayListTest, DrawPictureWithAClip) { flutter::DisplayListBuilder sub_builder; sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24), - flutter::ClipOp::kIntersect, + flutter::DlCanvas::ClipOp::kIntersect, /*is_aa=*/false); sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue()));