From 63de03930f6bc4f1fd65ba55a4bddc61fa9f3695 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Wed, 10 May 2023 01:14:31 -0700 Subject: [PATCH] switch from MockCanvas to DisplayListBuilder in layer unit tests --- display_list/display_list_unittests.cc | 16 ++ display_list/dl_builder.cc | 21 +- display_list/dl_builder.h | 12 +- .../layers/backdrop_filter_layer_unittests.cc | 198 ++++++++++---- flow/layers/clip_path_layer_unittests.cc | 49 ++-- flow/layers/clip_rect_layer_unittests.cc | 53 ++-- flow/layers/clip_rrect_layer_unittests.cc | 55 ++-- flow/layers/color_filter_layer_unittests.cc | 43 +-- flow/layers/container_layer_unittests.cc | 63 +++-- flow/layers/display_list_layer_unittests.cc | 24 +- flow/layers/image_filter_layer_unittests.cc | 192 +++++++------- flow/layers/layer_state_stack_unittests.cc | 9 +- flow/layers/opacity_layer_unittests.cc | 217 +++++++++------- flow/layers/shader_mask_layer_unittests.cc | 244 ++++++++++-------- flow/layers/transform_layer_unittests.cc | 133 ++++++---- flow/testing/layer_test.h | 12 +- testing/mock_canvas.h | 2 - 17 files changed, 781 insertions(+), 562 deletions(-) diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index f2e12f74d8d20..f63435acdd1a5 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -92,6 +92,22 @@ class DisplayListTestBase : public BaseT { }; using DisplayListTest = DisplayListTestBase<::testing::Test>; +TEST_F(DisplayListTest, EmptyBuild) { + DisplayListBuilder builder; + auto dl = builder.Build(); + EXPECT_EQ(dl->op_count(), 0u); + EXPECT_EQ(dl->bytes(), sizeof(DisplayList)); +} + +TEST_F(DisplayListTest, EmptyRebuild) { + DisplayListBuilder builder; + auto dl1 = builder.Build(); + auto dl2 = builder.Build(); + auto dl3 = builder.Build(); + ASSERT_TRUE(dl1->Equals(dl2)); + ASSERT_TRUE(dl2->Equals(dl3)); +} + TEST_F(DisplayListTest, BuilderCanBeReused) { DisplayListBuilder builder(kTestBounds); builder.DrawRect(kTestBounds, DlPaint()); diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index d48659426add3..731ac6307bc9c 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -578,15 +578,18 @@ void DisplayListBuilder::Transform2DAffine( SkScalar myx, SkScalar myy, SkScalar myt) { if (SkScalarsAreFinite(mxx, myx) && SkScalarsAreFinite(mxy, myy) && - SkScalarsAreFinite(mxt, myt) && - !(mxx == 1 && mxy == 0 && mxt == 0 && - myx == 0 && myy == 1 && myt == 0)) { - checkForDeferredSave(); - Push(0, 1, - mxx, mxy, mxt, - myx, myy, myt); - tracker_.transform2DAffine(mxx, mxy, mxt, - myx, myy, myt); + SkScalarsAreFinite(mxt, myt)) { + if (mxx == 1 && mxy == 0 && + myx == 0 && myy == 1) { + Translate(mxt, myt); + } else { + checkForDeferredSave(); + Push(0, 1, + mxx, mxy, mxt, + myx, myy, myt); + tracker_.transform2DAffine(mxx, mxy, mxt, + myx, myy, myt); + } } } // full 4x4 transform in row major order diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index e35e160e704dd..5a93f57eb525e 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -113,11 +113,17 @@ class DisplayListBuilder final : public virtual DlCanvas, SkMatrix GetTransform() const override { return tracker_.matrix_3x3(); } // |DlCanvas| - void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void ClipRect(const SkRect& rect, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) override; // |DlCanvas| - void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; + void ClipRRect(const SkRRect& rrect, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) override; // |DlCanvas| - void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; + void ClipPath(const SkPath& path, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) override; /// Conservative estimate of the bounds of all outstanding clip operations /// measured in the coordinate space within which this DisplayList will diff --git a/flow/layers/backdrop_filter_layer_unittests.cc b/flow/layers/backdrop_filter_layer_unittests.cc index c547a20b1f336..e73433889ff5d 100644 --- a/flow/layers/backdrop_filter_layer_unittests.cc +++ b/flow/layers/backdrop_filter_layer_unittests.cc @@ -11,9 +11,6 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" -#include "third_party/skia/include/core/SkImageFilter.h" -#include "third_party/skia/include/effects/SkImageFilters.h" namespace flutter { namespace testing { @@ -72,15 +69,30 @@ TEST_F(BackdropFilterLayerTest, EmptyFilter) { EXPECT_TRUE(layer->needs_painting(paint_context())); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, DlPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + parent->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)parent::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(child_bounds, DlCanvas::ClipOp::kIntersect, + false); + /* (BackdropFilter)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&child_bounds, nullptr, nullptr); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(BackdropFilterLayerTest, SimpleFilter) { @@ -104,15 +116,31 @@ TEST_F(BackdropFilterLayerTest, SimpleFilter) { EXPECT_TRUE(layer->needs_painting(paint_context())); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, DlPaint(), - layer_filter, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + parent->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)parent::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(child_bounds, DlCanvas::ClipOp::kIntersect, + false); + /* (BackdropFilter)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&child_bounds, nullptr, + layer_filter.get()); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(BackdropFilterLayerTest, NonSrcOverBlend) { @@ -139,15 +167,32 @@ TEST_F(BackdropFilterLayerTest, NonSrcOverBlend) { DlPaint filter_paint = DlPaint(); filter_paint.setBlendMode(DlBlendMode::kSrc); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, filter_paint, - layer_filter, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + parent->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)parent::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(child_bounds, DlCanvas::ClipOp::kIntersect, + false); + /* (BackdropFilter)layer::Paint */ { + expected_builder.Save(); + { + DlPaint save_paint = DlPaint().setBlendMode(DlBlendMode::kSrc); + expected_builder.SaveLayer(&child_bounds, &save_paint, + layer_filter.get()); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(BackdropFilterLayerTest, MultipleChildren) { @@ -184,17 +229,34 @@ TEST_F(BackdropFilterLayerTest, MultipleChildren) { EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, DlPaint(), - layer_filter, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + parent->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)parent::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(children_bounds, DlCanvas::ClipOp::kIntersect, + false); + /* (BackdropFilter)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&children_bounds, nullptr, + layer_filter.get()); + { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(BackdropFilterLayerTest, Nested) { @@ -238,21 +300,45 @@ TEST_F(BackdropFilterLayerTest, Nested) { EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform); EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform); - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, DlPaint(), - layer_filter1, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{children_bounds, DlPaint(), - layer_filter2, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + parent->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)parent::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(children_bounds, DlCanvas::ClipOp::kIntersect, + false); + /* (BackdropFilter)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&children_bounds, nullptr, + layer_filter1.get()); + { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* (BackdropFilter)layer2::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&children_bounds, nullptr, + layer_filter2.get()); + { + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(BackdropFilterLayerTest, Readback) { diff --git a/flow/layers/clip_path_layer_unittests.cc b/flow/layers/clip_path_layer_unittests.cc index 1012a4ca72fee..4d3489b9238f6 100644 --- a/flow/layers/clip_path_layer_unittests.cc +++ b/flow/layers/clip_path_layer_unittests.cc @@ -12,7 +12,6 @@ #include "flutter/flow/testing/mock_embedder.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" #include "gtest/gtest.h" namespace flutter { @@ -170,17 +169,19 @@ TEST_F(ClipPathLayerTest, FullyContainedChild) { EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipPathData{layer_path, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipPath)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipPath(layer_path); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ClipPathLayerTest, PartiallyContainedChild) { @@ -224,17 +225,19 @@ TEST_F(ClipPathLayerTest, PartiallyContainedChild) { EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_path)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipPathData{clip_path, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipPath)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipPath(clip_path); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } static bool ReadbackResult(PrerollContext* context, diff --git a/flow/layers/clip_rect_layer_unittests.cc b/flow/layers/clip_rect_layer_unittests.cc index 6ddb9076ddce5..f92d4599361c8 100644 --- a/flow/layers/clip_rect_layer_unittests.cc +++ b/flow/layers/clip_rect_layer_unittests.cc @@ -11,7 +11,6 @@ #include "flutter/flow/testing/mock_embedder.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -164,17 +163,19 @@ TEST_F(ClipRectLayerTest, FullyContainedChild) { EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_bounds)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{layer_bounds, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(layer_bounds); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ClipRectLayerTest, PartiallyContainedChild) { @@ -213,17 +214,19 @@ TEST_F(ClipRectLayerTest, PartiallyContainedChild) { EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rect)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRectData{clip_rect, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRect)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRect(clip_rect); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } static bool ReadbackResult(PrerollContext* context, @@ -488,8 +491,8 @@ TEST_F(ClipRectLayerTest, LayerCached) { auto initial_transform = SkMatrix::Translate(50.0, 25.5); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); use_mock_raster_cache(); preroll_context()->state_stack.set_preroll_delegate(initial_transform); diff --git a/flow/layers/clip_rrect_layer_unittests.cc b/flow/layers/clip_rrect_layer_unittests.cc index 75ca41c3e4863..9bbef5fbb05af 100644 --- a/flow/layers/clip_rrect_layer_unittests.cc +++ b/flow/layers/clip_rrect_layer_unittests.cc @@ -11,7 +11,6 @@ #include "flutter/flow/testing/mock_embedder.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -170,17 +169,19 @@ TEST_F(ClipRRectLayerTest, FullyContainedChild) { EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRRectData{layer_rrect, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRRect)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRRect(layer_rrect); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ClipRRectLayerTest, PartiallyContainedChild) { @@ -220,19 +221,19 @@ TEST_F(ClipRRectLayerTest, PartiallyContainedChild) { EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rrect)})); - EXPECT_TRUE(mock_layer->needs_painting(paint_context())); - EXPECT_TRUE(layer->needs_painting(paint_context())); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ClipRRectData{clip_rrect, ClipOp::kIntersect, - MockCanvas::kHard_ClipEdgeStyle}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ClipRRect)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.ClipRRect(clip_rrect); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } static bool ReadbackResult(PrerollContext* context, @@ -503,8 +504,8 @@ TEST_F(ClipRRectLayerTest, LayerCached) { auto initial_transform = SkMatrix::Translate(50.0, 25.5); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); use_mock_raster_cache(); preroll_context()->state_stack.set_preroll_delegate(initial_transform); diff --git a/flow/layers/color_filter_layer_unittests.cc b/flow/layers/color_filter_layer_unittests.cc index bba9ddb096a35..f07f47d73e73e 100644 --- a/flow/layers/color_filter_layer_unittests.cc +++ b/flow/layers/color_filter_layer_unittests.cc @@ -16,7 +16,6 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -67,12 +66,18 @@ TEST_F(ColorFilterLayerTest, EmptyFilter) { EXPECT_TRUE(layer->needs_painting(paint_context())); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({ - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, child_paint}}, - })); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ColorFilter)layer::Paint */ { + expected_builder.Save(); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ColorFilterLayerTest, SimpleFilter) { @@ -257,10 +262,10 @@ TEST_F(ColorFilterLayerTest, CacheChild) { layer->Add(mock_layer); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); const auto* cacheable_color_filter_item = layer->raster_cache_item(); @@ -301,10 +306,10 @@ TEST_F(ColorFilterLayerTest, CacheChildren) { DlPaint paint = DlPaint(); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); @@ -347,10 +352,10 @@ TEST_F(ColorFilterLayerTest, CacheColorFilterLayerSelf) { DlPaint paint = DlPaint(); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); preroll_context()->state_stack.set_preroll_delegate(initial_transform); diff --git a/flow/layers/container_layer_unittests.cc b/flow/layers/container_layer_unittests.cc index 990bb244cdc3f..a4c671d05f39d 100644 --- a/flow/layers/container_layer_unittests.cc +++ b/flow/layers/container_layer_unittests.cc @@ -10,9 +10,7 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" #include "gtest/gtest.h" -#include "include/core/SkCanvas.h" #include "include/core/SkMatrix.h" namespace flutter { @@ -111,10 +109,14 @@ TEST_F(ContainerLayerTest, Simple) { EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); EXPECT_EQ(mock_layer->parent_cull_rect(), kGiantRect); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, child_paint}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Container)layer::Paint */ { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ContainerLayerTest, Multiple) { @@ -151,13 +153,17 @@ TEST_F(ContainerLayerTest, Multiple) { EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); // Siblings are independent - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Container)layer::Paint */ { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ContainerLayerTest, MultipleWithEmpty) { @@ -188,10 +194,15 @@ TEST_F(ContainerLayerTest, MultipleWithEmpty) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Container)layer::Paint */ { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + // mock_layer2 not drawn due to needs_painting() returning false + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ContainerLayerTest, NeedsSystemComposite) { @@ -227,13 +238,17 @@ TEST_F(ContainerLayerTest, NeedsSystemComposite) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{0, MockCanvas::DrawPathData{ - child_path2, child_paint2}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Container)layer::Paint */ { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ContainerLayerTest, RasterCacheTest) { diff --git a/flow/layers/display_list_layer_unittests.cc b/flow/layers/display_list_layer_unittests.cc index eba4be82fbf78..137b76d2472fb 100644 --- a/flow/layers/display_list_layer_unittests.cc +++ b/flow/layers/display_list_layer_unittests.cc @@ -10,7 +10,6 @@ #include "flutter/flow/layers/layer_tree.h" #include "flutter/flow/testing/diff_context_test.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -69,8 +68,6 @@ TEST_F(DisplayListLayerTest, InvalidDisplayListDies) { TEST_F(DisplayListLayerTest, SimpleDisplayList) { const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f); - const SkMatrix layer_offset_matrix = - SkMatrix::Translate(layer_offset.fX, layer_offset.fY); const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f); DisplayListBuilder builder; builder.DrawRect(picture_bounds, DlPaint()); @@ -84,15 +81,18 @@ TEST_F(DisplayListLayerTest, SimpleDisplayList) { EXPECT_EQ(layer->display_list(), display_list.get()); EXPECT_TRUE(layer->needs_painting(paint_context())); - layer->Paint(paint_context()); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer_offset_matrix)}}, - MockCanvas::DrawCall{1, - MockCanvas::DrawDisplayListData{display_list, 1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (DisplayList)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(layer_offset.fX, layer_offset.fY); + expected_builder.DrawDisplayList(display_list); + } + expected_builder.Restore(); + } + EXPECT_TRUE( + DisplayListsEQ_Verbose(this->display_list(), expected_builder.Build())); } TEST_F(DisplayListLayerTest, CachingDoesNotChangeCullRect) { diff --git a/flow/layers/image_filter_layer_unittests.cc b/flow/layers/image_filter_layer_unittests.cc index 63f72227019fa..3d27ac6af7f50 100644 --- a/flow/layers/image_filter_layer_unittests.cc +++ b/flow/layers/image_filter_layer_unittests.cc @@ -11,7 +11,6 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" #include "gtest/gtest.h" #include "include/core/SkPath.h" #include "third_party/skia/include/effects/SkImageFilters.h" @@ -63,12 +62,16 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) { EXPECT_TRUE(layer->needs_painting(paint_context())); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({ - MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, child_paint}}, - })); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ImageFilter)layer::Paint */ { + expected_builder.Save(); + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ImageFilterLayerTest, SimpleFilter) { @@ -354,10 +357,10 @@ TEST_F(ImageFilterLayerTest, CacheChild) { layer->Add(mock_layer); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); DlPaint paint; use_mock_raster_cache(); @@ -400,10 +403,10 @@ TEST_F(ImageFilterLayerTest, CacheChildren) { layer->Add(mock_layer2); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); @@ -430,34 +433,36 @@ TEST_F(ImageFilterLayerTest, CacheChildren) { EXPECT_FALSE(raster_cache()->Draw( cacheable_image_filter_item->GetId().value(), other_canvas, &paint)); - mock_canvas().reset_draw_calls(); layer->Preroll(preroll_context()); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls().size(), 8UL); - auto call0 = MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}; - EXPECT_EQ(mock_canvas().draw_calls()[0], call0); - auto call1 = MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(SkMatrix::Translate(offset))}}; - EXPECT_EQ(mock_canvas().draw_calls()[1], call1); - auto call2 = MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{SkM44(SkMatrix::Translate(offset))}}; - EXPECT_EQ(mock_canvas().draw_calls()[2], call2); - auto call3 = MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}; - EXPECT_EQ(mock_canvas().draw_calls()[3], call3); - auto call4 = MockCanvas::DrawCall{ - 2, MockCanvas::SetMatrixData{SkM44(SkMatrix::Translate(0.0, 0.0))}}; - EXPECT_EQ(mock_canvas().draw_calls()[4], call4); - EXPECT_EQ(mock_canvas().draw_calls()[5].layer, 2); - EXPECT_TRUE(std::holds_alternative( - mock_canvas().draw_calls()[5].data)); - auto call5_data = - std::get(mock_canvas().draw_calls()[5].data); - EXPECT_EQ(call5_data.x, offset.fX); - EXPECT_EQ(call5_data.y, offset.fY); - auto call6 = MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}; - EXPECT_EQ(mock_canvas().draw_calls()[6], call6); - auto call7 = MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}; - EXPECT_EQ(mock_canvas().draw_calls()[7], call7); + + SkRect children_bounds = child_path1.getBounds(); + children_bounds.join(child_path2.getBounds()); + SkMatrix snapped_matrix = SkMatrix::MakeAll( // + 1, 0, SkScalarRoundToScalar(offset.fX), // + 0, 1, SkScalarRoundToScalar(offset.fY), // + 0, 0, 1); + SkMatrix cache_matrix = initial_transform; + cache_matrix.preConcat(snapped_matrix); + auto transformed_filter = dl_image_filter->makeWithLocalMatrix(cache_matrix); + + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ImageFilter)layer::Paint() */ { + expected_builder.Save(); + { + expected_builder.Translate(offset.fX, offset.fY); + // snap translation components to pixels due to using raster cache + expected_builder.TransformReset(); + expected_builder.Transform(snapped_matrix); + DlPaint dl_paint; + dl_paint.setImageFilter(transformed_filter.get()); + raster_cache()->Draw(cacheable_image_filter_item->GetId().value(), + expected_builder, &dl_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ImageFilterLayerTest, CacheImageFilterLayerSelf) { @@ -470,53 +475,58 @@ TEST_F(ImageFilterLayerTest, CacheImageFilterLayerSelf) { const SkPath child_path = SkPath().addRect(child_rect); auto mock_layer = std::make_shared(child_path); auto offset = SkPoint::Make(53.8, 24.4); - auto offset_rounded = - SkPoint::Make(std::round(offset.x()), std::round(offset.y())); - auto offset_rounded_out = - SkPoint::Make(std::floor(offset.x()), std::floor(offset.y())); auto layer = std::make_shared(dl_image_filter, offset); layer->Add(mock_layer); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); DlPaint paint; + SkMatrix snapped_matrix = SkMatrix::MakeAll( // + 1, 0, SkScalarRoundToScalar(offset.fX), // + 0, 1, SkScalarRoundToScalar(offset.fY), // + 0, 0, 1); + use_mock_raster_cache(); preroll_context()->state_stack.set_preroll_delegate(initial_transform); const auto* cacheable_image_filter_item = layer->raster_cache_item(); // frame 1. layer->Preroll(preroll_context()); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls().size(), 7UL); - auto uncached_call0 = MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}; - EXPECT_EQ(mock_canvas().draw_calls()[0], uncached_call0); - auto uncached_call1 = MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(SkMatrix::Translate(offset))}}; - EXPECT_EQ(mock_canvas().draw_calls()[1], uncached_call1); - auto uncached_call2 = MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{SkM44(SkMatrix::Translate(offset_rounded))}}; - EXPECT_EQ(mock_canvas().draw_calls()[2], uncached_call2); - EXPECT_EQ(mock_canvas().draw_calls()[3].layer, 1); - auto uncached_call3_data = - std::get(mock_canvas().draw_calls()[3].data); - EXPECT_EQ(uncached_call3_data.save_bounds, child_rect); - EXPECT_EQ(uncached_call3_data.save_to_layer, 2); - auto uncached_call4 = - MockCanvas::DrawCall{2, MockCanvas::DrawPathData{child_path, DlPaint()}}; - EXPECT_EQ(mock_canvas().draw_calls()[4], uncached_call4); - auto uncached_call5 = MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}; - EXPECT_EQ(mock_canvas().draw_calls()[5], uncached_call5); - auto uncached_call6 = MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}; - EXPECT_EQ(mock_canvas().draw_calls()[6], uncached_call6); + + layer->Paint(display_list_paint_context()); + { + DisplayListBuilder expected_builder; + /* (ImageFilter)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(offset.fX, offset.fY); + // Snap to pixel translation due to use of raster cache + expected_builder.TransformReset(); + expected_builder.Transform(snapped_matrix); + DlPaint save_paint = DlPaint().setImageFilter(dl_image_filter); + expected_builder.SaveLayer(&child_rect, &save_paint); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, DlPaint()); + } + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE( + DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); + } + // frame 2. layer->Preroll(preroll_context()); - layer->Paint(paint_context()); + layer->Paint(display_list_paint_context()); // frame 3. layer->Preroll(preroll_context()); - layer->Paint(paint_context()); + layer->Paint(display_list_paint_context()); LayerTree::TryToRasterCache(cacheable_items(), &paint_context()); // frame1,2 cache the ImageFilter's children layer, frame3 cache the @@ -533,24 +543,24 @@ TEST_F(ImageFilterLayerTest, CacheImageFilterLayerSelf) { EXPECT_FALSE(raster_cache()->Draw( cacheable_image_filter_item->GetId().value(), other_canvas, &paint)); - mock_canvas().reset_draw_calls(); layer->Preroll(preroll_context()); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls().size(), 4UL); - auto cached_call0 = MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}; - EXPECT_EQ(mock_canvas().draw_calls()[0], cached_call0); - auto cached_call1 = MockCanvas::DrawCall{ - 1, MockCanvas::SetMatrixData{SkM44(SkMatrix::Translate(0.0, 0.0))}}; - EXPECT_EQ(mock_canvas().draw_calls()[1], cached_call1); - EXPECT_EQ(mock_canvas().draw_calls()[2].layer, 1); - EXPECT_TRUE(std::holds_alternative( - mock_canvas().draw_calls()[2].data)); - auto cached_call2_data = std::get( - mock_canvas().draw_calls()[2].data); - EXPECT_EQ(cached_call2_data.x, offset_rounded_out.fX); - EXPECT_EQ(cached_call2_data.y, offset_rounded_out.fY); - auto cached_call3 = MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}; - EXPECT_EQ(mock_canvas().draw_calls()[3], cached_call3); + + reset_display_list(); + layer->Paint(display_list_paint_context()); + { + DisplayListBuilder expected_builder; + /* (ImageFilter)layer::Paint */ { + expected_builder.Save(); + { + EXPECT_TRUE( + raster_cache()->Draw(cacheable_image_filter_item->GetId().value(), + expected_builder, nullptr)); + } + expected_builder.Restore(); + } + EXPECT_TRUE( + DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); + } } TEST_F(ImageFilterLayerTest, OpacityInheritance) { diff --git a/flow/layers/layer_state_stack_unittests.cc b/flow/layers/layer_state_stack_unittests.cc index 2a7e0d83134c2..73ed2d3cc8dbf 100644 --- a/flow/layers/layer_state_stack_unittests.cc +++ b/flow/layers/layer_state_stack_unittests.cc @@ -9,7 +9,6 @@ #include "flutter/flow/layers/layer.h" #include "flutter/flow/layers/layer_state_stack.h" #include "flutter/testing/display_list_testing.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -63,9 +62,10 @@ TEST(LayerStateStack, SingularDelegate) { LayerStateStack state_stack; ASSERT_EQ(state_stack.canvas_delegate(), nullptr); - // Two kinds of DlCanvas implementation + // Two different DlCanvas implementators DisplayListBuilder builder; - MockCanvas canvas; + DisplayListBuilder builder2; + DlCanvas& canvas = builder2; // no delegate -> builder delegate state_stack.set_delegate(&builder); @@ -92,7 +92,8 @@ TEST(LayerStateStack, SingularDelegate) { TEST(LayerStateStack, OldDelegateIsRolledBack) { LayerStateStack state_stack; DisplayListBuilder builder; - MockCanvas canvas; + DisplayListBuilder builder2; + DlCanvas& canvas = builder2; ASSERT_TRUE(builder.GetTransform().isIdentity()); ASSERT_TRUE(canvas.GetTransform().isIdentity()); diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc index 1be70be8007ed..a2a119264bf8b 100644 --- a/flow/layers/opacity_layer_unittests.cc +++ b/flow/layers/opacity_layer_unittests.cc @@ -16,7 +16,6 @@ #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" #include "flutter/testing/display_list_testing.h" -#include "flutter/testing/mock_canvas.h" #include "gtest/gtest.h" namespace flutter { @@ -93,10 +92,10 @@ TEST_F(OpacityLayerTest, CacheChild) { DlPaint paint; SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); @@ -142,10 +141,10 @@ TEST_F(OpacityLayerTest, CacheChildren) { layer->Add(mock_layer2); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); - MockCanvas other_canvas; - other_canvas.SetTransform(other_transform); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); + DisplayListBuilder other_canvas; + other_canvas.Transform(other_transform); use_mock_raster_cache(); @@ -233,18 +232,20 @@ TEST_F(OpacityLayerTest, FullyOpaque) { EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_transform)})); - 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::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); + DisplayListBuilder expected_builder; + /* (Opacity)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(layer_offset.fX, layer_offset.fY); + // Opaque alpha needs no SaveLayer, just recurse into painting mock_layer + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + } + expected_builder.Restore(); + } + layer->Paint(display_list_paint_context()); + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(OpacityLayerTest, FullyTransparent) { @@ -275,20 +276,24 @@ TEST_F(OpacityLayerTest, FullyTransparent) { mock_layer->parent_mutators(), std::vector({Mutator(layer_transform), Mutator(SK_AlphaTRANSPARENT)})); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}}, - MockCanvas::DrawCall{ - 1, - MockCanvas::SaveLayerData{ - child_bounds, DlPaint(DlColor::kTransparent()), 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); + DisplayListBuilder expected_builder; + /* (Opacity)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(layer_offset.fX, layer_offset.fY); + /* (Opacity)layer::PaintChildren */ { + DlPaint save_paint(DlPaint().setOpacity(layer->opacity())); + expected_builder.SaveLayer(&child_bounds, &save_paint); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + layer->Paint(display_list_paint_context()); + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(OpacityLayerTest, HalfTransparent) { @@ -324,12 +329,18 @@ TEST_F(OpacityLayerTest, HalfTransparent) { DlPaint child_dl_paint = DlPaint(DlColor::kGreen()); auto expected_builder = DisplayListBuilder(); - expected_builder.Save(); - expected_builder.Translate(layer_offset.fX, layer_offset.fY); - expected_builder.SaveLayer(&opacity_bounds, &save_paint); - expected_builder.DrawPath(child_path, child_dl_paint); - expected_builder.Restore(); - expected_builder.Restore(); + /* (Opacity)layer::Paint */ { + expected_builder.Save(); + expected_builder.Translate(layer_offset.fX, layer_offset.fY); + /* (Opacity)layer::PaintChildren */ { + expected_builder.SaveLayer(&opacity_bounds, &save_paint); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_dl_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } sk_sp expected_display_list = expected_builder.Build(); layer->Paint(display_list_paint_context()); @@ -384,53 +395,65 @@ TEST_F(OpacityLayerTest, Nested) { EXPECT_TRUE(layer2->needs_painting(paint_context())); EXPECT_EQ(mock_layer1->parent_matrix(), SkMatrix::Concat(initial_transform, layer1_transform)); - // EXPECT_EQ(mock_layer1->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1)})); + EXPECT_EQ(mock_layer1->parent_mutators(), + std::vector({Mutator(layer1_transform), Mutator(alpha1)})); EXPECT_EQ( mock_layer2->parent_matrix(), SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform), layer2_transform)); - // EXPECT_EQ(mock_layer2->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1), - // Mutator(layer2_transform), Mutator(alpha2)})); + EXPECT_EQ(mock_layer2->parent_mutators(), + std::vector({Mutator(layer1_transform), Mutator(alpha1), + Mutator(layer2_transform), Mutator(alpha2)})); EXPECT_EQ(mock_layer3->parent_matrix(), SkMatrix::Concat(initial_transform, layer1_transform)); - // EXPECT_EQ(mock_layer3->parent_mutators(), - // std::vector({Mutator(layer1_transform), Mutator(alpha1)})); + EXPECT_EQ(mock_layer3->parent_mutators(), + std::vector({Mutator(layer1_transform), Mutator(alpha1)})); - DlPaint opacity1_paint; - opacity1_paint.setOpacity(alpha1 * (1.0 / SK_AlphaOPAQUE)); - DlPaint opacity2_paint; - opacity2_paint.setOpacity(alpha2 * (1.0 / SK_AlphaOPAQUE)); SkRect opacity1_bounds = expected_layer1_bounds.makeOffset(-layer1_offset.fX, -layer1_offset.fY); SkRect opacity2_bounds = expected_layer2_bounds.makeOffset(-layer2_offset.fX, -layer2_offset.fY); - auto expected_draw_calls = std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer1_transform)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{opacity1_bounds, opacity1_paint, - nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child1_path, child1_paint}}, - MockCanvas::DrawCall{2, MockCanvas::SaveData{3}}, - MockCanvas::DrawCall{ - 3, MockCanvas::ConcatMatrixData{SkM44(layer2_transform)}}, - MockCanvas::DrawCall{ - 3, MockCanvas::SaveLayerData{opacity2_bounds, opacity2_paint, - nullptr, 4}}, - MockCanvas::DrawCall{ - 4, MockCanvas::DrawPathData{child2_path, child2_paint}}, - MockCanvas::DrawCall{4, MockCanvas::RestoreData{3}}, - MockCanvas::DrawCall{3, MockCanvas::RestoreData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child3_path, child3_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer1->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); + DlPaint opacity1_paint; + opacity1_paint.setOpacity(alpha1 * (1.0 / SK_AlphaOPAQUE)); + DlPaint opacity2_paint; + opacity2_paint.setOpacity(alpha2 * (1.0 / SK_AlphaOPAQUE)); + + DisplayListBuilder expected_builder; + /* (Opacity)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(layer1_offset.fX, layer1_offset.fY); + /* (Opacity)layer1::PaintChildren */ { + expected_builder.SaveLayer(&opacity1_bounds, &opacity1_paint); + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child1_path, child1_paint); + } + /* (Opacity)layer2::Paint */ { + expected_builder.Save(); + { + expected_builder.Translate(layer2_offset.fX, layer2_offset.fY); + /* (Opacity)layer2::PaintChidren */ { + expected_builder.SaveLayer(&opacity2_bounds, &opacity2_paint); + { + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child2_path, child2_paint); + } + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + /* mock_layer3::Paint */ { + expected_builder.DrawPath(child3_path, child3_paint); + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + layer1->Paint(display_list_paint_context()); + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(OpacityLayerTest, Readback) { @@ -658,16 +681,12 @@ TEST_F(OpacityLayerDiffTest, FractionalTranslationWithRasterCache) { } TEST_F(OpacityLayerTest, FullyOpaqueWithFractionalValues) { - use_mock_raster_cache(); // Ensure non-fractional alignment. + use_mock_raster_cache(); // Ensure pixel-snapped 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 DlPaint child_paint = DlPaint(DlColor::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); @@ -675,21 +694,25 @@ TEST_F(OpacityLayerTest, FullyOpaqueWithFractionalValues) { preroll_context()->state_stack.set_preroll_delegate(initial_transform); layer->Preroll(preroll_context()); - 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::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); + auto expected_builder = DisplayListBuilder(); + /* (Opacity)layer::Paint */ { + expected_builder.Save(); + expected_builder.Translate(layer_offset.fX, layer_offset.fY); + // Opaque alpha needs no SaveLayer, just recurse into painting mock_layer + // but since we use the mock raster cache we pixel snap the transform + expected_builder.TransformReset(); + expected_builder.Transform2DAffine( + 1, 0, SkScalarRoundToScalar(layer_offset.fX), // + 0, 1, SkScalarRoundToScalar(layer_offset.fY)); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Restore(); + } + sk_sp expected_display_list = expected_builder.Build(); + + layer->Paint(display_list_paint_context()); + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_display_list)); } TEST_F(OpacityLayerTest, FullyTransparentDoesNotCullPlatformView) { diff --git a/flow/layers/shader_mask_layer_unittests.cc b/flow/layers/shader_mask_layer_unittests.cc index b08d73cf9cdf5..b5361a54eb09a 100644 --- a/flow/layers/shader_mask_layer_unittests.cc +++ b/flow/layers/shader_mask_layer_unittests.cc @@ -11,10 +11,7 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" #include "gtest/gtest.h" -#include "third_party/skia/include/core/SkShader.h" -#include "third_party/skia/include/effects/SkPerlinNoiseShader.h" namespace flutter { namespace testing { @@ -86,23 +83,27 @@ TEST_F(ShaderMaskLayerTest, EmptyFilter) { DlPaint filter_paint; filter_paint.setBlendMode(DlBlendMode::kSrc); filter_paint.setColorSource(nullptr); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, DlPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ShaderMask)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&child_bounds); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ShaderMaskLayerTest, SimpleFilter) { @@ -127,23 +128,27 @@ TEST_F(ShaderMaskLayerTest, SimpleFilter) { DlPaint filter_paint; filter_paint.setBlendMode(DlBlendMode::kSrc); filter_paint.setColorSource(dl_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{child_bounds, DlPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ShaderMask)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&child_bounds); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ShaderMaskLayerTest, MultipleChildren) { @@ -180,25 +185,30 @@ TEST_F(ShaderMaskLayerTest, MultipleChildren) { DlPaint filter_paint; filter_paint.setBlendMode(DlBlendMode::kSrc); filter_paint.setColorSource(dl_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, DlPaint(), - nullptr, 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ShaderMask)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&children_bounds); + { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ShaderMaskLayerTest, Nested) { @@ -244,38 +254,44 @@ TEST_F(ShaderMaskLayerTest, Nested) { filter_paint2.setBlendMode(DlBlendMode::kSrc); filter_paint1.setColorSource(dl_filter1); filter_paint2.setColorSource(dl_filter2); - layer1->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{ - 0, MockCanvas::SaveLayerData{children_bounds, DlPaint(), nullptr, - 1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path1, child_paint1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{child_path2.getBounds(), DlPaint(), - nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path2, child_paint2}}, - MockCanvas::DrawCall{2, - MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 2, - MockCanvas::DrawRectData{ - SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), - filter_paint2}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, - MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 1, - MockCanvas::DrawRectData{ - SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), - filter_paint1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + + layer1->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ShaderMask)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&children_bounds); + { + /* mock_layer1::Paint */ { + expected_builder.DrawPath(child_path1, child_paint1); + } + /* (ShaderMask)layer2::Paint */ { + expected_builder.Save(); + { + expected_builder.SaveLayer(&child_path2.getBounds()); + { + /* mock_layer2::Paint */ { + expected_builder.DrawPath(child_path2, child_paint2); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint2); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint1); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(ShaderMaskLayerTest, Readback) { @@ -310,8 +326,8 @@ TEST_F(ShaderMaskLayerTest, LayerCached) { layer->Add(mock_layer); SkMatrix cache_ctm = initial_transform; - MockCanvas cache_canvas; - cache_canvas.SetTransform(cache_ctm); + DisplayListBuilder cache_canvas; + cache_canvas.Transform(cache_ctm); use_mock_raster_cache(); preroll_context()->state_stack.set_preroll_delegate(initial_transform); @@ -398,7 +414,7 @@ TEST_F(ShaderMaskLayerTest, OpacityInheritance) { EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list())); } -TEST_F(ShaderMaskLayerTest, SimpleFilterWithRasterCache) { +TEST_F(ShaderMaskLayerTest, SimpleFilterWithRasterCacheLayerNotCached) { use_mock_raster_cache(); // Ensure non-fractional alignment. const SkMatrix initial_transform = SkMatrix::Translate(0.5f, 1.0f); @@ -418,27 +434,31 @@ TEST_F(ShaderMaskLayerTest, SimpleFilterWithRasterCache) { DlPaint filter_paint; filter_paint.setBlendMode(DlBlendMode::kSrc); filter_paint.setColorSource(dl_filter); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44( - SkMatrix::Translate(0.0, 0.0))}}, - MockCanvas::DrawCall{ - 1, MockCanvas::SaveLayerData{child_bounds, DlPaint(), - nullptr, 2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, child_paint}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{SkM44::Translate( - layer_bounds.fLeft, layer_bounds.fTop)}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawRectData{SkRect::MakeWH( - layer_bounds.width(), - layer_bounds.height()), - filter_paint}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (ShaderMask)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.TransformReset(); + // The layer will perform this Identity transform operation by default, + // but it should be ignored both here and in the layer paint + expected_builder.Transform(SkMatrix()); + expected_builder.SaveLayer(&child_bounds); + { + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint); + } + expected_builder.Translate(layer_bounds.fLeft, layer_bounds.fTop); + expected_builder.DrawRect( + SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()), + filter_paint); + } + expected_builder.Restore(); + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } } // namespace testing diff --git a/flow/layers/transform_layer_unittests.cc b/flow/layers/transform_layer_unittests.cc index a0fd2bb04673d..129edb57723da 100644 --- a/flow/layers/transform_layer_unittests.cc +++ b/flow/layers/transform_layer_unittests.cc @@ -8,7 +8,6 @@ #include "flutter/flow/testing/layer_test.h" #include "flutter/flow/testing/mock_layer.h" #include "flutter/fml/macros.h" -#include "flutter/testing/mock_canvas.h" namespace flutter { namespace testing { @@ -59,10 +58,19 @@ TEST_F(TransformLayerTest, Identity) { EXPECT_EQ(mock_layer->parent_cull_rect(), cull_rect); EXPECT_EQ(mock_layer->parent_mutators(), MutatorsStack()); - layer->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{ - 0, MockCanvas::DrawPathData{child_path, DlPaint()}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Transform)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(SkMatrix()); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, DlPaint()); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(TransformLayerTest, Simple) { @@ -95,15 +103,19 @@ TEST_F(TransformLayerTest, Simple) { EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_transform)})); - layer->Paint(paint_context()); - EXPECT_EQ( - mock_canvas().draw_calls(), - std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, DlPaint()}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + layer->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Transform)layer::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(layer_transform); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, DlPaint()); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(TransformLayerTest, Nested) { @@ -113,7 +125,7 @@ TEST_F(TransformLayerTest, Nested) { SkRect local_cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); SkRect device_cull_rect = initial_transform.mapRect(local_cull_rect); SkMatrix layer1_transform = SkMatrix::Translate(2.5f, 2.5f); - SkMatrix layer2_transform = SkMatrix::Translate(2.5f, 2.5f); + SkMatrix layer2_transform = SkMatrix::Translate(3.5f, 3.5f); SkMatrix inverse_layer1_transform, inverse_layer2_transform; EXPECT_TRUE(layer1_transform.invert(&inverse_layer1_transform)); EXPECT_TRUE(layer2_transform.invert(&inverse_layer2_transform)); @@ -146,21 +158,28 @@ TEST_F(TransformLayerTest, Nested) { inverse_layer1_transform.mapRect(local_cull_rect))); EXPECT_EQ( mock_layer->parent_mutators(), - std::vector({Mutator(layer2_transform), Mutator(layer1_transform)})); - - layer1->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer1_transform)}}, - MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{SkM44(layer2_transform)}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, DlPaint()}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + std::vector({Mutator(layer1_transform), Mutator(layer2_transform)})); + + layer1->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Transform)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(layer1_transform); + /* (Transform)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(layer2_transform); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, DlPaint()); + } + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(TransformLayerTest, NestedSeparated) { @@ -170,15 +189,15 @@ TEST_F(TransformLayerTest, NestedSeparated) { SkRect local_cull_rect = SkRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f); SkRect device_cull_rect = initial_transform.mapRect(local_cull_rect); SkMatrix layer1_transform = SkMatrix::Translate(2.5f, 2.5f); - SkMatrix layer2_transform = SkMatrix::Translate(2.5f, 2.5f); + SkMatrix layer2_transform = SkMatrix::Translate(3.5f, 3.5f); SkMatrix inverse_layer1_transform, inverse_layer2_transform; EXPECT_TRUE(layer1_transform.invert(&inverse_layer1_transform)); EXPECT_TRUE(layer2_transform.invert(&inverse_layer2_transform)); + DlPaint child_paint1(DlColor::kBlue()); + DlPaint child_paint2(DlColor::kGreen()); - auto mock_layer1 = - std::make_shared(child_path, DlPaint(DlColor::kBlue())); - auto mock_layer2 = - std::make_shared(child_path, DlPaint(DlColor::kGreen())); + auto mock_layer1 = std::make_shared(child_path, child_paint1); + auto mock_layer2 = std::make_shared(child_path, child_paint2); auto layer1 = std::make_shared(layer1_transform); auto layer2 = std::make_shared(layer2_transform); layer1->Add(mock_layer1); @@ -219,25 +238,31 @@ TEST_F(TransformLayerTest, NestedSeparated) { std::vector({Mutator(layer1_transform)})); EXPECT_EQ( mock_layer2->parent_mutators(), - std::vector({Mutator(layer2_transform), Mutator(layer1_transform)})); - - layer1->Paint(paint_context()); - EXPECT_EQ(mock_canvas().draw_calls(), - std::vector( - {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, - MockCanvas::DrawCall{ - 1, MockCanvas::ConcatMatrixData{SkM44(layer1_transform)}}, - MockCanvas::DrawCall{ - 1, MockCanvas::DrawPathData{child_path, - DlPaint(DlColor::kBlue())}}, - MockCanvas::DrawCall{1, MockCanvas::SaveData{2}}, - MockCanvas::DrawCall{ - 2, MockCanvas::ConcatMatrixData{SkM44(layer2_transform)}}, - MockCanvas::DrawCall{ - 2, MockCanvas::DrawPathData{child_path, - DlPaint(DlColor::kGreen())}}, - MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, - MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); + std::vector({Mutator(layer1_transform), Mutator(layer2_transform)})); + + layer1->Paint(display_list_paint_context()); + DisplayListBuilder expected_builder; + /* (Transform)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(layer1_transform); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint1); + } + /* (Transform)layer1::Paint */ { + expected_builder.Save(); + { + expected_builder.Transform(layer2_transform); + /* mock_layer::Paint */ { + expected_builder.DrawPath(child_path, child_paint2); + } + } + expected_builder.Restore(); + } + } + expected_builder.Restore(); + } + EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build())); } TEST_F(TransformLayerTest, OpacityInheritance) { diff --git a/flow/testing/layer_test.h b/flow/testing/layer_test.h index 70e26670a8133..f4e3fd88c9bbb 100644 --- a/flow/testing/layer_test.h +++ b/flow/testing/layer_test.h @@ -172,15 +172,19 @@ class LayerTestBase : public CanvasTestBase { sk_sp display_list() { if (display_list_ == nullptr) { - // null out the canvas and recorder fields of the PaintContext - // and the delegate of the state_stack to prevent future use. - display_list_paint_context_.state_stack.clear_delegate(); - display_list_paint_context_.canvas = nullptr; display_list_ = display_list_builder_.Build(); } return display_list_; } + void reset_display_list() { + display_list_ = nullptr; + // Build() will leave the builder in a state to start recording a new DL + display_list_builder_.Build(); + // Make sure we are starting from a fresh state stack + FML_DCHECK(display_list_state_stack_.is_empty()); + } + void enable_leaf_layer_tracing() { paint_context_.enable_leaf_layer_tracing = true; paint_context_.layer_snapshot_store = &snapshot_store_; diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index b5d8b44cb7d07..71260d5b8755f 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -159,8 +159,6 @@ class MockCanvas final : public DlCanvas { MockCanvas(int width, int height); ~MockCanvas(); - // SkNWayCanvas* internal_canvas() { return &internal_canvas_; } - const std::vector& draw_calls() const { return draw_calls_; } void reset_draw_calls() { draw_calls_.clear(); }