From 5890f35646d2115e97d4b8fdc3d7e23f24929941 Mon Sep 17 00:00:00 2001 From: fredlee12345678 Date: Fri, 4 Sep 2020 17:59:36 +0800 Subject: [PATCH 1/3] add checker board for clip_path,clip_rect,clip_rrect,physical_shap_layer --- flow/layers/clip_path_layer.cc | 4 ++++ flow/layers/clip_rect_layer.cc | 4 ++++ flow/layers/clip_rrect_layer.cc | 4 ++++ flow/layers/physical_shape_layer.cc | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index fc7d2b87acc9f..f8aaa58f74787 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/flow/layers/clip_path_layer.h" +#include #if defined(LEGACY_FUCHSIA_EMBEDDER) @@ -72,6 +73,9 @@ void ClipPathLayer::Paint(PaintContext& context) const { PaintChildren(context); if (UsesSaveLayer()) { context.internal_nodes_canvas->restore(); + if (context.checkerboard_offscreen_layers) { + DrawCheckerboard(context.internal_nodes_canvas, paint_bounds()); + } } } diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index 857ce58a61d45..fbd36dab65d05 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/flow/layers/clip_rect_layer.h" +#include "flutter/flow/paint_utils.h" namespace flutter { @@ -65,6 +66,9 @@ void ClipRectLayer::Paint(PaintContext& context) const { PaintChildren(context); if (UsesSaveLayer()) { context.internal_nodes_canvas->restore(); + if (context.checkerboard_offscreen_layers) { + DrawCheckerboard(context.internal_nodes_canvas, clip_rect_); + } } } diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index 71bea800c83ac..b3ff833c4a4f3 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/flow/layers/clip_rrect_layer.h" +#include "flutter/flow/paint_utils.h" namespace flutter { @@ -66,6 +67,9 @@ void ClipRRectLayer::Paint(PaintContext& context) const { PaintChildren(context); if (UsesSaveLayer()) { context.internal_nodes_canvas->restore(); + if (context.checkerboard_offscreen_layers) { + DrawCheckerboard(context.internal_nodes_canvas, paint_bounds()); + } } } diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 7ba2b7cb734ea..7d44f6792a993 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -87,6 +87,12 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { PaintChildren(context); context.internal_nodes_canvas->restoreToCount(saveCount); + + if (UsesSaveLayer()){ + if (context.checkerboard_offscreen_layers) { + DrawCheckerboard(context.internal_nodes_canvas, paint_bounds()); + } + } } SkRect PhysicalShapeLayer::ComputeShadowBounds(const SkRect& bounds, From 98671e0bd347cfc25e9e63c25b88351c72620a71 Mon Sep 17 00:00:00 2001 From: fredlee12345678 Date: Thu, 10 Sep 2020 09:48:54 +0800 Subject: [PATCH 2/3] merge commit --- ci/licenses_golden/licenses_flutter | 1 + flow/BUILD.gn | 1 + .../checkerboard_layertree_unittests.cc | 375 ++++++++++++++++++ flow/layers/clip_path_layer.cc | 2 +- flow/layers/physical_shape_layer.cc | 2 +- flow/testing/layer_test.h | 12 + testing/mock_canvas.cc | 13 +- testing/mock_canvas.h | 12 +- 8 files changed, 412 insertions(+), 6 deletions(-) create mode 100644 flow/layers/checkerboard_layertree_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 1c0977092063e..5bab20ba8b172 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -40,6 +40,7 @@ FILE: ../../../flutter/flow/instrumentation.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer_unittests.cc +FILE: ../../../flutter/flow/layers/checkerboard_layertree_unittests.cc FILE: ../../../flutter/flow/layers/child_scene_layer.cc FILE: ../../../flutter/flow/layers/child_scene_layer.h FILE: ../../../flutter/flow/layers/clip_path_layer.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 63f1fe529108b..43676e81a2ec6 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -137,6 +137,7 @@ if (enable_unittests) { "flow_test_utils.h", "gl_context_switch_unittests.cc", "layers/backdrop_filter_layer_unittests.cc", + "layers/checkerboard_layertree_unittests.cc", "layers/clip_path_layer_unittests.cc", "layers/clip_rect_layer_unittests.cc", "layers/clip_rrect_layer_unittests.cc", diff --git a/flow/layers/checkerboard_layertree_unittests.cc b/flow/layers/checkerboard_layertree_unittests.cc new file mode 100644 index 0000000000000..7fbe9847bfa75 --- /dev/null +++ b/flow/layers/checkerboard_layertree_unittests.cc @@ -0,0 +1,375 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/flow/layers/clip_path_layer.h" +#include "flutter/flow/layers/clip_rect_layer.h" +#include "flutter/flow/layers/clip_rrect_layer.h" +#include "flutter/flow/layers/physical_shape_layer.h" + +#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 { + +using CheckerBoardLayerTest = LayerTest; + +#ifndef NDEBUG +TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); + const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0); + const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = std::make_shared(layer_bounds, + Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + SkRect intersect_bounds = layer_bounds; + SkRect child_intersect_bounds = layer_bounds; + intersect_bounds.intersect(cull_bounds); + child_intersect_bounds.intersect(child_bounds); + preroll_context()->cull_rect = cull_bounds; // Cull child + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); + EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); + 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, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{layer_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f); + const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0); + const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = std::make_shared(layer_bounds, + Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + SkRect intersect_bounds = layer_bounds; + SkRect child_intersect_bounds = layer_bounds; + intersect_bounds.intersect(cull_bounds); + child_intersect_bounds.intersect(child_bounds); + preroll_context()->cull_rect = cull_bounds; // Cull child + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds); + EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); + EXPECT_EQ(mock_layer->parent_mutators(), + std::vector({Mutator(layer_bounds)})); + + layer->Paint(check_board_context()); + + EXPECT_NE( + mock_canvas().draw_calls(), + std::vector( + {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{layer_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f); + const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkPath layer_path = SkPath().addRect(layer_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = + std::make_shared(layer_path, Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); + 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::ClipRectData{layer_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f); + const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkPath layer_path = SkPath().addRect(layer_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = + std::make_shared(layer_path, Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); + EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); + EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)})); + + layer->Paint(check_board_context()); + EXPECT_NE( + mock_canvas().draw_calls(), + std::vector( + {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f); + const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = std::make_shared(layer_rrect, + Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); + 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::ClipRectData{layer_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) { + const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f); + const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0); + const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0); + const SkPath child_path = SkPath().addRect(child_bounds); + const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds); + const SkPaint child_paint = SkPaint(SkColors::kYellow); + const SkPaint clip_paint; + auto mock_layer = std::make_shared(child_path, child_paint); + auto layer = std::make_shared(layer_rrect, + Clip::antiAliasWithSaveLayer); + layer->Add(mock_layer); + + layer->Preroll(preroll_context(), initial_matrix); + EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched + EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched + EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); + EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); + EXPECT_TRUE(mock_layer->needs_painting()); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds); + EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix); + EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)})); + + layer->Paint(check_board_context()); + EXPECT_NE( + mock_canvas().draw_calls(), + std::vector( + {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, + MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}}, + MockCanvas::DrawCall{ + 2, MockCanvas::DrawPathData{child_path, child_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +} + +TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) { + constexpr float initial_elevation = 20.0f; + SkPath layer_path; + const SkRect paint_bounds = SkRect::MakeXYWH(0, 0, 8, 8); + const SkPaint clip_paint; + layer_path.addRect(0, 0, 8, 8).close(); + auto layer = std::make_shared( + SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path, + Clip::antiAliasWithSaveLayer); + + layer->Preroll(preroll_context(), SkMatrix()); + // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and + // their shadows , so we do not do any painting there. + EXPECT_EQ(layer->paint_bounds(), + PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(), + initial_elevation, 1.0f)); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_FALSE(layer->needs_system_composite()); + EXPECT_EQ(layer->elevation(), initial_elevation); + + // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and + // their shadows , so we do not use the direct |Paint()| path there. +#if !defined(LEGACY_FUCHSIA_EMBEDDER) + SkPaint layer_paint; + layer_paint.setColor(SK_ColorGREEN); + layer_paint.setAntiAlias(true); + layer->Paint(paint_context()); + EXPECT_EQ( + mock_canvas().draw_calls(), + std::vector( + {MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, + MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ClipRectData{paint_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint, + nullptr, 2}}, + MockCanvas::DrawCall{2, MockCanvas::DrawPaint{layer_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +#endif +} + +TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) { + constexpr float initial_elevation = 20.0f; + SkPath layer_path; + const SkRect paint_bounds = SkRect::MakeXYWH(0, 0, 8, 8); + const SkPaint clip_paint; + layer_path.addRect(0, 0, 8, 8).close(); + auto layer = std::make_shared( + SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path, + Clip::antiAliasWithSaveLayer); + + layer->Preroll(preroll_context(), SkMatrix()); + // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and + // their shadows , so we do not do any painting there. + EXPECT_EQ(layer->paint_bounds(), + PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(), + initial_elevation, 1.0f)); + EXPECT_TRUE(layer->needs_painting()); + EXPECT_FALSE(layer->needs_system_composite()); + EXPECT_EQ(layer->elevation(), initial_elevation); + + // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and + // their shadows , so we do not use the direct |Paint()| path there. +#if !defined(LEGACY_FUCHSIA_EMBEDDER) + SkPaint layer_paint; + layer_paint.setColor(SK_ColorGREEN); + layer_paint.setAntiAlias(true); + layer->Paint(check_board_context()); + EXPECT_NE( + mock_canvas().draw_calls(), + std::vector( + {MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}}, + MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, + MockCanvas::DrawCall{ + 1, MockCanvas::ClipRectData{paint_bounds, SkClipOp::kIntersect, + MockCanvas::kSoft_ClipEdgeStyle}}, + MockCanvas::DrawCall{ + 1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint, + nullptr, 2}}, + MockCanvas::DrawCall{2, MockCanvas::DrawPaint{layer_paint}}, + MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}}, + MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); +#endif +} + +#endif +} // namespace testing +} // namespace flutter diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index f8aaa58f74787..bcfb4931b1f43 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "flutter/flow/layers/clip_path_layer.h" -#include +#include "flutter/flow/paint_utils.h" #if defined(LEGACY_FUCHSIA_EMBEDDER) diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 7d44f6792a993..534962fff0a40 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -88,7 +88,7 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { context.internal_nodes_canvas->restoreToCount(saveCount); - if (UsesSaveLayer()){ + if (UsesSaveLayer()) { if (context.checkerboard_offscreen_layers) { DrawCheckerboard(context.internal_nodes_canvas, paint_bounds()); } diff --git a/flow/testing/layer_test.h b/flow/testing/layer_test.h index d2df8b404ca9b..d3facde953868 100644 --- a/flow/testing/layer_test.h +++ b/flow/testing/layer_test.h @@ -60,6 +60,16 @@ class LayerTestBase : public CanvasTestBase { nullptr, /* raster_cache */ false, /* checkerboard_offscreen_layers */ 1.0f, /* frame_device_pixel_ratio */ + }), + check_board_context_({ + TestT::mock_canvas().internal_canvas(), /* internal_nodes_canvas */ + &TestT::mock_canvas(), /* leaf_nodes_canvas */ + nullptr, /* gr_context */ + nullptr, /* external_view_embedder */ + raster_time_, ui_time_, texture_registry_, + nullptr, /* raster_cache */ + true, /* checkerboard_offscreen_layers */ + 1.0f, /* frame_device_pixel_ratio */ }) { use_null_raster_cache(); } @@ -117,6 +127,7 @@ class LayerTestBase : public CanvasTestBase { RasterCache* raster_cache() { return raster_cache_.get(); } PrerollContext* preroll_context() { return &preroll_context_; } Layer::PaintContext& paint_context() { return paint_context_; } + Layer::PaintContext& check_board_context() { return check_board_context_; } private: void set_raster_cache_(std::unique_ptr raster_cache) { @@ -133,6 +144,7 @@ class LayerTestBase : public CanvasTestBase { std::unique_ptr raster_cache_; PrerollContext preroll_context_; Layer::PaintContext paint_context_; + Layer::PaintContext check_board_context_; FML_DISALLOW_COPY_AND_ASSIGN(LayerTestBase); }; diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 66c83b491b32a..8b2ba26601cda 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -190,8 +190,8 @@ void MockCanvas::onDrawPatch(const SkPoint[12], FML_DCHECK(false); } -void MockCanvas::onDrawPaint(const SkPaint&) { - FML_DCHECK(false); +void MockCanvas::onDrawPaint(const SkPaint& skPaint) { + draw_calls_.emplace_back(DrawCall{current_layer_, DrawPaint{skPaint}}); } void MockCanvas::onDrawBehind(const SkPaint&) { @@ -450,5 +450,14 @@ std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) { return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]"; } +bool operator==(const MockCanvas::DrawPaint& a, + const MockCanvas::DrawPaint& b) { + return a.paint == b.paint; +} + +std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawPaint& data) { + return os << data.paint; +} + } // namespace testing } // namespace flutter diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index 2836ccaba2cb5..3515f2ee58e39 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -108,6 +108,10 @@ class MockCanvas : public SkCanvasVirtualEnforcer { ClipEdgeStyle style; }; + struct DrawPaint { + SkPaint paint; + }; + // Discriminated union of all the different |DrawCall| types. It is roughly // equivalent to the different methods in |SkCanvas|' public API. using DrawCallData = std::variant { DrawShadowData, ClipRectData, ClipRRectData, - ClipPathData>; + ClipPathData, + DrawPaint>; // A single call made against this canvas. struct DrawCall { @@ -305,7 +310,10 @@ extern bool operator==(const MockCanvas::DrawCall& a, const MockCanvas::DrawCall& b); extern std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw); - +extern bool operator==(const MockCanvas::DrawPaint& a, + const MockCanvas::DrawPaint& b); +extern std::ostream& operator<<(std::ostream& os, + const MockCanvas::DrawPaint& data); } // namespace testing } // namespace flutter From 239768a93617428a795d54d82ef32082372eed60 Mon Sep 17 00:00:00 2001 From: fredlee12345678 Date: Thu, 5 Nov 2020 15:26:05 +0800 Subject: [PATCH 3/3] fix raster cache bug; if parent_need_cached is true, Clipxxxlayer will preroll the whole process --- flow/layers/backdrop_filter_layer.cc | 5 +++-- flow/layers/backdrop_filter_layer.h | 2 +- flow/layers/backdrop_filter_layer_unittests.cc | 18 +++++++++--------- flow/layers/child_scene_layer.cc | 2 +- flow/layers/child_scene_layer.h | 2 +- flow/layers/clip_path_layer.cc | 12 ++++++++---- flow/layers/clip_path_layer.h | 2 +- flow/layers/clip_path_layer_unittests.cc | 12 ++++++------ flow/layers/clip_rect_layer.cc | 12 ++++++++---- flow/layers/clip_rect_layer.h | 2 +- flow/layers/clip_rect_layer_unittests.cc | 12 ++++++------ flow/layers/clip_rrect_layer.cc | 12 ++++++++---- flow/layers/clip_rrect_layer.h | 2 +- flow/layers/clip_rrect_layer_unittests.cc | 12 ++++++------ flow/layers/color_filter_layer.cc | 5 +++-- flow/layers/color_filter_layer.h | 2 +- flow/layers/color_filter_layer_unittests.cc | 14 +++++++------- flow/layers/container_layer.cc | 9 +++++---- flow/layers/container_layer.h | 6 +++--- flow/layers/container_layer_unittests.cc | 12 ++++++------ flow/layers/image_filter_layer.cc | 5 +++-- flow/layers/image_filter_layer.h | 2 +- flow/layers/image_filter_layer_unittests.cc | 16 ++++++++-------- flow/layers/layer.cc | 2 +- flow/layers/layer.h | 2 +- flow/layers/opacity_layer.cc | 4 ++-- flow/layers/opacity_layer.h | 3 ++- flow/layers/opacity_layer_unittests.cc | 14 +++++++------- .../performance_overlay_layer_unittests.cc | 6 +++--- flow/layers/physical_shape_layer.cc | 2 +- flow/layers/physical_shape_layer.h | 2 +- flow/layers/physical_shape_layer_unittests.cc | 12 ++++++------ flow/layers/picture_layer.cc | 3 +-- flow/layers/picture_layer.h | 2 +- flow/layers/picture_layer_unittests.cc | 4 ++-- flow/layers/platform_view_layer.cc | 3 ++- flow/layers/platform_view_layer.h | 2 +- flow/layers/platform_view_layer_unittests.cc | 2 +- flow/layers/shader_mask_layer.cc | 4 ++-- flow/layers/shader_mask_layer.h | 2 +- flow/layers/shader_mask_layer_unittests.cc | 14 +++++++------- flow/layers/texture_layer.cc | 2 +- flow/layers/texture_layer.h | 2 +- flow/layers/texture_layer_unittests.cc | 4 ++-- flow/layers/transform_layer.cc | 3 ++- flow/layers/transform_layer.h | 2 +- flow/layers/transform_layer_unittests.cc | 10 +++++----- flow/testing/mock_layer.cc | 2 +- flow/testing/mock_layer.h | 2 +- flow/testing/mock_layer_unittests.cc | 8 ++++---- 50 files changed, 157 insertions(+), 139 deletions(-) diff --git a/flow/layers/backdrop_filter_layer.cc b/flow/layers/backdrop_filter_layer.cc index ce86db3deaad7..1631ede9418ba 100644 --- a/flow/layers/backdrop_filter_layer.cc +++ b/flow/layers/backdrop_filter_layer.cc @@ -10,10 +10,11 @@ BackdropFilterLayer::BackdropFilterLayer(sk_sp filter) : filter_(std::move(filter)) {} void BackdropFilterLayer::Preroll(PrerollContext* context, - const SkMatrix& matrix) { + const SkMatrix& matrix, + bool parent_need_cached) { Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context, true, bool(filter_)); - ContainerLayer::Preroll(context, matrix); + ContainerLayer::Preroll(context, matrix, parent_need_cached); } void BackdropFilterLayer::Paint(PaintContext& context) const { diff --git a/flow/layers/backdrop_filter_layer.h b/flow/layers/backdrop_filter_layer.h index e1fd667d712e9..4b9b3de540584 100644 --- a/flow/layers/backdrop_filter_layer.h +++ b/flow/layers/backdrop_filter_layer.h @@ -14,7 +14,7 @@ class BackdropFilterLayer : public ContainerLayer { public: BackdropFilterLayer(sk_sp filter); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/backdrop_filter_layer_unittests.cc b/flow/layers/backdrop_filter_layer_unittests.cc index 47f7b66e35771..674781ba02bc1 100644 --- a/flow/layers/backdrop_filter_layer_unittests.cc +++ b/flow/layers/backdrop_filter_layer_unittests.cc @@ -20,7 +20,7 @@ using BackdropFilterLayerTest = LayerTest; TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(sk_sp()); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -51,7 +51,7 @@ TEST_F(BackdropFilterLayerTest, EmptyFilter) { auto layer = std::make_shared(nullptr); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -77,7 +77,7 @@ TEST_F(BackdropFilterLayerTest, SimpleFilter) { auto layer = std::make_shared(layer_filter); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -110,7 +110,7 @@ TEST_F(BackdropFilterLayerTest, MultipleChildren) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), children_bounds); @@ -153,7 +153,7 @@ TEST_F(BackdropFilterLayerTest, Nested) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer1->paint_bounds(), children_bounds); @@ -190,18 +190,18 @@ TEST_F(BackdropFilterLayerTest, Readback) { // BDF with filter always reads from surface auto layer1 = std::make_shared(layer_filter); preroll_context()->surface_needs_readback = false; - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_TRUE(preroll_context()->surface_needs_readback); // BDF with no filter does not read from surface itself auto layer2 = std::make_shared(no_filter); preroll_context()->surface_needs_readback = false; - layer2->Preroll(preroll_context(), initial_transform); + layer2->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); // BDF with no filter does not block prior readback value preroll_context()->surface_needs_readback = true; - layer2->Preroll(preroll_context(), initial_transform); + layer2->Preroll(preroll_context(), initial_transform, false); EXPECT_TRUE(preroll_context()->surface_needs_readback); // BDF with no filter blocks child with readback @@ -209,7 +209,7 @@ TEST_F(BackdropFilterLayerTest, Readback) { std::make_shared(SkPath(), SkPaint(), false, false, true); layer2->Add(mock_layer); preroll_context()->surface_needs_readback = false; - layer2->Preroll(preroll_context(), initial_transform); + layer2->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); } diff --git a/flow/layers/child_scene_layer.cc b/flow/layers/child_scene_layer.cc index 3408f7b4367d2..abb274b7062db 100644 --- a/flow/layers/child_scene_layer.cc +++ b/flow/layers/child_scene_layer.cc @@ -15,7 +15,7 @@ ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id, size_(size), hit_testable_(hit_testable) {} -void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "ChildSceneLayer::Preroll"); context->child_scene_layer_exists_below = true; diff --git a/flow/layers/child_scene_layer.h b/flow/layers/child_scene_layer.h index 0ec7f3b16efb1..4ee1e0e232d53 100644 --- a/flow/layers/child_scene_layer.h +++ b/flow/layers/child_scene_layer.h @@ -22,7 +22,7 @@ class ChildSceneLayer : public Layer { bool hit_testable); ~ChildSceneLayer() override = default; - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index 0b714392b60f5..d4bfe1c38c9c2 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -16,12 +16,16 @@ ClipPathLayer::ClipPathLayer(const SkPath& clip_path, Clip clip_behavior) FML_DCHECK(clip_behavior != Clip::none); } -void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "ClipPathLayer::Preroll"); SkRect previous_cull_rect = context->cull_rect; SkRect clip_path_bounds = clip_path_.getBounds(); - children_inside_clip_ = context->cull_rect.intersect(clip_path_bounds); + if (parent_need_cached) { + children_inside_clip_ = true; + } else { + children_inside_clip_ = context->cull_rect.intersect(clip_path_bounds); + } if (children_inside_clip_) { TRACE_EVENT_INSTANT0("flutter", "children inside clip rect"); @@ -29,9 +33,9 @@ void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); context->mutators_stack.PushClipPath(clip_path_); SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, matrix, &child_paint_bounds); + PrerollChildren(context, matrix, &child_paint_bounds,parent_need_cached); - if (child_paint_bounds.intersect(clip_path_bounds)) { + if (child_paint_bounds.intersect(clip_path_bounds) || parent_need_cached) { set_paint_bounds(child_paint_bounds); } context->mutators_stack.Pop(); diff --git a/flow/layers/clip_path_layer.h b/flow/layers/clip_path_layer.h index eac015db9e5d1..b3c33853f1f94 100644 --- a/flow/layers/clip_path_layer.h +++ b/flow/layers/clip_path_layer.h @@ -13,7 +13,7 @@ class ClipPathLayer : public ContainerLayer { public: ClipPathLayer(const SkPath& clip_path, Clip clip_behavior = Clip::antiAlias); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/clip_path_layer_unittests.cc b/flow/layers/clip_path_layer_unittests.cc index 6491fe5b40db7..37bafb11155d4 100644 --- a/flow/layers/clip_path_layer_unittests.cc +++ b/flow/layers/clip_path_layer_unittests.cc @@ -24,7 +24,7 @@ TEST_F(ClipPathLayerTest, ClipNoneBehaviorDies) { TEST_F(ClipPathLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(SkPath(), Clip::hardEdge); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(layer->paint_bounds(), kEmptyRect); @@ -57,7 +57,7 @@ TEST_F(ClipPathLayerTest, PaintingCulledLayerDies) { preroll_context()->cull_rect = kEmptyRect; // Cull everything - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); @@ -91,7 +91,7 @@ TEST_F(ClipPathLayerTest, ChildOutsideBounds) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -126,7 +126,7 @@ TEST_F(ClipPathLayerTest, FullyContainedChild) { auto layer = std::make_shared(layer_path, Clip::hardEdge); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -168,7 +168,7 @@ TEST_F(ClipPathLayerTest, PartiallyContainedChild) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -204,7 +204,7 @@ static bool ReadbackResult(PrerollContext* context, layer->Add(child); } context->surface_needs_readback = before; - layer->Preroll(context, initial_matrix); + layer->Preroll(context, initial_matrix, false); return context->surface_needs_readback; } diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index cd4443b5c0198..eeaa9840982d2 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -12,11 +12,15 @@ ClipRectLayer::ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior) FML_DCHECK(clip_behavior != Clip::none); } -void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "ClipRectLayer::Preroll"); SkRect previous_cull_rect = context->cull_rect; - children_inside_clip_ = context->cull_rect.intersect(clip_rect_); + if (parent_need_cached) { + children_inside_clip_ = true; + } else { + children_inside_clip_ = context->cull_rect.intersect(clip_rect_); + } if (children_inside_clip_) { TRACE_EVENT_INSTANT0("flutter", "children inside clip rect"); @@ -24,9 +28,9 @@ void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); context->mutators_stack.PushClipRect(clip_rect_); SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, matrix, &child_paint_bounds); + PrerollChildren(context, matrix, &child_paint_bounds, parent_need_cached); - if (child_paint_bounds.intersect(clip_rect_)) { + if (child_paint_bounds.intersect(clip_rect_) || parent_need_cached) { set_paint_bounds(child_paint_bounds); } context->mutators_stack.Pop(); diff --git a/flow/layers/clip_rect_layer.h b/flow/layers/clip_rect_layer.h index 9c57861d87fe2..054c6f018142c 100644 --- a/flow/layers/clip_rect_layer.h +++ b/flow/layers/clip_rect_layer.h @@ -13,7 +13,7 @@ class ClipRectLayer : public ContainerLayer { public: ClipRectLayer(const SkRect& clip_rect, Clip clip_behavior); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; bool UsesSaveLayer() const { diff --git a/flow/layers/clip_rect_layer_unittests.cc b/flow/layers/clip_rect_layer_unittests.cc index 70decfa154e34..4597c59daa781 100644 --- a/flow/layers/clip_rect_layer_unittests.cc +++ b/flow/layers/clip_rect_layer_unittests.cc @@ -24,7 +24,7 @@ TEST_F(ClipRectLayerTest, ClipNoneBehaviorDies) { TEST_F(ClipRectLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(kEmptyRect, Clip::hardEdge); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(layer->paint_bounds(), kEmptyRect); @@ -55,7 +55,7 @@ TEST_F(ClipRectLayerTest, PaintingCulledLayerDies) { preroll_context()->cull_rect = kEmptyRect; // Cull everything - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); @@ -88,7 +88,7 @@ TEST_F(ClipRectLayerTest, ChildOutsideBounds) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -123,7 +123,7 @@ TEST_F(ClipRectLayerTest, FullyContainedChild) { auto layer = std::make_shared(layer_bounds, Clip::hardEdge); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -165,7 +165,7 @@ TEST_F(ClipRectLayerTest, PartiallyContainedChild) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -201,7 +201,7 @@ static bool ReadbackResult(PrerollContext* context, layer->Add(child); } context->surface_needs_readback = before; - layer->Preroll(context, initial_matrix); + layer->Preroll(context, initial_matrix, false); return context->surface_needs_readback; } diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index 32ed1a39096ab..7d5e82c2a1cf2 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -12,12 +12,16 @@ ClipRRectLayer::ClipRRectLayer(const SkRRect& clip_rrect, Clip clip_behavior) FML_DCHECK(clip_behavior != Clip::none); } -void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "ClipRRectLayer::Preroll"); SkRect previous_cull_rect = context->cull_rect; SkRect clip_rrect_bounds = clip_rrect_.getBounds(); - children_inside_clip_ = context->cull_rect.intersect(clip_rrect_bounds); + if (parent_need_cached) { + children_inside_clip_ = true; + } else { + children_inside_clip_ = context->cull_rect.intersect(clip_rrect_bounds); + } if (children_inside_clip_) { TRACE_EVENT_INSTANT0("flutter", "children inside clip rect"); @@ -25,9 +29,9 @@ void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); context->mutators_stack.PushClipRRect(clip_rrect_); SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, matrix, &child_paint_bounds); + PrerollChildren(context, matrix, &child_paint_bounds, parent_need_cached); - if (child_paint_bounds.intersect(clip_rrect_bounds)) { + if (child_paint_bounds.intersect(clip_rrect_bounds) || parent_need_cached) { set_paint_bounds(child_paint_bounds); } context->mutators_stack.Pop(); diff --git a/flow/layers/clip_rrect_layer.h b/flow/layers/clip_rrect_layer.h index 1422615c5c6b3..7c24fcb21082f 100644 --- a/flow/layers/clip_rrect_layer.h +++ b/flow/layers/clip_rrect_layer.h @@ -13,7 +13,7 @@ class ClipRRectLayer : public ContainerLayer { public: ClipRRectLayer(const SkRRect& clip_rrect, Clip clip_behavior); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/clip_rrect_layer_unittests.cc b/flow/layers/clip_rrect_layer_unittests.cc index 39d40b72221ee..4d56ead638289 100644 --- a/flow/layers/clip_rrect_layer_unittests.cc +++ b/flow/layers/clip_rrect_layer_unittests.cc @@ -26,7 +26,7 @@ TEST_F(ClipRRectLayerTest, PaintingEmptyLayerDies) { const SkRRect layer_rrect = SkRRect::MakeEmpty(); auto layer = std::make_shared(layer_rrect, Clip::hardEdge); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(layer->paint_bounds(), kEmptyRect); @@ -60,7 +60,7 @@ TEST_F(ClipRRectLayerTest, PaintingCulledLayerDies) { preroll_context()->cull_rect = kEmptyRect; // Cull everything - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); @@ -94,7 +94,7 @@ TEST_F(ClipRRectLayerTest, ChildOutsideBounds) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -129,7 +129,7 @@ TEST_F(ClipRRectLayerTest, FullyContainedChild) { auto layer = std::make_shared(layer_rrect, Clip::hardEdge); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -171,7 +171,7 @@ TEST_F(ClipRRectLayerTest, PartiallyContainedChild) { child_intersect_bounds.intersect(child_bounds); preroll_context()->cull_rect = cull_bounds; // Cull child - layer->Preroll(preroll_context(), initial_matrix); + layer->Preroll(preroll_context(), initial_matrix, false); EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); @@ -207,7 +207,7 @@ static bool ReadbackResult(PrerollContext* context, layer->Add(child); } context->surface_needs_readback = before; - layer->Preroll(context, initial_matrix); + layer->Preroll(context, initial_matrix, false); return context->surface_needs_readback; } diff --git a/flow/layers/color_filter_layer.cc b/flow/layers/color_filter_layer.cc index b212720da581d..f57723a3b1bbd 100644 --- a/flow/layers/color_filter_layer.cc +++ b/flow/layers/color_filter_layer.cc @@ -10,10 +10,11 @@ ColorFilterLayer::ColorFilterLayer(sk_sp filter) : filter_(std::move(filter)) {} void ColorFilterLayer::Preroll(PrerollContext* context, - const SkMatrix& matrix) { + const SkMatrix& matrix, + bool parent_need_cached) { Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context); - ContainerLayer::Preroll(context, matrix); + ContainerLayer::Preroll(context, matrix,parent_need_cached); } void ColorFilterLayer::Paint(PaintContext& context) const { diff --git a/flow/layers/color_filter_layer.h b/flow/layers/color_filter_layer.h index cd3c584b4405b..a67a5ca1720c9 100644 --- a/flow/layers/color_filter_layer.h +++ b/flow/layers/color_filter_layer.h @@ -14,7 +14,7 @@ class ColorFilterLayer : public ContainerLayer { public: ColorFilterLayer(sk_sp filter); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/color_filter_layer_unittests.cc b/flow/layers/color_filter_layer_unittests.cc index 5c16f8c0cb1f0..12982121f98ee 100644 --- a/flow/layers/color_filter_layer_unittests.cc +++ b/flow/layers/color_filter_layer_unittests.cc @@ -20,7 +20,7 @@ using ColorFilterLayerTest = LayerTest; TEST_F(ColorFilterLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(sk_sp()); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -51,7 +51,7 @@ TEST_F(ColorFilterLayerTest, EmptyFilter) { auto layer = std::make_shared(nullptr); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -80,7 +80,7 @@ TEST_F(ColorFilterLayerTest, SimpleFilter) { auto layer = std::make_shared(layer_filter); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -116,7 +116,7 @@ TEST_F(ColorFilterLayerTest, MultipleChildren) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), children_bounds); @@ -163,7 +163,7 @@ TEST_F(ColorFilterLayerTest, Nested) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer1->paint_bounds(), children_bounds); @@ -202,7 +202,7 @@ TEST_F(ColorFilterLayerTest, Readback) { // ColorFilterLayer does not read from surface auto layer = std::make_shared(layer_filter); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); // ColorFilterLayer blocks child with readback @@ -210,7 +210,7 @@ TEST_F(ColorFilterLayerTest, Readback) { std::make_shared(SkPath(), SkPaint(), false, false, true); layer->Add(mock_layer); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); } diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index a6ad98ba1aae4..a934efe9c4b48 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -14,11 +14,11 @@ void ContainerLayer::Add(std::shared_ptr layer) { layers_.emplace_back(std::move(layer)); } -void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "ContainerLayer::Preroll"); SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, matrix, &child_paint_bounds); + PrerollChildren(context, matrix, &child_paint_bounds,parent_need_cached); set_paint_bounds(child_paint_bounds); } @@ -30,7 +30,8 @@ void ContainerLayer::Paint(PaintContext& context) const { void ContainerLayer::PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, - SkRect* child_paint_bounds) { + SkRect* child_paint_bounds, + bool parent_need_cached) { #if defined(LEGACY_FUCHSIA_EMBEDDER) // If there is embedded Fuchsia content in the scene (a ChildSceneLayer), // Layers that appear above the embedded content will be turned into their own @@ -49,7 +50,7 @@ void ContainerLayer::PrerollChildren(PrerollContext* context, // sibling tree. context->has_platform_view = false; - layer->Preroll(context, child_matrix); + layer->Preroll(context, child_matrix, parent_need_cached); if (layer->needs_system_composite()) { set_needs_system_composite(true); diff --git a/flow/layers/container_layer.h b/flow/layers/container_layer.h index 11eae5f3fe123..3c62cfd5da4a3 100644 --- a/flow/layers/container_layer.h +++ b/flow/layers/container_layer.h @@ -6,7 +6,6 @@ #define FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_ #include - #include "flutter/flow/layers/layer.h" namespace flutter { @@ -17,7 +16,7 @@ class ContainerLayer : public Layer { virtual void Add(std::shared_ptr layer); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; #if defined(LEGACY_FUCHSIA_EMBEDDER) void CheckForChildLayerBelow(PrerollContext* context) override; @@ -29,7 +28,8 @@ class ContainerLayer : public Layer { protected: void PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, - SkRect* child_paint_bounds); + SkRect* child_paint_bounds, + bool parent_need_cached ); void PaintChildren(PaintContext& context) const; #if defined(LEGACY_FUCHSIA_EMBEDDER) diff --git a/flow/layers/container_layer_unittests.cc b/flow/layers/container_layer_unittests.cc index 65c2ff365fa0c..b9e47f69fede2 100644 --- a/flow/layers/container_layer_unittests.cc +++ b/flow/layers/container_layer_unittests.cc @@ -19,14 +19,14 @@ TEST_F(ContainerLayerTest, LayerWithParentHasPlatformView) { auto layer = std::make_shared(); preroll_context()->has_platform_view = true; - EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), + EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix(), false), "!context->has_platform_view"); } TEST_F(ContainerLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -58,7 +58,7 @@ TEST_F(ContainerLayerTest, Simple) { auto layer = std::make_shared(); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->has_platform_view); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), child_path.getBounds()); @@ -93,7 +93,7 @@ TEST_F(ContainerLayerTest, Multiple) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_TRUE(preroll_context()->has_platform_view); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); @@ -132,7 +132,7 @@ TEST_F(ContainerLayerTest, MultipleWithEmpty) { layer->Add(mock_layer1); layer->Add(mock_layer2); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->has_platform_view); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds()); @@ -173,7 +173,7 @@ TEST_F(ContainerLayerTest, NeedsSystemComposite) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->has_platform_view); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); diff --git a/flow/layers/image_filter_layer.cc b/flow/layers/image_filter_layer.cc index 6f2d7aa59e407..a21640453fb84 100644 --- a/flow/layers/image_filter_layer.cc +++ b/flow/layers/image_filter_layer.cc @@ -12,14 +12,15 @@ ImageFilterLayer::ImageFilterLayer(sk_sp filter) render_count_(1) {} void ImageFilterLayer::Preroll(PrerollContext* context, - const SkMatrix& matrix) { + const SkMatrix& matrix, + bool parent_need_cached) { TRACE_EVENT0("flutter", "ImageFilterLayer::Preroll"); Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context); SkRect child_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, matrix, &child_bounds); + PrerollChildren(context, matrix, &child_bounds, true); if (filter_) { const SkIRect filter_input_bounds = child_bounds.roundOut(); SkIRect filter_output_bounds = diff --git a/flow/layers/image_filter_layer.h b/flow/layers/image_filter_layer.h index 4b274fef8fdc3..35878cf65b35b 100644 --- a/flow/layers/image_filter_layer.h +++ b/flow/layers/image_filter_layer.h @@ -14,7 +14,7 @@ class ImageFilterLayer : public MergedContainerLayer { public: ImageFilterLayer(sk_sp filter); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/image_filter_layer_unittests.cc b/flow/layers/image_filter_layer_unittests.cc index bcc2d8e08e8b0..b62742e771c6a 100644 --- a/flow/layers/image_filter_layer_unittests.cc +++ b/flow/layers/image_filter_layer_unittests.cc @@ -19,7 +19,7 @@ using ImageFilterLayerTest = LayerTest; TEST_F(ImageFilterLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(sk_sp()); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -50,7 +50,7 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) { auto layer = std::make_shared(nullptr); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -83,7 +83,7 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) { const SkRect child_rounded_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 21.0f, 22.0f); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_rounded_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -116,7 +116,7 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) { const SkRect filter_bounds = SkRect::MakeLTRB(10.0f, 12.0f, 42.0f, 44.0f); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), filter_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -155,7 +155,7 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) { children_bounds.join(child_path2.getBounds()); SkRect children_rounded_bounds = SkRect::Make(children_bounds.roundOut()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), children_rounded_bounds); @@ -207,7 +207,7 @@ TEST_F(ImageFilterLayerTest, Nested) { const SkRect mock_layer2_rounded_bounds = SkRect::Make(child_path2.getBounds().roundOut()); - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer1->paint_bounds(), children_rounded_bounds); @@ -248,7 +248,7 @@ TEST_F(ImageFilterLayerTest, Readback) { // ImageFilterLayer does not read from surface auto layer = std::make_shared(layer_filter); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); // ImageFilterLayer blocks child with readback @@ -256,7 +256,7 @@ TEST_F(ImageFilterLayerTest, Readback) { std::make_shared(SkPath(), SkPaint(), false, false, true); layer->Add(mock_layer); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); } diff --git a/flow/layers/layer.cc b/flow/layers/layer.cc index 006f5cb84e916..6311495c2ed26 100644 --- a/flow/layers/layer.cc +++ b/flow/layers/layer.cc @@ -25,7 +25,7 @@ uint64_t Layer::NextUniqueID() { return id; } -void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {} +void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) {} Layer::AutoPrerollSaveLayerState::AutoPrerollSaveLayerState( PrerollContext* preroll_context, diff --git a/flow/layers/layer.h b/flow/layers/layer.h index 0ce351db63b2f..e005ba18ce5b5 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -73,7 +73,7 @@ class Layer { Layer(); virtual ~Layer(); - virtual void Preroll(PrerollContext* context, const SkMatrix& matrix); + virtual void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached = false); // Used during Preroll by layers that employ a saveLayer to manage the // PrerollContext settings with values affected by the saveLayer mechanism. diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index b8922bff18b10..809ddd5190fa2 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -12,7 +12,7 @@ namespace flutter { OpacityLayer::OpacityLayer(SkAlpha alpha, const SkPoint& offset) : alpha_(alpha), offset_(offset) {} -void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "OpacityLayer::Preroll"); FML_DCHECK(!GetChildContainer()->layers().empty()); // We can't be a leaf. @@ -28,7 +28,7 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { context->mutators_stack.PushOpacity(alpha_); Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context); - ContainerLayer::Preroll(context, child_matrix); + ContainerLayer::Preroll(context, child_matrix,true); context->mutators_stack.Pop(); context->mutators_stack.Pop(); diff --git a/flow/layers/opacity_layer.h b/flow/layers/opacity_layer.h index 25f1c7944a829..fb229ae3b764d 100644 --- a/flow/layers/opacity_layer.h +++ b/flow/layers/opacity_layer.h @@ -27,7 +27,8 @@ class OpacityLayer : public MergedContainerLayer { // the propagation as repainting the OpacityLayer is expensive. OpacityLayer(SkAlpha alpha, const SkPoint& offset); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc index b8238cc8da45c..004085b52cba7 100644 --- a/flow/layers/opacity_layer_unittests.cc +++ b/flow/layers/opacity_layer_unittests.cc @@ -31,7 +31,7 @@ TEST_F(OpacityLayerTest, PaintingEmptyLayerDies) { std::make_shared(SK_AlphaOPAQUE, SkPoint::Make(0.0f, 0.0f)); layer->Add(mock_layer); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(mock_layer->paint_bounds(), SkPath().getBounds()); EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); EXPECT_FALSE(mock_layer->needs_painting()); @@ -153,7 +153,7 @@ TEST_F(OpacityLayerTest, FullyOpaque) { auto layer = std::make_shared(SK_AlphaOPAQUE, layer_offset); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); EXPECT_TRUE(mock_layer->needs_painting()); @@ -203,7 +203,7 @@ TEST_F(OpacityLayerTest, FullyTransparent) { std::make_shared(SK_AlphaTRANSPARENT, layer_offset); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); EXPECT_TRUE(mock_layer->needs_painting()); @@ -251,7 +251,7 @@ TEST_F(OpacityLayerTest, HalfTransparent) { auto layer = std::make_shared(alpha_half, layer_offset); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds); EXPECT_TRUE(mock_layer->needs_painting()); @@ -323,7 +323,7 @@ TEST_F(OpacityLayerTest, Nested) { expected_layer1_bounds.join(child1_path.getBounds()); expected_layer1_bounds.join(child3_path.getBounds()); expected_layer1_bounds = layer1_transform.mapRect(expected_layer1_bounds); - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child1_path.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child2_path.getBounds()); EXPECT_EQ(mock_layer3->paint_bounds(), child3_path.getBounds()); @@ -399,7 +399,7 @@ TEST_F(OpacityLayerTest, Readback) { // OpacityLayer does not read from surface preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); // OpacityLayer blocks child with readback @@ -407,7 +407,7 @@ TEST_F(OpacityLayerTest, Readback) { std::make_shared(SkPath(), SkPaint(), false, false, true); layer->Add(mock_layer); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); } diff --git a/flow/layers/performance_overlay_layer_unittests.cc b/flow/layers/performance_overlay_layer_unittests.cc index 7a010fd4e703c..7cb01e6926c18 100644 --- a/flow/layers/performance_overlay_layer_unittests.cc +++ b/flow/layers/performance_overlay_layer_unittests.cc @@ -124,7 +124,7 @@ TEST_F(PerformanceOverlayLayerTest, PaintingEmptyLayerDies) { const uint64_t overlay_opts = kVisualizeRasterizerStatistics; auto layer = std::make_shared(overlay_opts); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_FALSE(layer->needs_painting()); @@ -141,7 +141,7 @@ TEST_F(PerformanceOverlayLayerTest, InvalidOptions) { // this a constructor parameter and move the set_paint_bounds into Preroll layer->set_paint_bounds(layer_bounds); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), layer_bounds); EXPECT_TRUE(layer->needs_painting()); @@ -159,7 +159,7 @@ TEST_F(PerformanceOverlayLayerTest, SimpleRasterizerStatistics) { // this a constructor parameter and move the set_paint_bounds into Preroll layer->set_paint_bounds(layer_bounds); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), layer_bounds); EXPECT_TRUE(layer->needs_painting()); diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 534962fff0a40..67b7b722603e9 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -24,7 +24,7 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color, clip_behavior_(clip_behavior) {} void PhysicalShapeLayer::Preroll(PrerollContext* context, - const SkMatrix& matrix) { + const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "PhysicalShapeLayer::Preroll"); Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); diff --git a/flow/layers/physical_shape_layer.h b/flow/layers/physical_shape_layer.h index ce49af1a003ae..1a799159b326c 100644 --- a/flow/layers/physical_shape_layer.h +++ b/flow/layers/physical_shape_layer.h @@ -27,7 +27,7 @@ class PhysicalShapeLayer : public ContainerLayer { bool transparentOccluder, SkScalar dpr); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc index bb5d0acfad757..d44373e5a2323 100644 --- a/flow/layers/physical_shape_layer_unittests.cc +++ b/flow/layers/physical_shape_layer_unittests.cc @@ -21,7 +21,7 @@ TEST_F(PhysicalShapeLayerTest, PaintingEmptyLayerDies) { 0.0f, // elevation SkPath(), Clip::none); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -52,7 +52,7 @@ TEST_F(PhysicalShapeLayerTest, NonEmptyLayer) { std::make_shared(SK_ColorGREEN, SK_ColorBLACK, 0.0f, // elevation layer_path, Clip::none); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds()); EXPECT_TRUE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -88,7 +88,7 @@ TEST_F(PhysicalShapeLayerTest, ChildrenLargerThanPath) { layer->Add(child2); SkRect child_paint_bounds; - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); child_paint_bounds.join(child1->paint_bounds()); child_paint_bounds.join(child2->paint_bounds()); EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds()); @@ -123,7 +123,7 @@ TEST_F(PhysicalShapeLayerTest, ElevationSimple) { auto layer = std::make_shared( SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path, Clip::none); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); // The Fuchsia system compositor handles all elevated PhysicalShapeLayers and // their shadows , so we do not do any painting there. EXPECT_EQ(layer->paint_bounds(), @@ -175,7 +175,7 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) { layers[0]->Add(layers[2]); layers[2]->Add(layers[3]); - layers[0]->Preroll(preroll_context(), SkMatrix()); + layers[0]->Preroll(preroll_context(), SkMatrix(), false); for (int i = 0; i < 4; i += 1) { // On Fuchsia, the system compositor handles all elevated // PhysicalShapeLayers and their shadows , so we do not do any painting @@ -228,7 +228,7 @@ static bool ReadbackResult(PrerollContext* context, layer->Add(child); } context->surface_needs_readback = before; - layer->Preroll(context, initial_matrix); + layer->Preroll(context, initial_matrix, false); return context->surface_needs_readback; } diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 6df2c9e34bf30..7f8d9131566a0 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -17,9 +17,8 @@ PictureLayer::PictureLayer(const SkPoint& offset, is_complex_(is_complex), will_change_(will_change) {} -void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "PictureLayer::Preroll"); - #if defined(LEGACY_FUCHSIA_EMBEDDER) CheckForChildLayerBelow(context); #endif diff --git a/flow/layers/picture_layer.h b/flow/layers/picture_layer.h index e733e7455ca6c..3ab2f274f864c 100644 --- a/flow/layers/picture_layer.h +++ b/flow/layers/picture_layer.h @@ -22,7 +22,7 @@ class PictureLayer : public Layer { SkPicture* picture() const { return picture_.get().get(); } - void Preroll(PrerollContext* frame, const SkMatrix& matrix) override; + void Preroll(PrerollContext* frame, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/picture_layer_unittests.cc b/flow/layers/picture_layer_unittests.cc index dc9e6080c1508..68370442a2904 100644 --- a/flow/layers/picture_layer_unittests.cc +++ b/flow/layers/picture_layer_unittests.cc @@ -49,7 +49,7 @@ TEST_F(PictureLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared( layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_FALSE(layer->needs_painting()); EXPECT_FALSE(layer->needs_system_composite()); @@ -77,7 +77,7 @@ TEST_F(PictureLayerTest, SimplePicture) { auto layer = std::make_shared( layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), picture_bounds.makeOffset(layer_offset.fX, layer_offset.fY)); EXPECT_EQ(layer->picture(), mock_picture.get()); diff --git a/flow/layers/platform_view_layer.cc b/flow/layers/platform_view_layer.cc index 0971f93db777e..18ad4f45585f2 100644 --- a/flow/layers/platform_view_layer.cc +++ b/flow/layers/platform_view_layer.cc @@ -12,7 +12,8 @@ PlatformViewLayer::PlatformViewLayer(const SkPoint& offset, : offset_(offset), size_(size), view_id_(view_id) {} void PlatformViewLayer::Preroll(PrerollContext* context, - const SkMatrix& matrix) { + const SkMatrix& matrix, + bool parent_need_cached) { #if defined(LEGACY_FUCHSIA_EMBEDDER) context->child_scene_layer_exists_below = true; CheckForChildLayerBelow(context); diff --git a/flow/layers/platform_view_layer.h b/flow/layers/platform_view_layer.h index e9d6fac42eb23..44cfd24085c23 100644 --- a/flow/layers/platform_view_layer.h +++ b/flow/layers/platform_view_layer.h @@ -15,7 +15,7 @@ class PlatformViewLayer : public Layer { public: PlatformViewLayer(const SkPoint& offset, const SkSize& size, int64_t view_id); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; #if defined(LEGACY_FUCHSIA_EMBEDDER) // Updates the system composited scene. diff --git a/flow/layers/platform_view_layer_unittests.cc b/flow/layers/platform_view_layer_unittests.cc index 98393651e27f0..3836d5f0045e0 100644 --- a/flow/layers/platform_view_layer_unittests.cc +++ b/flow/layers/platform_view_layer_unittests.cc @@ -21,7 +21,7 @@ TEST_F(PlatformViewLayerTest, NullViewEmbedderDoesntPrerollCompositeOrPaint) { auto layer = std::make_shared(layer_offset, layer_size, view_id); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_FALSE(preroll_context()->has_platform_view); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeSize(layer_size) diff --git a/flow/layers/shader_mask_layer.cc b/flow/layers/shader_mask_layer.cc index a03edfd504879..b2b7b52d3e1f5 100644 --- a/flow/layers/shader_mask_layer.cc +++ b/flow/layers/shader_mask_layer.cc @@ -11,14 +11,14 @@ ShaderMaskLayer::ShaderMaskLayer(sk_sp shader, SkBlendMode blend_mode) : shader_(shader), mask_rect_(mask_rect), blend_mode_(blend_mode) {} -void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { #if defined(LEGACY_FUCHSIA_EMBEDDER) CheckForChildLayerBelow(context); #endif Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context); - ContainerLayer::Preroll(context, matrix); + ContainerLayer::Preroll(context, matrix, parent_need_cached); } void ShaderMaskLayer::Paint(PaintContext& context) const { diff --git a/flow/layers/shader_mask_layer.h b/flow/layers/shader_mask_layer.h index 9bfce9644bc5a..a7123f3f61cee 100644 --- a/flow/layers/shader_mask_layer.h +++ b/flow/layers/shader_mask_layer.h @@ -16,7 +16,7 @@ class ShaderMaskLayer : public ContainerLayer { const SkRect& mask_rect, SkBlendMode blend_mode); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/shader_mask_layer_unittests.cc b/flow/layers/shader_mask_layer_unittests.cc index a4118ce2dbc75..77daf04a76fed 100644 --- a/flow/layers/shader_mask_layer_unittests.cc +++ b/flow/layers/shader_mask_layer_unittests.cc @@ -21,7 +21,7 @@ TEST_F(ShaderMaskLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(nullptr, kEmptyRect, SkBlendMode::kSrc); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_FALSE(layer->needs_painting()); @@ -54,7 +54,7 @@ TEST_F(ShaderMaskLayerTest, EmptyFilter) { SkBlendMode::kSrc); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(mock_layer->needs_painting()); @@ -96,7 +96,7 @@ TEST_F(ShaderMaskLayerTest, SimpleFilter) { SkBlendMode::kSrc); layer->Add(mock_layer); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(layer->paint_bounds(), child_bounds); EXPECT_TRUE(layer->needs_painting()); EXPECT_EQ(mock_layer->parent_matrix(), initial_transform); @@ -143,7 +143,7 @@ TEST_F(ShaderMaskLayerTest, MultipleChildren) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), children_bounds); @@ -202,7 +202,7 @@ TEST_F(ShaderMaskLayerTest, Nested) { SkRect children_bounds = child_path1.getBounds(); children_bounds.join(child_path2.getBounds()); - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer1->paint_bounds(), children_bounds); @@ -263,7 +263,7 @@ TEST_F(ShaderMaskLayerTest, Readback) { // ShaderMaskLayer does not read from surface preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); // ShaderMaskLayer blocks child with readback @@ -271,7 +271,7 @@ TEST_F(ShaderMaskLayerTest, Readback) { std::make_shared(SkPath(), SkPaint(), false, false, true); layer->Add(mock_layer); preroll_context()->surface_needs_readback = false; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_FALSE(preroll_context()->surface_needs_readback); } diff --git a/flow/layers/texture_layer.cc b/flow/layers/texture_layer.cc index 55e3ed3f16e3c..f4e10e3f0f1c1 100644 --- a/flow/layers/texture_layer.cc +++ b/flow/layers/texture_layer.cc @@ -19,7 +19,7 @@ TextureLayer::TextureLayer(const SkPoint& offset, freeze_(freeze), filter_quality_(filter_quality) {} -void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "TextureLayer::Preroll"); #if defined(LEGACY_FUCHSIA_EMBEDDER) diff --git a/flow/layers/texture_layer.h b/flow/layers/texture_layer.h index 250cefd10eea6..c4e0422398659 100644 --- a/flow/layers/texture_layer.h +++ b/flow/layers/texture_layer.h @@ -20,7 +20,7 @@ class TextureLayer : public Layer { bool freeze, SkFilterQuality filter_quality); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; private: diff --git a/flow/layers/texture_layer_unittests.cc b/flow/layers/texture_layer_unittests.cc index 525239a8e0f5f..1fd2b453ad610 100644 --- a/flow/layers/texture_layer_unittests.cc +++ b/flow/layers/texture_layer_unittests.cc @@ -21,7 +21,7 @@ TEST_F(TextureLayerTest, InvalidTexture) { auto layer = std::make_shared(layer_offset, layer_size, 0, false, kNone_SkFilterQuality); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), (SkRect::MakeSize(layer_size) .makeOffset(layer_offset.fX, layer_offset.fY))); @@ -42,7 +42,7 @@ TEST_F(TextureLayerTest, PaintingEmptyLayerDies) { // Ensure the texture is located by the Layer. preroll_context()->texture_registry.RegisterTexture(mock_texture); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_FALSE(layer->needs_painting()); diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc index 3e26e525ac637..968f8f02bc0e2 100644 --- a/flow/layers/transform_layer.cc +++ b/flow/layers/transform_layer.cc @@ -27,6 +27,7 @@ TransformLayer::TransformLayer(const SkMatrix& transform) } void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { TRACE_EVENT0("flutter", "TransformLayer::Preroll"); SkMatrix child_matrix; @@ -43,7 +44,7 @@ void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { } SkRect child_paint_bounds = SkRect::MakeEmpty(); - PrerollChildren(context, child_matrix, &child_paint_bounds); + PrerollChildren(context, child_matrix, &child_paint_bounds,need_raster_cached_); transform_.mapRect(&child_paint_bounds); set_paint_bounds(child_paint_bounds); diff --git a/flow/layers/transform_layer.h b/flow/layers/transform_layer.h index 7956e3906a680..1065df7acc4d8 100644 --- a/flow/layers/transform_layer.h +++ b/flow/layers/transform_layer.h @@ -15,7 +15,7 @@ class TransformLayer : public ContainerLayer { public: TransformLayer(const SkMatrix& transform); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; diff --git a/flow/layers/transform_layer_unittests.cc b/flow/layers/transform_layer_unittests.cc index 5820e021055c5..062c5f589224f 100644 --- a/flow/layers/transform_layer_unittests.cc +++ b/flow/layers/transform_layer_unittests.cc @@ -18,7 +18,7 @@ using TransformLayerTest = LayerTest; TEST_F(TransformLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(SkMatrix()); // identity - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_FALSE(layer->needs_painting()); @@ -47,7 +47,7 @@ TEST_F(TransformLayerTest, Identity) { layer->Add(mock_layer); preroll_context()->cull_rect = cull_rect; - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); EXPECT_TRUE(mock_layer->needs_painting()); @@ -76,7 +76,7 @@ TEST_F(TransformLayerTest, Simple) { layer->Add(mock_layer); preroll_context()->cull_rect = cull_rect; - layer->Preroll(preroll_context(), initial_transform); + layer->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer->paint_bounds(), layer_transform.mapRect(mock_layer->paint_bounds())); @@ -118,7 +118,7 @@ TEST_F(TransformLayerTest, Nested) { layer2->Add(mock_layer); preroll_context()->cull_rect = cull_rect; - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds()); EXPECT_EQ(layer2->paint_bounds(), layer2_transform.mapRect(mock_layer->paint_bounds())); @@ -175,7 +175,7 @@ TEST_F(TransformLayerTest, NestedSeparated) { layer2->Add(mock_layer2); preroll_context()->cull_rect = cull_rect; - layer1->Preroll(preroll_context(), initial_transform); + layer1->Preroll(preroll_context(), initial_transform, false); SkRect expected_layer1_bounds = layer2->paint_bounds(); expected_layer1_bounds.join(mock_layer1->paint_bounds()); layer1_transform.mapRect(&expected_layer1_bounds); diff --git a/flow/testing/mock_layer.cc b/flow/testing/mock_layer.cc index b32bdb23abc09..64545ecc7419e 100644 --- a/flow/testing/mock_layer.cc +++ b/flow/testing/mock_layer.cc @@ -18,7 +18,7 @@ MockLayer::MockLayer(SkPath path, fake_needs_system_composite_(fake_needs_system_composite), fake_reads_surface_(fake_reads_surface) {} -void MockLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { +void MockLayer::Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) { parent_mutators_ = context->mutators_stack; parent_matrix_ = matrix; parent_cull_rect_ = context->cull_rect; diff --git a/flow/testing/mock_layer.h b/flow/testing/mock_layer.h index b92583f581209..b9748478af817 100644 --- a/flow/testing/mock_layer.h +++ b/flow/testing/mock_layer.h @@ -22,7 +22,7 @@ class MockLayer : public Layer { bool fake_needs_system_composite = false, bool fake_reads_surface = false); - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Preroll(PrerollContext* context, const SkMatrix& matrix, bool parent_need_cached) override; void Paint(PaintContext& context) const override; const MutatorsStack& parent_mutators() { return parent_mutators_; } diff --git a/flow/testing/mock_layer_unittests.cc b/flow/testing/mock_layer_unittests.cc index ebb837ca8b8dd..cb435e110ee9a 100644 --- a/flow/testing/mock_layer_unittests.cc +++ b/flow/testing/mock_layer_unittests.cc @@ -25,7 +25,7 @@ TEST_F(MockLayerTest, PaintBeforePreollDies) { TEST_F(MockLayerTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(SkPath(), SkPaint()); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->paint_bounds(), SkPath().getBounds()); EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), @@ -45,7 +45,7 @@ TEST_F(MockLayerTest, SimpleParams) { preroll_context()->mutators_stack.PushTransform(scale_matrix); preroll_context()->cull_rect = cull_rect; preroll_context()->has_platform_view = parent_has_platform_view; - layer->Preroll(preroll_context(), start_matrix); + layer->Preroll(preroll_context(), start_matrix, false); EXPECT_EQ(preroll_context()->has_platform_view, false); EXPECT_EQ(layer->paint_bounds(), path.getBounds()); EXPECT_TRUE(layer->needs_painting()); @@ -66,7 +66,7 @@ TEST_F(MockLayerTest, FakePlatformView) { true /* fake_has_platform_view */); EXPECT_EQ(preroll_context()->has_platform_view, false); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(preroll_context()->has_platform_view, true); } @@ -76,7 +76,7 @@ TEST_F(MockLayerTest, FakeSystemComposite) { true /* fake_needs_system_composite */); EXPECT_EQ(layer->needs_system_composite(), false); - layer->Preroll(preroll_context(), SkMatrix()); + layer->Preroll(preroll_context(), SkMatrix(), false); EXPECT_EQ(layer->needs_system_composite(), true); }