From cf0ff1698a840e95df7bfac7cae3146cbf643f40 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 15 Sep 2022 10:28:03 -0700 Subject: [PATCH 1/3] Ensure pre-rolled opacity children see snapped matrix --- flow/layers/opacity_layer.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index eba8bf828e2c7..155c20e8733cf 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -42,6 +42,9 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkMatrix child_matrix = matrix; child_matrix.preTranslate(offset_.fX, offset_.fY); + if (context->raster_cache) { + child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); + } // Similar to what's done in TransformLayer::Preroll, we have to apply the // reverse transformation to the cull rect to properly cull child layers. @@ -52,7 +55,7 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { context->mutators_stack.PushOpacity(alpha_); AutoCache auto_cache = - AutoCache(layer_raster_cache_item_.get(), context, matrix); + AutoCache(layer_raster_cache_item_.get(), context, child_matrix); Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context); From 8ee1b8088d99a6286f88850e0cf8f4a3c94b737c Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 15 Sep 2022 12:05:40 -0700 Subject: [PATCH 2/3] ++ --- flow/layers/opacity_layer_unittests.cc | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc index cf7fe4715f343..9048710571af2 100644 --- a/flow/layers/opacity_layer_unittests.cc +++ b/flow/layers/opacity_layer_unittests.cc @@ -8,6 +8,7 @@ #include "flutter/flow/layers/image_filter_layer.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/layers/transform_layer.h" +#include "flutter/flow/raster_cache_util.h" #include "flutter/flow/testing/diff_context_test.h" #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" @@ -662,5 +663,42 @@ TEST_F(OpacityLayerDiffTest, FractionalTranslationWithRasterCache) { EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(11, 11, 61, 61)); } +TEST_F(OpacityLayerTest, FullyOpaqueWithFractionalValues) { + use_mock_raster_cache(); // Ensure non-fractional alignment. + + const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f)); + const SkPoint layer_offset = SkPoint::Make(0.5f, 1.5f); + const SkMatrix initial_transform = SkMatrix::Translate(0.5f, 0.5f); + const SkMatrix layer_transform = + SkMatrix::Translate(layer_offset.fX, layer_offset.fY); + const SkPaint child_paint = SkPaint(SkColors::kGreen); + const SkRect expected_layer_bounds = + layer_transform.mapRect(child_path.getBounds()); + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = std::make_shared(SK_AlphaOPAQUE, layer_offset); + layer->Add(mock_layer); + layer->Preroll(preroll_context(), initial_transform); + + const SkPaint opacity_paint = SkPaint(SkColors::kBlack); // A = 1.0f + SkRect opacity_bounds; + expected_layer_bounds.makeOffset(-layer_offset.fX, -layer_offset.fY) + .roundOut(&opacity_bounds); + auto expected_draw_calls = + std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SetMatrixData{SkM44(RasterCacheUtil::GetIntegralTransCTM(layer_transform))}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SaveLayerData{opacity_bounds, + opacity_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); + layer->Paint(paint_context()); + EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); +} + } // namespace testing } // namespace flutter From 5ea9c311980841e3004354cf06b9e6344dd83a1c Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 15 Sep 2022 12:37:21 -0700 Subject: [PATCH 3/3] ++ --- flow/layers/opacity_layer_unittests.cc | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc index 9048710571af2..84a8ef29cd5a5 100644 --- a/flow/layers/opacity_layer_unittests.cc +++ b/flow/layers/opacity_layer_unittests.cc @@ -683,19 +683,20 @@ TEST_F(OpacityLayerTest, FullyOpaqueWithFractionalValues) { SkRect opacity_bounds; expected_layer_bounds.makeOffset(-layer_offset.fX, -layer_offset.fY) .roundOut(&opacity_bounds); - auto expected_draw_calls = - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{SkM44(RasterCacheUtil::GetIntegralTransCTM(layer_transform))}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{opacity_bounds, - opacity_paint, nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); + auto expected_draw_calls = std::vector( + {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SetMatrixData{SkM44( + RasterCacheUtil::GetIntegralTransCTM(layer_transform))}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr, + 2}}, + MockCanvas::DrawCall{2, + MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); layer->Paint(paint_context()); EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); }