Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit fdead7a

Browse files
authored
[CP] Remove LayerStateStack premature culling (#38163)
* Fix premature LayerStateStack layer culling (#38159) * remove premature opacity culling * remove premature clip culling * empty
1 parent b379dc9 commit fdead7a

9 files changed

+130
-12
lines changed

flow/layers/clip_path_layer_unittests.cc

+27
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66

77
#include "flutter/flow/layers/layer_tree.h"
88
#include "flutter/flow/layers/opacity_layer.h"
9+
#include "flutter/flow/layers/platform_view_layer.h"
910
#include "flutter/flow/raster_cache_item.h"
1011
#include "flutter/flow/testing/layer_test.h"
12+
#include "flutter/flow/testing/mock_embedder.h"
1113
#include "flutter/flow/testing/mock_layer.h"
1214
#include "flutter/fml/macros.h"
1315
#include "flutter/testing/mock_canvas.h"
@@ -533,5 +535,30 @@ TEST_F(ClipPathLayerTest, LayerCached) {
533535
cache_canvas, &paint));
534536
}
535537

538+
TEST_F(ClipPathLayerTest, EmptyClipDoesNotCullPlatformView) {
539+
const SkPoint view_offset = SkPoint::Make(0.0f, 0.0f);
540+
const SkSize view_size = SkSize::Make(8.0f, 8.0f);
541+
const int64_t view_id = 42;
542+
auto platform_view =
543+
std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
544+
545+
auto layer_clip = SkPath().addRect(kEmptyRect);
546+
auto clip =
547+
std::make_shared<ClipPathLayer>(layer_clip, Clip::antiAliasWithSaveLayer);
548+
clip->Add(platform_view);
549+
550+
auto embedder = MockViewEmbedder();
551+
SkCanvas fake_overlay_canvas;
552+
embedder.AddCanvas(&fake_overlay_canvas);
553+
preroll_context()->view_embedder = &embedder;
554+
paint_context().view_embedder = &embedder;
555+
556+
clip->Preroll(preroll_context());
557+
EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
558+
559+
clip->Paint(paint_context());
560+
EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
561+
}
562+
536563
} // namespace testing
537564
} // namespace flutter

flow/layers/clip_rect_layer_unittests.cc

+25
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
#include "flutter/flow/layers/layer_tree.h"
88
#include "flutter/flow/layers/opacity_layer.h"
9+
#include "flutter/flow/layers/platform_view_layer.h"
910
#include "flutter/flow/testing/layer_test.h"
11+
#include "flutter/flow/testing/mock_embedder.h"
1012
#include "flutter/flow/testing/mock_layer.h"
1113
#include "flutter/fml/macros.h"
1214
#include "flutter/testing/mock_canvas.h"
@@ -514,5 +516,28 @@ TEST_F(ClipRectLayerTest, LayerCached) {
514516
cache_canvas, &paint));
515517
}
516518

519+
TEST_F(ClipRectLayerTest, EmptyClipDoesNotCullPlatformView) {
520+
const SkPoint view_offset = SkPoint::Make(0.0f, 0.0f);
521+
const SkSize view_size = SkSize::Make(8.0f, 8.0f);
522+
const int64_t view_id = 42;
523+
auto platform_view =
524+
std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
525+
526+
auto clip = std::make_shared<ClipRectLayer>(kEmptyRect, Clip::hardEdge);
527+
clip->Add(platform_view);
528+
529+
auto embedder = MockViewEmbedder();
530+
SkCanvas fake_overlay_canvas;
531+
embedder.AddCanvas(&fake_overlay_canvas);
532+
preroll_context()->view_embedder = &embedder;
533+
paint_context().view_embedder = &embedder;
534+
535+
clip->Preroll(preroll_context());
536+
EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
537+
538+
clip->Paint(paint_context());
539+
EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
540+
}
541+
517542
} // namespace testing
518543
} // namespace flutter

flow/layers/clip_rrect_layer_unittests.cc

