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

Commit edd0b81

Browse files
authored
Enable RasterCache for clipper layers using saveLayer (#32899)
1 parent 70c94f1 commit edd0b81

File tree

4 files changed

+128
-9
lines changed

4 files changed

+128
-9
lines changed

flow/layers/clip_path_layer_unittests.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,5 +498,42 @@ TEST_F(ClipPathLayerTest, OpacityInheritanceSaveLayerPainting) {
498498
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
499499
}
500500

501+
TEST_F(ClipPathLayerTest, LayerCached) {
502+
auto path1 = SkPath().addRect({10, 10, 30, 30});
503+
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
504+
auto layer_clip = SkPath()
505+
.addRect(SkRect::MakeLTRB(5, 5, 25, 25))
506+
.addOval(SkRect::MakeLTRB(20, 20, 40, 50));
507+
auto layer =
508+
std::make_shared<ClipPathLayer>(layer_clip, Clip::antiAliasWithSaveLayer);
509+
layer->Add(mock1);
510+
511+
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
512+
SkMatrix cache_ctm = initial_transform;
513+
SkCanvas cache_canvas;
514+
cache_canvas.setMatrix(cache_ctm);
515+
516+
use_mock_raster_cache();
517+
518+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
519+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
520+
RasterCacheLayerStrategy::kLayer));
521+
522+
layer->Preroll(preroll_context(), initial_transform);
523+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
524+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
525+
RasterCacheLayerStrategy::kLayer));
526+
527+
layer->Preroll(preroll_context(), initial_transform);
528+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
529+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
530+
RasterCacheLayerStrategy::kLayer));
531+
532+
layer->Preroll(preroll_context(), initial_transform);
533+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
534+
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
535+
RasterCacheLayerStrategy::kLayer));
536+
}
537+
501538
} // namespace testing
502539
} // namespace flutter

flow/layers/clip_rect_layer_unittests.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,5 +488,40 @@ TEST_F(ClipRectLayerTest, OpacityInheritanceSaveLayerPainting) {
488488
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
489489
}
490490

491+
TEST_F(ClipRectLayerTest, LayerCached) {
492+
auto path1 = SkPath().addRect({10, 10, 30, 30});
493+
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
494+
SkRect clip_rect = SkRect::MakeWH(500, 500);
495+
auto layer =
496+
std::make_shared<ClipRectLayer>(clip_rect, Clip::antiAliasWithSaveLayer);
497+
layer->Add(mock1);
498+
499+
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
500+
SkMatrix cache_ctm = initial_transform;
501+
SkCanvas cache_canvas;
502+
cache_canvas.setMatrix(cache_ctm);
503+
504+
use_mock_raster_cache();
505+
506+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
507+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
508+
RasterCacheLayerStrategy::kLayer));
509+
510+
layer->Preroll(preroll_context(), initial_transform);
511+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
512+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
513+
RasterCacheLayerStrategy::kLayer));
514+
515+
layer->Preroll(preroll_context(), initial_transform);
516+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
517+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
518+
RasterCacheLayerStrategy::kLayer));
519+
520+
layer->Preroll(preroll_context(), initial_transform);
521+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
522+
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
523+
RasterCacheLayerStrategy::kLayer));
524+
}
525+
491526
} // namespace testing
492527
} // namespace flutter

flow/layers/clip_rrect_layer_unittests.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,5 +498,41 @@ TEST_F(ClipRRectLayerTest, OpacityInheritanceSaveLayerPainting) {
498498
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
499499
}
500500

501+
TEST_F(ClipRRectLayerTest, LayerCached) {
502+
auto path1 = SkPath().addRect({10, 10, 30, 30});
503+
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
504+
SkRect clip_rect = SkRect::MakeWH(500, 500);
505+
SkRRect clip_r_rect = SkRRect::MakeRectXY(clip_rect, 20, 20);
506+
auto layer = std::make_shared<ClipRRectLayer>(clip_r_rect,
507+
Clip::antiAliasWithSaveLayer);
508+
layer->Add(mock1);
509+
510+
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
511+
SkMatrix cache_ctm = initial_transform;
512+
SkCanvas cache_canvas;
513+
cache_canvas.setMatrix(cache_ctm);
514+
515+
use_mock_raster_cache();
516+
517+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
518+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
519+
RasterCacheLayerStrategy::kLayer));
520+
521+
layer->Preroll(preroll_context(), initial_transform);
522+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
523+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
524+
RasterCacheLayerStrategy::kLayer));
525+
526+
layer->Preroll(preroll_context(), initial_transform);
527+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
528+
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
529+
RasterCacheLayerStrategy::kLayer));
530+
531+
layer->Preroll(preroll_context(), initial_transform);
532+
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
533+
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
534+
RasterCacheLayerStrategy::kLayer));
535+
}
536+
501537
} // namespace testing
502538
} // namespace flutter

flow/layers/clip_shape_layer.h

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ class ClipShapeLayer : public ContainerLayer {
1515
public:
1616
using ClipShape = T;
1717
ClipShapeLayer(const ClipShape& clip_shape, Clip clip_behavior)
18-
: clip_shape_(clip_shape), clip_behavior_(clip_behavior) {
18+
: clip_shape_(clip_shape),
19+
clip_behavior_(clip_behavior),
20+
render_count_(1) {
1921
FML_DCHECK(clip_behavior != Clip::none);
2022
}
2123

@@ -58,6 +60,12 @@ class ClipShapeLayer : public ContainerLayer {
5860
// of our children and apply it in the saveLayer.
5961
if (UsesSaveLayer()) {
6062
context->subtree_can_inherit_opacity = true;
63+
if (render_count_ >= kMinimumRendersBeforeCachingLayer) {
64+
TryToPrepareRasterCache(context, this, matrix,
65+
RasterCacheLayerStrategy::kLayer);
66+
} else {
67+
render_count_++;
68+
}
6169
}
6270

6371
context->mutators_stack.Pop();
@@ -76,16 +84,16 @@ class ClipShapeLayer : public ContainerLayer {
7684
}
7785

7886
AutoCachePaint cache_paint(context);
79-
TRACE_EVENT0("flutter", "Canvas::saveLayer");
80-
context.internal_nodes_canvas->saveLayer(paint_bounds(),
81-
cache_paint.paint());
87+
if (context.raster_cache &&
88+
context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
89+
RasterCacheLayerStrategy::kLayer,
90+
cache_paint.paint())) {
91+
return;
92+
}
8293

94+
Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create(
95+
context, paint_bounds(), cache_paint.paint());
8396
PaintChildren(context);
84-
85-
context.internal_nodes_canvas->restore();
86-
if (context.checkerboard_offscreen_layers) {
87-
DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
88-
}
8997
}
9098

9199
bool UsesSaveLayer() const {
@@ -105,6 +113,9 @@ class ClipShapeLayer : public ContainerLayer {
105113
const ClipShape clip_shape_;
106114
Clip clip_behavior_;
107115

116+
static constexpr int kMinimumRendersBeforeCachingLayer = 3;
117+
int render_count_;
118+
108119
FML_DISALLOW_COPY_AND_ASSIGN(ClipShapeLayer);
109120
};
110121

0 commit comments

Comments
 (0)