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

Commit e95b027

Browse files
committed
Reuse existing RTree from DisplayListLayer
1 parent 0e15b47 commit e95b027

File tree

5 files changed

+80
-73
lines changed

5 files changed

+80
-73
lines changed

flow/layers/display_list_layer_unittests.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,56 @@ TEST_F(DisplayListLayerTest, CachedIncompatibleDisplayListOpacityInheritance) {
294294
EXPECT_TRUE(DisplayListsEQ_Verbose(expected.Build(), this->display_list()));
295295
}
296296

297+
TEST_F(DisplayListLayerTest, RasterCachePreservesRTree) {
298+
const SkRect picture1_bounds = SkRect::MakeXYWH(10, 10, 10, 10);
299+
const SkRect picture2_bounds = SkRect::MakeXYWH(15, 15, 10, 10);
300+
DisplayListBuilder builder(true);
301+
builder.DrawRect(picture1_bounds, DlPaint());
302+
builder.DrawRect(picture2_bounds, DlPaint());
303+
auto display_list = builder.Build();
304+
auto display_list_layer = std::make_shared<DisplayListLayer>(
305+
SkPoint::Make(3, 3), display_list, true, false);
306+
307+
use_skia_raster_cache();
308+
309+
auto context = preroll_context();
310+
display_list_layer->Preroll(preroll_context());
311+
EXPECT_EQ(context->renderable_state_flags, 0);
312+
313+
// Pump the DisplayListLayer until it is ready to cache its DL
314+
display_list_layer->Preroll(preroll_context());
315+
display_list_layer->Preroll(preroll_context());
316+
display_list_layer->Preroll(preroll_context());
317+
LayerTree::TryToRasterCache(*preroll_context()->raster_cached_entries,
318+
&paint_context(), false);
319+
320+
DisplayListBuilder expected_root_canvas(true);
321+
context->raster_cache->Draw(display_list_layer->caching_key_id(),
322+
expected_root_canvas, nullptr, true);
323+
auto root_canvas_dl = expected_root_canvas.Build();
324+
const auto root_canvas_rects =
325+
root_canvas_dl->rtree()->searchAndConsolidateRects(kGiantRect, true);
326+
std::list<SkRect> root_canvas_rects_expected = {
327+
SkRect::MakeLTRB(13, 13, 28, 28),
328+
};
329+
EXPECT_EQ(root_canvas_rects_expected, root_canvas_rects);
330+
331+
DisplayListBuilder expected_overlay_canvas(true);
332+
context->raster_cache->Draw(display_list_layer->caching_key_id(),
333+
expected_overlay_canvas, nullptr, false);
334+
auto overlay_canvas_dl = expected_overlay_canvas.Build();
335+
const auto overlay_canvas_rects =
336+
overlay_canvas_dl->rtree()->searchAndConsolidateRects(kGiantRect, true);
337+
338+
// Same bounds as root canvas, but preserves individual rects.
339+
std::list<SkRect> overlay_canvas_rects_expected = {
340+
SkRect::MakeLTRB(13, 13, 23, 18),
341+
SkRect::MakeLTRB(13, 18, 28, 23),
342+
SkRect::MakeLTRB(18, 23, 28, 28),
343+
};
344+
EXPECT_EQ(overlay_canvas_rects_expected, overlay_canvas_rects);
345+
};
346+
297347
using DisplayListLayerDiffTest = DiffContextTest;
298348

299349
TEST_F(DisplayListLayerDiffTest, SimpleDisplayList) {

flow/layers/display_list_raster_cache_item.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ bool DisplayListRasterCacheItem::TryToPrepareRasterCache(
167167
// clang-format on
168168
};
169169
return context.raster_cache->UpdateCacheEntry(
170-
id.value(), r_context, [display_list = display_list_](DlCanvas* canvas) {
170+
id.value(), r_context,
171+
[display_list = display_list_](DlCanvas* canvas) {
171172
canvas->DrawDisplayList(display_list);
172-
});
173+
},
174+
display_list_->rtree());
173175
}
174176
} // namespace flutter