+26
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
#include "flutter/flow/layers/layer_tree.h"
88
#include "flutter/flow/layers/opacity_layer.h"
9+
#include "flutter/flow/layers/platform_view_layer.h"
910
#include "flutter/flow/testing/layer_test.h"
11+
#include "flutter/flow/testing/mock_embedder.h"
1012
#include "flutter/flow/testing/mock_layer.h"
1113
#include "flutter/fml/macros.h"
1214
#include "flutter/testing/mock_canvas.h"
@@ -562,5 +564,29 @@ TEST_F(ClipRRectLayerTest, NoSaveLayerShouldNotCache) {
562564
EXPECT_EQ(clip_cache_item->cache_state(), RasterCacheItem::CacheState::kNone);
563565
}
564566

567+
TEST_F(ClipRRectLayerTest, EmptyClipDoesNotCullPlatformView) {
568+
const SkPoint view_offset = SkPoint::Make(0.0f, 0.0f);
569+
const SkSize view_size = SkSize::Make(8.0f, 8.0f);
570+
const int64_t view_id = 42;
571+
auto platform_view =
572+
std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
573+
574+
SkRRect clip_rrect = SkRRect::MakeRectXY(kEmptyRect, 20, 20);
575+
auto clip = std::make_shared<ClipRRectLayer>(clip_rrect, Clip::antiAlias);
576+
clip->Add(platform_view);
577+
578+
auto embedder = MockViewEmbedder();
579+
SkCanvas fake_overlay_canvas;
580+
embedder.AddCanvas(&fake_overlay_canvas);
581+
preroll_context()->view_embedder = &embedder;
582+
paint_context().view_embedder = &embedder;
583+
584+
clip->Preroll(preroll_context());
585+
EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
586+
587+
clip->Paint(paint_context());
588+
EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
589+
}
590+
565591
} // namespace testing
566592
} // namespace flutter

flow/layers/clip_shape_layer.h

-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ class ClipShapeLayer : public CacheableContainerLayer {
7878

7979
auto mutator = context.state_stack.save();
8080
ApplyClip(mutator);
81-
if (context.state_stack.content_culled(child_paint_bounds())) {
82-
return;
83-
}
8481

8582
if (!UsesSaveLayer()) {
8683
PaintChildren(context);

flow/layers/opacity_layer.cc

+1-3
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ void OpacityLayer::Paint(PaintContext& context) const {
8787
}
8888
}
8989

90-
if (!context.state_stack.painting_is_nop()) {
91-
PaintChildren(context);
92-
}
90+
PaintChildren(context);
9391
}
9492

9593
} // namespace flutter

flow/layers/opacity_layer_unittests.cc

+37-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
#include "flutter/flow/layers/clip_rect_layer.h"
88
#include "flutter/flow/layers/image_filter_layer.h"
99
#include "flutter/flow/layers/layer_tree.h"
10+
#include "flutter/flow/layers/platform_view_layer.h"
1011
#include "flutter/flow/layers/transform_layer.h"
1112
#include "flutter/flow/raster_cache_util.h"
1213
#include "flutter/flow/testing/diff_context_test.h"
1314
#include "flutter/flow/testing/layer_test.h"
15+
#include "flutter/flow/testing/mock_embedder.h"
1416
#include "flutter/flow/testing/mock_layer.h"
1517
#include "flutter/fml/macros.h"
1618
#include "flutter/testing/display_list_testing.h"
@@ -274,11 +276,16 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
274276
mock_layer->parent_mutators(),
275277
std::vector({Mutator(layer_transform), Mutator(SK_AlphaTRANSPARENT)}));
276278

