Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
add test case for DL caching interaction with cull rect
  • Loading branch information
flar committed Jul 10, 2022
commit e84646f4d8f18864382eede0e827d45b8138a7b8
92 changes: 92 additions & 0 deletions flow/layers/display_list_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,5 +398,97 @@ TEST_F(DisplayListLayerTest, NoLayerTreeSnapshotsWhenDisabledByDefault) {
EXPECT_EQ(0u, snapshot_store.Size());
}

TEST_F(DisplayListLayerTest, DisplayListAccessCountDependsOnVisibility) {
const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
const SkRect missed_cull_rect = SkRect::MakeLTRB(100, 100, 200, 200);
const SkRect hit_cull_rect = SkRect::MakeLTRB(0, 0, 200, 200);
DisplayListBuilder builder;
builder.drawRect(picture_bounds);
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), true, false);

auto raster_cache_item = layer->raster_cache_item();
use_mock_raster_cache();

// First Preroll the DisplayListLayer a few times where it does not intersect
// the cull rect. No caching progress should occur during this time, the
// access_count should remain 0 because the DisplayList was never "visible".
preroll_context()->cull_rect = missed_cull_rect;
for (int i = 0; i < 10; i++) {
preroll_context()->raster_cached_entries->clear();
layer->Preroll(preroll_context(), SkMatrix::I());
ASSERT_EQ(raster_cache_item->cache_state(), RasterCacheItem::kNone);
ASSERT_TRUE(raster_cache_item->GetId().has_value());
ASSERT_EQ(preroll_context()->raster_cache->GetAccessCount(
raster_cache_item->GetId().value(), SkMatrix::I()),
0);
ASSERT_EQ(preroll_context()->raster_cached_entries->size(), size_t(1));
ASSERT_EQ(preroll_context()->raster_cache->EstimatePictureCacheByteSize(),
size_t(0));
ASSERT_FALSE(raster_cache_item->TryToPrepareRasterCache(paint_context()));
ASSERT_FALSE(raster_cache_item->Draw(paint_context(), nullptr));
}

// Next Preroll the DisplayListLayer once where it does intersect
// the cull rect. No caching progress should occur during this time
// since this is the first frame in which it was visible, but the
// count should start incrementing.
preroll_context()->cull_rect = hit_cull_rect;
preroll_context()->raster_cached_entries->clear();
layer->Preroll(preroll_context(), SkMatrix());
ASSERT_EQ(raster_cache_item->cache_state(), RasterCacheItem::kNone);
ASSERT_TRUE(raster_cache_item->GetId().has_value());
ASSERT_EQ(preroll_context()->raster_cache->GetAccessCount(
raster_cache_item->GetId().value(), SkMatrix::I()),
1);
ASSERT_EQ(preroll_context()->raster_cached_entries->size(), size_t(1));
ASSERT_EQ(preroll_context()->raster_cache->EstimatePictureCacheByteSize(),
size_t(0));
ASSERT_FALSE(raster_cache_item->TryToPrepareRasterCache(paint_context()));
ASSERT_FALSE(raster_cache_item->Draw(paint_context(), nullptr));

// Now we can Preroll the DisplayListLayer again with a cull rect that
// it does not intersect and it should continue to count these operations
// even though it is not visible. No actual caching should occur yet,
// even though we will surpass its threshold.
preroll_context()->cull_rect = missed_cull_rect;
for (int i = 0; i < 10; i++) {
preroll_context()->raster_cached_entries->clear();
layer->Preroll(preroll_context(), SkMatrix());
ASSERT_EQ(raster_cache_item->cache_state(), RasterCacheItem::kNone);
ASSERT_TRUE(raster_cache_item->GetId().has_value());
ASSERT_EQ(preroll_context()->raster_cache->GetAccessCount(
raster_cache_item->GetId().value(), SkMatrix::I()),
i + 2);
ASSERT_EQ(preroll_context()->raster_cached_entries->size(), size_t(1));
ASSERT_EQ(preroll_context()->raster_cache->EstimatePictureCacheByteSize(),
size_t(0));
ASSERT_FALSE(raster_cache_item->TryToPrepareRasterCache(paint_context()));
ASSERT_FALSE(raster_cache_item->Draw(paint_context(), nullptr));
}

// Finally Preroll the DisplayListLayer again where it does intersect
// the cull rect. Since we should have exhausted our access count
// threshold in the loop above, these operations should result in the
// DisplayList being cached.
preroll_context()->cull_rect = hit_cull_rect;
preroll_context()->raster_cached_entries->clear();
layer->Preroll(preroll_context(), SkMatrix());
ASSERT_EQ(raster_cache_item->cache_state(), RasterCacheItem::kCurrent);
ASSERT_TRUE(raster_cache_item->GetId().has_value());
ASSERT_EQ(preroll_context()->raster_cache->GetAccessCount(
raster_cache_item->GetId().value(), SkMatrix::I()),
12);
ASSERT_EQ(preroll_context()->raster_cached_entries->size(), size_t(1));
ASSERT_EQ(preroll_context()->raster_cache->EstimatePictureCacheByteSize(),
size_t(0));
ASSERT_TRUE(raster_cache_item->TryToPrepareRasterCache(paint_context()));
ASSERT_GT(preroll_context()->raster_cache->EstimatePictureCacheByteSize(),
size_t(0));
ASSERT_TRUE(raster_cache_item->Draw(paint_context(), nullptr));
}

} // namespace testing
} // namespace flutter
10 changes: 10 additions & 0 deletions flow/raster_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ int RasterCache::MarkSeen(const RasterCacheKeyID& id,
return entry.accesses_since_visible;
}

int RasterCache::GetAccessCount(const RasterCacheKeyID& id,
const SkMatrix& matrix) const {
RasterCacheKey key = RasterCacheKey(id, matrix);
auto entry = cache_.find(key);
if (entry != cache_.cend()) {
return entry->second.accesses_since_visible;
}
return -1;
}

bool RasterCache::HasEntry(const RasterCacheKeyID& id,
const SkMatrix& matrix) const {
RasterCacheKey key = RasterCacheKey(id, matrix);
Expand Down
6 changes: 6 additions & 0 deletions flow/raster_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ class RasterCache {
const SkMatrix& matrix,
bool visible) const;

/**
* Returns the access count (i.e. accesses_since_visible) for the given
* entry in the cache, or -1 if no such entry exists.
*/
int GetAccessCount(const RasterCacheKeyID& id, const SkMatrix& matrix) const;

bool UpdateCacheEntry(
const RasterCacheKeyID& id,
const Context& raster_cache_context,
Expand Down