Enable RasterCache for clipper layers using saveLayer (flutter/engine#32899)

This commit is contained in:
wangying 2022-05-17 09:22:04 +08:00 committed by GitHub
parent 81d2c04680
commit e09bcd7eba
4 changed files with 129 additions and 10 deletions

View File

@ -498,5 +498,42 @@ TEST_F(ClipPathLayerTest, OpacityInheritanceSaveLayerPainting) {
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
}
TEST_F(ClipPathLayerTest, LayerCached) {
auto path1 = SkPath().addRect({10, 10, 30, 30});
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
auto layer_clip = SkPath()
.addRect(SkRect::MakeLTRB(5, 5, 25, 25))
.addOval(SkRect::MakeLTRB(20, 20, 40, 50));
auto layer =
std::make_shared<ClipPathLayer>(layer_clip, Clip::antiAliasWithSaveLayer);
layer->Add(mock1);
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
SkMatrix cache_ctm = initial_transform;
SkCanvas cache_canvas;
cache_canvas.setMatrix(cache_ctm);
use_mock_raster_cache();
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
}
} // namespace testing
} // namespace flutter

View File

@ -488,5 +488,40 @@ TEST_F(ClipRectLayerTest, OpacityInheritanceSaveLayerPainting) {
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
}
TEST_F(ClipRectLayerTest, LayerCached) {
auto path1 = SkPath().addRect({10, 10, 30, 30});
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
SkRect clip_rect = SkRect::MakeWH(500, 500);
auto layer =
std::make_shared<ClipRectLayer>(clip_rect, Clip::antiAliasWithSaveLayer);
layer->Add(mock1);
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
SkMatrix cache_ctm = initial_transform;
SkCanvas cache_canvas;
cache_canvas.setMatrix(cache_ctm);
use_mock_raster_cache();
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
}
} // namespace testing
} // namespace flutter

View File

@ -498,5 +498,41 @@ TEST_F(ClipRRectLayerTest, OpacityInheritanceSaveLayerPainting) {
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
}
TEST_F(ClipRRectLayerTest, LayerCached) {
auto path1 = SkPath().addRect({10, 10, 30, 30});
auto mock1 = MockLayer::MakeOpacityCompatible(path1);
SkRect clip_rect = SkRect::MakeWH(500, 500);
SkRRect clip_r_rect = SkRRect::MakeRectXY(clip_rect, 20, 20);
auto layer = std::make_shared<ClipRRectLayer>(clip_r_rect,
Clip::antiAliasWithSaveLayer);
layer->Add(mock1);
auto initial_transform = SkMatrix::Translate(50.0, 25.5);
SkMatrix cache_ctm = initial_transform;
SkCanvas cache_canvas;
cache_canvas.setMatrix(cache_ctm);
use_mock_raster_cache();
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
EXPECT_FALSE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
EXPECT_TRUE(raster_cache()->Draw(layer.get(), cache_canvas,
RasterCacheLayerStrategy::kLayer));
}
} // namespace testing
} // namespace flutter

View File

@ -15,7 +15,9 @@ class ClipShapeLayer : public ContainerLayer {
public:
using ClipShape = T;
ClipShapeLayer(const ClipShape& clip_shape, Clip clip_behavior)
: clip_shape_(clip_shape), clip_behavior_(clip_behavior) {
: clip_shape_(clip_shape),
clip_behavior_(clip_behavior),
render_count_(1) {
FML_DCHECK(clip_behavior != Clip::none);
}
@ -58,6 +60,12 @@ class ClipShapeLayer : public ContainerLayer {
// of our children and apply it in the saveLayer.
if (UsesSaveLayer()) {
context->subtree_can_inherit_opacity = true;
if (render_count_ >= kMinimumRendersBeforeCachingLayer) {
TryToPrepareRasterCache(context, this, matrix,
RasterCacheLayerStrategy::kLayer);
} else {
render_count_++;
}
}
context->mutators_stack.Pop();
@ -76,16 +84,16 @@ class ClipShapeLayer : public ContainerLayer {
}
AutoCachePaint cache_paint(context);
TRACE_EVENT0("flutter", "Canvas::saveLayer");
context.internal_nodes_canvas->saveLayer(paint_bounds(),
cache_paint.paint());
PaintChildren(context);
context.internal_nodes_canvas->restore();
if (context.checkerboard_offscreen_layers) {
DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
if (context.raster_cache &&
context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
RasterCacheLayerStrategy::kLayer,
cache_paint.paint())) {
return;
}
Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create(
context, paint_bounds(), cache_paint.paint());
PaintChildren(context);
}
bool UsesSaveLayer() const {
@ -105,6 +113,9 @@ class ClipShapeLayer : public ContainerLayer {
const ClipShape clip_shape_;
Clip clip_behavior_;
static constexpr int kMinimumRendersBeforeCachingLayer = 3;
int render_count_;
FML_DISALLOW_COPY_AND_ASSIGN(ClipShapeLayer);
};