277-
auto expected_draw_calls =
278-
std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
279-
MockCanvas::DrawCall{
280-
1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}},
281-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
279+
auto expected_draw_calls = std::vector(
280+
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
281+
MockCanvas::DrawCall{
282+
1, MockCanvas::ConcatMatrixData{SkM44(layer_transform)}},
283+
MockCanvas::DrawCall{1, MockCanvas::SaveData{2}},
284+
MockCanvas::DrawCall{
285+
2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect,
286+
MockCanvas::kHard_ClipEdgeStyle}},
287+
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
288+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
282289
layer->Paint(paint_context());
283290
EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
284291
}
@@ -686,5 +693,30 @@ TEST_F(OpacityLayerTest, FullyOpaqueWithFractionalValues) {
686693
EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
687694
}
688695

696+
TEST_F(OpacityLayerTest, FullyTransparentDoesNotCullPlatformView) {
697+
const SkPoint opacity_offset = SkPoint::Make(0.5f, 1.5f);
698+
const SkPoint view_offset = SkPoint::Make(0.0f, 0.0f);
699+
const SkSize view_size = SkSize::Make(8.0f, 8.0f);
700+
const int64_t view_id = 42;
701+
auto platform_view =
702+
std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
703+
704+
auto opacity =
705+
std::make_shared<OpacityLayer>(SK_AlphaTRANSPARENT, opacity_offset);
706+
opacity->Add(platform_view);
707+
708+
auto embedder = MockViewEmbedder();
709+
SkCanvas fake_overlay_canvas;
710+
embedder.AddCanvas(&fake_overlay_canvas);
711+
preroll_context()->view_embedder = &embedder;
712+
paint_context().view_embedder = &embedder;
713+
714+
opacity->Preroll(preroll_context());
715+
EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
716+
717+
opacity->Paint(paint_context());
718+
EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
719+
}
720+
689721
} // namespace testing
690722
} // namespace flutter

flow/layers/platform_view_layer_unittests.cc

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ TEST_F(PlatformViewLayerTest, ClippedPlatformViewPrerollsAndPaintsNothing) {
7676
MockCanvas::DrawCall{
7777
1, MockCanvas::ClipRectData{parent_clip, SkClipOp::kIntersect,
7878
MockCanvas::kHard_ClipEdgeStyle}},
79+
MockCanvas::DrawCall{1, MockCanvas::SaveData{2}},
80+
MockCanvas::DrawCall{
81+
2, MockCanvas::ClipRectData{child_clip, SkClipOp::kIntersect,
82+
MockCanvas::kHard_ClipEdgeStyle}},
83+
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
7984
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
8085
}
8186

flow/testing/mock_embedder.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ void MockViewEmbedder::BeginFrame(
3838
// |ExternalViewEmbedder|
3939
void MockViewEmbedder::PrerollCompositeEmbeddedView(
4040
int view_id,
41-
std::unique_ptr<EmbeddedViewParams> params) {}
41+
std::unique_ptr<EmbeddedViewParams> params) {
42+
prerolled_views_.emplace_back(view_id);
43+
}
4244

4345
// |ExternalViewEmbedder|
4446
std::vector<SkCanvas*> MockViewEmbedder::GetCurrentCanvases() {
@@ -52,6 +54,7 @@ std::vector<DisplayListBuilder*> MockViewEmbedder::GetCurrentBuilders() {
5254

5355
// |ExternalViewEmbedder|
5456
EmbedderPaintContext MockViewEmbedder::CompositeEmbeddedView(int view_id) {
57+
painted_views_.emplace_back(view_id);
5558
EmbedderPaintContext context = contexts_.front();
5659
contexts_.pop_front();
5760
return context;

flow/testing/mock_embedder.h

+5
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@ class MockViewEmbedder : public ExternalViewEmbedder {
4646
// |ExternalViewEmbedder|
4747
EmbedderPaintContext CompositeEmbeddedView(int view_id) override;
4848

49+
std::vector<int64_t> prerolled_views() const { return prerolled_views_; }
50+
std::vector<int64_t> painted_views() const { return painted_views_; }
51+
4952
private:
5053
std::deque<EmbedderPaintContext> contexts_;
54+
std::vector<int64_t> prerolled_views_;
55+
std::vector<int64_t> painted_views_;
5156
};
5257

5358
} // namespace testing

0 commit comments

Comments
 (0)