flow/raster_cache.cc

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,18 @@ void RasterCacheResult::draw(DlCanvas& canvas,
5454
// platform views and hit testing. To preserve the RTree raster cache must
5555
// paint individual rects instead of the whole image.
5656
auto rects = rtree_->searchAndConsolidateRects(kGiantRect);
57+
58+
// Bounds of original display list.
59+
SkRect rtree_bounds = SkRect::MakeEmpty();
60+
for (auto rect : rects) {
61+
rtree_bounds.join(rect);
62+
}
5763
for (auto rect : rects) {
58-
SkRect dst(rect);
64+
SkRect src(rect);
65+
src.offset(-rtree_bounds.fLeft, -rtree_bounds.fTop);
66+
SkRect dst(src);
5967
dst.offset(bounds.fLeft, bounds.fTop);
60-
canvas.DrawImageRect(image_, rect, dst, DlImageSampling::kNearestNeighbor,
68+
canvas.DrawImageRect(image_, src, dst, DlImageSampling::kNearestNeighbor,
6169
paint);
6270
}
6371
}
@@ -72,6 +80,7 @@ RasterCache::RasterCache(size_t access_threshold,
7280
/// @note Procedure doesn't copy all closures.
7381
std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
7482
const RasterCache::Context& context,
83+
sk_sp<const DlRTree> rtree,
7584
const std::function<void(DlCanvas*)>& draw_function,
7685
const std::function<void(DlCanvas*, const SkRect& rect)>& draw_checkerboard)
7786
const {
@@ -93,12 +102,9 @@ std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
93102
return nullptr;
94103
}
95104

96-
// Clear the surface canvas directly to avoid RTree storing a giant clear
97-
// rect.
98-
auto surfaceCanvas = surface->getCanvas();
99-
surfaceCanvas->clear(SK_ColorTRANSPARENT);
105+
DlSkCanvasAdapter canvas(surface->getCanvas());
106+
canvas.Clear(DlColor::kTransparent());
100107

101-
DisplayListBuilder canvas(true);
102108
canvas.Translate(-dest_rect.left(), -dest_rect.top());
103109
canvas.Transform(matrix);
104110
draw_function(&canvas);
@@ -107,24 +113,22 @@ std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
107113
draw_checkerboard(&canvas, context.logical_rect);
108114
}
109115

110-
auto display_list = canvas.Build();
111-
DlSkCanvasDispatcher dispatcher(surfaceCanvas);
112-
display_list->Dispatch(dispatcher);
113-
auto rtree = display_list->rtree();
114116
auto image = DlImage::Make(surface->makeImageSnapshot());
115-
return std::make_unique<RasterCacheResult>(image, context.logical_rect,
116-
context.flow_type, rtree);
117+
return std::make_unique<RasterCacheResult>(
118+
image, context.logical_rect, context.flow_type, std::move(rtree));
117119
}
118120

