[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
diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc
index b413023..848f84f 100644
--- a/impeller/display_list/display_list_unittests.cc
+++ b/impeller/display_list/display_list_unittests.cc
@@ -1076,36 +1076,60 @@
}
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);
+ auto callback = [&]() {
+ static float translation[2] = {0, 0};
+ static bool enable_save_layer = true;
- 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);
+ ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
+ ImGui::SliderFloat2("Translation", translation, -130, 130);
+ ImGui::Checkbox("Enable save layer", &enable_save_layer);
+ ImGui::End();
- auto filter = flutter::DlMatrixImageFilter(
- filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
- save_paint.setImageFilter(filter.shared());
+ 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);
- builder.SaveLayer(&bounds, &save_paint);
- flutter::DlPaint paint2;
- paint2.setColor(flutter::DlColor::kBlue());
- builder.DrawRect(bounds, paint2);
- builder.Restore();
+ 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);
+ }
- ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
+ 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 e28e14a..efa4ffc 100644
--- a/impeller/entity/entity_pass.cc
+++ b/impeller/entity/entity_pass.cc
@@ -358,7 +358,8 @@
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