From dee0ae590f5ef48c468c77119d5cda736164902d Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Wed, 15 Mar 2023 17:30:22 +0800 Subject: [PATCH] [Impeller] Make matrix image filters work as expected with nested saving layers (#40299) [Impeller] Make matrix image filters work as expected with nested saving layers --- .../display_list/display_list_unittests.cc | 82 ++++++++++++------- impeller/entity/entity_pass.cc | 3 +- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index b413023c965e1..848f84fe84fdf 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -1076,36 +1076,60 @@ TEST_P(DisplayListTest, CanDrawWithMatrixFilter) { } TEST_P(DisplayListTest, CanDrawWithMatrixFilterWhenSavingLayer) { - flutter::DisplayListBuilder builder; - builder.Save(); - builder.Scale(2.0, 2.0); - flutter::DlPaint paint; - paint.setColor(flutter::DlColor::kYellow()); - builder.DrawRect(SkRect::MakeWH(300, 300), paint); - paint.setStrokeWidth(1.0); - paint.setDrawStyle(flutter::DlDrawStyle::kStroke); - paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80)); - builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint); - builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint); - - SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100); - flutter::DlPaint save_paint; - SkMatrix filter_matrix = SkMatrix::I(); - filter_matrix.postTranslate(-150, -150); - filter_matrix.postScale(0.2f, 0.2f); - filter_matrix.postTranslate(150, 150); - - auto filter = flutter::DlMatrixImageFilter( - filter_matrix, flutter::DlImageSampling::kNearestNeighbor); - save_paint.setImageFilter(filter.shared()); - - builder.SaveLayer(&bounds, &save_paint); - flutter::DlPaint paint2; - paint2.setColor(flutter::DlColor::kBlue()); - builder.DrawRect(bounds, paint2); - builder.Restore(); + auto callback = [&]() { + static float translation[2] = {0, 0}; + static bool enable_save_layer = true; - ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); + ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); + ImGui::SliderFloat2("Translation", translation, -130, 130); + ImGui::Checkbox("Enable save layer", &enable_save_layer); + ImGui::End(); + + flutter::DisplayListBuilder builder; + builder.Save(); + builder.Scale(2.0, 2.0); + flutter::DlPaint paint; + paint.setColor(flutter::DlColor::kYellow()); + builder.DrawRect(SkRect::MakeWH(300, 300), paint); + paint.setStrokeWidth(1.0); + paint.setDrawStyle(flutter::DlDrawStyle::kStroke); + paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80)); + builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint); + builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint); + + flutter::DlPaint save_paint; + SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100); + SkMatrix translate_matrix = + SkMatrix::Translate(translation[0], translation[1]); + if (enable_save_layer) { + auto filter = flutter::DlMatrixImageFilter( + translate_matrix, flutter::DlImageSampling::kNearestNeighbor); + save_paint.setImageFilter(filter.shared()); + builder.SaveLayer(&bounds, &save_paint); + } else { + builder.Save(); + builder.Transform(translate_matrix); + } + + SkMatrix filter_matrix = SkMatrix::I(); + filter_matrix.postTranslate(-150, -150); + filter_matrix.postScale(0.2f, 0.2f); + filter_matrix.postTranslate(150, 150); + auto filter = flutter::DlMatrixImageFilter( + filter_matrix, flutter::DlImageSampling::kNearestNeighbor); + + save_paint.setImageFilter(filter.shared()); + + builder.SaveLayer(&bounds, &save_paint); + flutter::DlPaint paint2; + paint2.setColor(flutter::DlColor::kBlue()); + builder.DrawRect(bounds, paint2); + builder.Restore(); + builder.Restore(); + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); } TEST_P(DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter) { diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index e28e14a22120b..efa4ffc345f75 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -358,7 +358,8 @@ EntityPass::EntityResult EntityPass::GetEntityForElement( auto offscreen_texture_contents = subpass->delegate_->CreateContentsForSubpassTarget( - subpass_texture, subpass->xformation_); + subpass_texture, + Matrix::MakeTranslation(Vector3{-position}) * subpass->xformation_); if (!offscreen_texture_contents) { // This is an error because the subpass delegate said the pass couldn't