119121
bool RasterCache::UpdateCacheEntry(
120122
const RasterCacheKeyID& id,
121123
const Context& raster_cache_context,
122-
const std::function<void(DlCanvas*)>& render_function) const {
124+
const std::function<void(DlCanvas*)>& render_function,
125+
sk_sp<const DlRTree> rtree) const {
123126
RasterCacheKey key = RasterCacheKey(id, raster_cache_context.matrix);
124127
Entry& entry = cache_[key];
125128
if (!entry.image) {
126129
void (*func)(DlCanvas*, const SkRect& rect) = DrawCheckerboard;
127-
entry.image = Rasterize(raster_cache_context, render_function, func);
130+
entry.image = Rasterize(raster_cache_context, std::move(rtree),
131+
render_function, func);
128132
if (entry.image != nullptr) {
129133
switch (id.type()) {
130134
case RasterCacheKeyType::kDisplayList: {

flow/raster_cache.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class RasterCache {
131131

132132
std::unique_ptr<RasterCacheResult> Rasterize(
133133
const RasterCache::Context& context,
134+
sk_sp<const DlRTree> rtree,
134135
const std::function<void(DlCanvas*)>& draw_function,
135136
const std::function<void(DlCanvas*, const SkRect& rect)>&
136137
draw_checkerboard) const;
@@ -241,10 +242,10 @@ class RasterCache {
241242
*/
242243
int GetAccessCount(const RasterCacheKeyID& id, const SkMatrix& matrix) const;
243244

244-
bool UpdateCacheEntry(
245-
const RasterCacheKeyID& id,
246-
const Context& raster_cache_context,
247-
const std::function<void(DlCanvas*)>& render_function) const;
245+
bool UpdateCacheEntry(const RasterCacheKeyID& id,
246+
const Context& raster_cache_context,
247+
const std::function<void(DlCanvas*)>& render_function,
248+
sk_sp<const DlRTree> rtree = nullptr) const;
248249

249250
private:
250251
struct Entry {

flow/raster_cache_unittests.cc

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@ TEST(RasterCache, SetCheckboardCacheImages) {
178178
};
179179

180180
cache.SetCheckboardCacheImages(false);
181-
cache.Rasterize(r_context, dummy_draw_function, draw_checkerboard);
181+
cache.Rasterize(r_context, nullptr, dummy_draw_function, draw_checkerboard);
182182
ASSERT_FALSE(did_draw_checkerboard);
183183

184184
cache.SetCheckboardCacheImages(true);
185-
cache.Rasterize(r_context, dummy_draw_function, draw_checkerboard);
185+
cache.Rasterize(r_context, nullptr, dummy_draw_function, draw_checkerboard);
186186
ASSERT_TRUE(did_draw_checkerboard);
187187
}
188188

@@ -886,56 +886,6 @@ TEST_F(RasterCacheTest, RasterCacheKeyIDLayerChildrenIds) {
886886
ASSERT_EQ(ids, expected_ids);
887887
}
888888

889-
TEST(RasterCache, PreservesRTree) {
890-
flutter::RasterCache cache(1);
891-
LayerStateStack preroll_state_stack;
892-
SkMatrix matrix = SkMatrix::I();
893-
preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
894-
895-
FixedRefreshRateStopwatch raster_time;
896-
FixedRefreshRateStopwatch ui_time;
897-
PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
898-
preroll_state_stack, &cache, &raster_time, &ui_time);
899-
auto& paint_context = paint_context_holder.paint_context;
900-
RasterCache::Context r_context = {
901-
// clang-format off
902-
.gr_context = paint_context.gr_context,
903-
.dst_color_space = paint_context.dst_color_space,
904-
.matrix = matrix,
905-
.logical_rect = SkRect::MakeWH(100, 100),
906-
.flow_type = "RasterCacheFlow::DisplayList",
907-
// clang-format on
908-
};
909-
910-
RasterCacheKeyID id(10, RasterCacheKeyType::kLayer);
911-
cache.UpdateCacheEntry(id, r_context, [&](DlCanvas* canvas) {
912-
canvas->DrawRect(SkRect::MakeXYWH(0, 0, 100, 10), DlPaint());
913-
canvas->DrawRect(SkRect::MakeXYWH(0, 40, 100, 10), DlPaint());
914-
});
915-
916-
{
917-
DisplayListBuilder canvas(true);
918-
cache.Draw(id, canvas, nullptr, true);
919-
auto display_list = canvas.Build();
920-
auto rtree = display_list->rtree();
921-
auto rects = rtree->searchAndConsolidateRects(kGiantRect);
922-
// For root canvas the display may clober the RTree.
923-
ASSERT_EQ(rects.size(), 1u);
924-
ASSERT_EQ(rects.front(), SkRect::MakeWH(100, 100));
925-
}
926-
{
927-
DisplayListBuilder canvas(true);
928-
cache.Draw(id, canvas, nullptr, false);
929-
auto display_list = canvas.Build();
930-
auto rtree = display_list->rtree();
931-
auto rects = rtree->searchAndConsolidateRects(kGiantRect);
932-
// For non-root canvas the RTree must be preserved
933-
ASSERT_EQ(rects.size(), 2u);
934-
ASSERT_EQ(rects.front(), SkRect::MakeXYWH(0, 0, 100, 10));
935-
ASSERT_EQ(*std::next(rects.begin(), 1), SkRect::MakeXYWH(0, 40, 100, 10));
936-
}
937-
}
938-
939889
} // namespace testing
940890
} // namespace flutter
941891

0 commit comments

Comments
 (0)