Skip to content

Commit 780a1eb

Browse files
Evicting unused cache entries before RasterCache actions (flutter#34627)
1 parent cb137c5 commit 780a1eb

9 files changed

+244
-191
lines changed

flow/frame_timings_recorder_unittests.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ TEST(FrameTimingsRecorderTest, RecordRasterTimesWithCache) {
9191
using namespace std::chrono_literals;
9292

9393
MockRasterCache cache(1, 10);
94-
cache.PrepareNewFrame();
94+
cache.BeginFrame();
9595

9696
const auto raster_start = fml::TimePoint::Now();
9797
recorder->RecordRasterStart(raster_start);
@@ -102,8 +102,9 @@ TEST(FrameTimingsRecorderTest, RecordRasterTimesWithCache) {
102102
cache.AddMockPicture(100, 100);
103103
size_t picture_bytes = cache.EstimatePictureCacheByteSize();
104104
EXPECT_GT(picture_bytes, 0u);
105+
cache.EvictUnusedCacheEntries();
105106

106-
cache.CleanupAfterFrame();
107+
cache.EndFrame();
107108

108109
const auto before_raster_end_wall_time = fml::TimePoint::CurrentWallTime();
109110
std::this_thread::sleep_for(1ms);
@@ -252,7 +253,7 @@ TEST(FrameTimingsRecorderTest, ClonedHasSameRasterEnd) {
252253
TEST(FrameTimingsRecorderTest, ClonedHasSameRasterEndWithCache) {
253254
auto recorder = std::make_unique<FrameTimingsRecorder>();
254255
MockRasterCache cache(1, 10);
255-
cache.PrepareNewFrame();
256+
cache.BeginFrame();
256257

257258
const auto now = fml::TimePoint::Now();
258259
recorder->RecordVsync(now, now + fml::TimeDelta::FromMilliseconds(16));
@@ -266,8 +267,8 @@ TEST(FrameTimingsRecorderTest, ClonedHasSameRasterEndWithCache) {
266267
cache.AddMockPicture(100, 100);
267268
size_t picture_bytes = cache.EstimatePictureCacheByteSize();
268269
EXPECT_GT(picture_bytes, 0u);
269-
270-
cache.CleanupAfterFrame();
270+
cache.EvictUnusedCacheEntries();
271+
cache.EndFrame();
271272
recorder->RecordRasterEnd(&cache);
272273

273274
auto cloned = recorder->CloneUntil(FrameTimingsRecorder::State::kRasterEnd);

flow/layers/container_layer_unittests.cc

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,9 @@ TEST_F(ContainerLayerTest, RasterCacheTest) {
268268
{
269269
// frame1
270270
use_mock_raster_cache();
271-
preroll_context()->raster_cache->PrepareNewFrame();
271+
preroll_context()->raster_cache->BeginFrame();
272272
layer->Preroll(preroll_context(), SkMatrix::I());
273+
preroll_context()->raster_cache->EvictUnusedCacheEntries();
273274
// Cache the cacheable entries
274275
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
275276
&paint_context());
@@ -299,16 +300,17 @@ TEST_F(ContainerLayerTest, RasterCacheTest) {
299300
// render count < 2 don't cache it
300301
EXPECT_EQ(cacheable_container_layer2->raster_cache_item()->cache_state(),
301302
RasterCacheItem::CacheState::kNone);
302-
preroll_context()->raster_cache->CleanupAfterFrame();
303+
preroll_context()->raster_cache->EndFrame();
303304
}
304305

305306
{
306307
// frame2
307308
// new frame the layer tree will create new PrerollContext, so in here we
308309
// clear the cached_entries
309310
preroll_context()->raster_cached_entries->clear();
310-
preroll_context()->raster_cache->PrepareNewFrame();
311+
preroll_context()->raster_cache->BeginFrame();
311312
layer->Preroll(preroll_context(), SkMatrix::I());
313+
preroll_context()->raster_cache->EvictUnusedCacheEntries();
312314

313315
// Cache the cacheable entries
314316
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
@@ -342,17 +344,17 @@ TEST_F(ContainerLayerTest, RasterCacheTest) {
342344
EXPECT_TRUE(raster_cache()->Draw(
343345
cacheable_layer21->raster_cache_item()->GetId().value(), cache_canvas,
344346
&paint));
345-
preroll_context()->raster_cache->CleanupAfterFrame();
347+
preroll_context()->raster_cache->EndFrame();
346348
}
347349

348350
{
349351
// frame3
350352
// new frame the layer tree will create new PrerollContext, so in here we
351353
// clear the cached_entries
352-
preroll_context()->raster_cache->PrepareNewFrame();
354+
preroll_context()->raster_cache->BeginFrame();
353355
preroll_context()->raster_cached_entries->clear();
354356
layer->Preroll(preroll_context(), SkMatrix::I());
355-
357+
preroll_context()->raster_cache->EvictUnusedCacheEntries();
356358
// Cache the cacheable entries
357359
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
358360
&paint_context());
@@ -385,33 +387,34 @@ TEST_F(ContainerLayerTest, RasterCacheTest) {
385387
EXPECT_TRUE(raster_cache()->HasEntry(
386388
cacheable_layer21->raster_cache_item()->GetId().value(),
387389
SkMatrix::I()));
388-
preroll_context()->raster_cache->CleanupAfterFrame();
390+
preroll_context()->raster_cache->EndFrame();
389391
}
390392

391393
{
392-
preroll_context()->raster_cache->PrepareNewFrame();
394+
preroll_context()->raster_cache->BeginFrame();
393395
// frame4
394396
preroll_context()->raster_cached_entries->clear();
395397
layer->Preroll(preroll_context(), SkMatrix::I());
398+
preroll_context()->raster_cache->EvictUnusedCacheEntries();
396399
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
397400
&paint_context());
398-
preroll_context()->raster_cache->CleanupAfterFrame();
401+
preroll_context()->raster_cache->EndFrame();
399402

400403
// frame5
401-
preroll_context()->raster_cache->PrepareNewFrame();
404+
preroll_context()->raster_cache->BeginFrame();
402405
preroll_context()->raster_cached_entries->clear();
403406
layer->Preroll(preroll_context(), SkMatrix::I());
404407
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
405408
&paint_context());
406-
preroll_context()->raster_cache->CleanupAfterFrame();
409+
preroll_context()->raster_cache->EndFrame();
407410

408411
// frame6
409-
preroll_context()->raster_cache->PrepareNewFrame();
412+
preroll_context()->raster_cache->BeginFrame();
410413
preroll_context()->raster_cached_entries->clear();
411414
layer->Preroll(preroll_context(), SkMatrix::I());
412415
LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
413416
&paint_context());
414-
preroll_context()->raster_cache->CleanupAfterFrame();
417+
preroll_context()->raster_cache->EndFrame();
415418
}
416419
}
417420

flow/layers/layer_tree.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
150150
};
151151

152152
if (cache) {
153+
cache->EvictUnusedCacheEntries();
153154
TryToRasterCache(raster_cache_items_, &context, ignore_raster_cache);
154155
}
155156

flow/raster_cache.cc

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -171,58 +171,47 @@ bool RasterCache::Draw(const RasterCacheKeyID& id,
171171
return false;
172172
}
173173

174-
void RasterCache::PrepareNewFrame() {
174+
void RasterCache::BeginFrame() {
175175
display_list_cached_this_frame_ = 0;
176+
picture_metrics_ = {};
177+
layer_metrics_ = {};
176178
}
177179

178-
void RasterCache::SweepOneCacheAfterFrame(RasterCacheKey::Map<Entry>& cache,
179-
RasterCacheMetrics& picture_metrics,
180-
RasterCacheMetrics& layer_metrics) {
180+
void RasterCache::UpdateMetrics() {
181+
for (auto it = cache_.begin(); it != cache_.end(); ++it) {
182+
Entry& entry = it->second;
183+
FML_DCHECK(entry.encountered_this_frame);
184+
if (entry.image) {
185+
RasterCacheMetrics& metrics = GetMetricsForKind(it->first.kind());
186+
metrics.in_use_count++;
187+
metrics.in_use_bytes += entry.image->image_bytes();
188+
}
189+
entry.encountered_this_frame = false;
190+
}
191+
}
192+
193+
void RasterCache::EvictUnusedCacheEntries() {
181194
std::vector<RasterCacheKey::Map<Entry>::iterator> dead;
182195

183-
for (auto it = cache.begin(); it != cache.end(); ++it) {
196+
for (auto it = cache_.begin(); it != cache_.end(); ++it) {
184197
Entry& entry = it->second;
185-
186198
if (!entry.encountered_this_frame) {
187199
dead.push_back(it);
188-
} else if (entry.image) {
189-
RasterCacheKeyKind kind = it->first.kind();
190-
switch (kind) {
191-
case RasterCacheKeyKind::kDisplayListMetrics:
192-
picture_metrics.in_use_count++;
193-
picture_metrics.in_use_bytes += entry.image->image_bytes();
194-
break;
195-
case RasterCacheKeyKind::kLayerMetrics:
196-
layer_metrics.in_use_count++;
197-
layer_metrics.in_use_bytes += entry.image->image_bytes();
198-
break;
199-
}
200200
}
201-
entry.encountered_this_frame = false;
202201
}
203202

204203
for (auto it : dead) {
205204
if (it->second.image) {
206-
RasterCacheKeyKind kind = it->first.kind();
207-
switch (kind) {
208-
case RasterCacheKeyKind::kDisplayListMetrics:
209-
picture_metrics.eviction_count++;
210-
picture_metrics.eviction_bytes += it->second.image->image_bytes();
211-
break;
212-
case RasterCacheKeyKind::kLayerMetrics:
213-
layer_metrics.eviction_count++;
214-
layer_metrics.eviction_bytes += it->second.image->image_bytes();
215-
break;
216-
}
205+
RasterCacheMetrics& metrics = GetMetricsForKind(it->first.kind());
206+
metrics.eviction_count++;
207+
metrics.eviction_bytes += it->second.image->image_bytes();
217208
}
218-
cache.erase(it);
209+
cache_.erase(it);
219210
}
220211
}
221212

222-
void RasterCache::CleanupAfterFrame() {
223-
picture_metrics_ = {};
224-
layer_metrics_ = {};
225-
SweepOneCacheAfterFrame(cache_, picture_metrics_, layer_metrics_);
213+
void RasterCache::EndFrame() {
214+
UpdateMetrics();
226215
TraceStatsToTimeline();
227216
}
228217

@@ -303,4 +292,13 @@ size_t RasterCache::EstimatePictureCacheByteSize() const {
303292
return picture_cache_bytes;
304293
}
305294

295+
RasterCacheMetrics& RasterCache::GetMetricsForKind(RasterCacheKeyKind kind) {
296+
switch (kind) {
297+
case RasterCacheKeyKind::kDisplayListMetrics:
298+
return picture_metrics_;
299+
case RasterCacheKeyKind::kLayerMetrics:
300+
return layer_metrics_;
301+
}
302+
}
303+
306304
} // namespace flutter

flow/raster_cache.h

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,40 @@ struct RasterCacheMetrics {
7878
size_t in_use_bytes = 0;
7979

8080
/**
81-
* The total cache entries that had images during this frame whether
82-
* they were used in the frame or held memory during the frame and then
83-
* were evicted after it ended.
81+
* The total cache entries that had images during this frame.
8482
*/
85-
size_t total_count() const { return in_use_count + eviction_count; }
83+
size_t total_count() const { return in_use_count; }
8684

8785
/**
88-
* The size of all of the cached images during this frame whether
89-
* they were used in the frame or held memory during the frame and then
90-
* were evicted after it ended.
86+
* The size of all of the cached images during this frame.
9187
*/
92-
size_t total_bytes() const { return in_use_bytes + eviction_bytes; }
88+
size_t total_bytes() const { return in_use_bytes; }
9389
};
9490

91+
/**
92+
* RasterCache is used to cache rasterized layers or display lists to improve
93+
* performance.
94+
*
95+
* Life cycle of RasterCache methods:
96+
* - Preroll stage
97+
* - LayerTree::Preroll - for each Layer in the tree:
98+
* - RasterCacheItem::PrerollSetup
99+
* At the start of each layer's preroll, add cache items to
100+
* `PrerollContext::raster_cached_entries`.
101+
* - RasterCacheItem::PrerollFinalize
102+
* At the end of each layer's preroll, may mark cache entris as
103+
* encountered by the current frame.
104+
* - Paint stage
105+
* - RasterCache::EvictUnusedCacheEntries
106+
* Evit cached images that are no longer used.
107+
* - LayerTree::TryToPrepareRasterCache
108+
* Create cache image for each cache entry if it does not exist.
109+
* - LayerTree::Paint - for each layer in the tree:
110+
* If layers or display lists are cached as cached images, the method
111+
* `RasterCache::Draw` will be used to draw those cache images.
112+
* - RasterCache::EndFrame:
113+
* Computes used counts and memory then reports cache metrics.
114+
*/
95115
class RasterCache {
96116
public:
97117
struct Context {
@@ -126,9 +146,11 @@ class RasterCache {
126146

127147
bool HasEntry(const RasterCacheKeyID& id, const SkMatrix&) const;
128148

129-
void PrepareNewFrame();
149+
void BeginFrame();
130150

131-
void CleanupAfterFrame();
151+
void EvictUnusedCacheEntries();
152+
153+
void EndFrame();
132154

133155
void Clear();
134156

@@ -222,9 +244,9 @@ class RasterCache {
222244
std::unique_ptr<RasterCacheResult> image;
223245
};
224246

225-
void SweepOneCacheAfterFrame(RasterCacheKey::Map<Entry>& cache,
226-
RasterCacheMetrics& picture_metrics,
227-
RasterCacheMetrics& layer_metrics);
247+
void UpdateMetrics();
248+
249+
RasterCacheMetrics& GetMetricsForKind(RasterCacheKeyKind kind);
228250

229251
const size_t access_threshold_;
230252
const size_t display_list_cache_limit_per_frame_;

0 commit comments

Comments
 (0)