mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Enable RasterCache for clipper layers using saveLayer (flutter/engine#32899)
This commit is contained in:
parent
81d2c04680
commit
e09bcd7eba
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user