@@ -238,9 +238,9 @@ TEST_F(DisplayListLayerTest, CachedIncompatibleDisplayListOpacityInheritance) {
238238 EXPECT_FALSE (context->subtree_can_inherit_opacity );
239239
240240 // Pump the DisplayListLayer until it is ready to cache its DL
241- display_list_layer->Paint ( paint_context ());
242- display_list_layer->Paint ( paint_context ());
243- display_list_layer->Paint ( paint_context ());
241+ display_list_layer->Preroll ( preroll_context (), SkMatrix ());
242+ display_list_layer->Preroll ( preroll_context (), SkMatrix ());
243+ display_list_layer->Preroll ( preroll_context (), SkMatrix ());
244244
245245 int opacity_alpha = 0x7F ;
246246 SkPoint opacity_offset = SkPoint::Make (10 , 10 );
@@ -398,5 +398,97 @@ TEST_F(DisplayListLayerTest, NoLayerTreeSnapshotsWhenDisabledByDefault) {
398398 EXPECT_EQ (0u , snapshot_store.Size ());
399399}
400400
401+ TEST_F (DisplayListLayerTest, DisplayListAccessCountDependsOnVisibility) {
402+ const SkPoint layer_offset = SkPoint::Make (1 .5f , -0 .5f );
403+ const SkRect picture_bounds = SkRect::MakeLTRB (5 .0f , 6 .0f , 20 .5f , 21 .5f );
404+ const SkRect missed_cull_rect = SkRect::MakeLTRB (100 , 100 , 200 , 200 );
405+ const SkRect hit_cull_rect = SkRect::MakeLTRB (0 , 0 , 200 , 200 );
406+ DisplayListBuilder builder;
407+ builder.drawRect (picture_bounds);
408+ auto display_list = builder.Build ();
409+ auto layer = std::make_shared<DisplayListLayer>(
410+ layer_offset, SkiaGPUObject (display_list, unref_queue ()), true , false );
411+
412+ auto raster_cache_item = layer->raster_cache_item ();
413+ use_mock_raster_cache ();
414+
415+ // First Preroll the DisplayListLayer a few times where it does not intersect
416+ // the cull rect. No caching progress should occur during this time, the
417+ // access_count should remain 0 because the DisplayList was never "visible".
418+ preroll_context ()->cull_rect = missed_cull_rect;
419+ for (int i = 0 ; i < 10 ; i++) {
420+ preroll_context ()->raster_cached_entries ->clear ();
421+ layer->Preroll (preroll_context (), SkMatrix::I ());
422+ ASSERT_EQ (raster_cache_item->cache_state (), RasterCacheItem::kNone );
423+ ASSERT_TRUE (raster_cache_item->GetId ().has_value ());
424+ ASSERT_EQ (preroll_context ()->raster_cache ->GetAccessCount (
425+ raster_cache_item->GetId ().value (), SkMatrix::I ()),
426+ 0 );
427+ ASSERT_EQ (preroll_context ()->raster_cached_entries ->size (), size_t (1 ));
428+ ASSERT_EQ (preroll_context ()->raster_cache ->EstimatePictureCacheByteSize (),
429+ size_t (0 ));
430+ ASSERT_FALSE (raster_cache_item->TryToPrepareRasterCache (paint_context ()));
431+ ASSERT_FALSE (raster_cache_item->Draw (paint_context (), nullptr ));
432+ }
433+
434+ // Next Preroll the DisplayListLayer once where it does intersect
435+ // the cull rect. No caching progress should occur during this time
436+ // since this is the first frame in which it was visible, but the
437+ // count should start incrementing.
438+ preroll_context ()->cull_rect = hit_cull_rect;
439+ preroll_context ()->raster_cached_entries ->clear ();
440+ layer->Preroll (preroll_context (), SkMatrix ());
441+ ASSERT_EQ (raster_cache_item->cache_state (), RasterCacheItem::kNone );
442+ ASSERT_TRUE (raster_cache_item->GetId ().has_value ());
443+ ASSERT_EQ (preroll_context ()->raster_cache ->GetAccessCount (
444+ raster_cache_item->GetId ().value (), SkMatrix::I ()),
445+ 1 );
446+ ASSERT_EQ (preroll_context ()->raster_cached_entries ->size (), size_t (1 ));
447+ ASSERT_EQ (preroll_context ()->raster_cache ->EstimatePictureCacheByteSize (),
448+ size_t (0 ));
449+ ASSERT_FALSE (raster_cache_item->TryToPrepareRasterCache (paint_context ()));
450+ ASSERT_FALSE (raster_cache_item->Draw (paint_context (), nullptr ));
451+
452+ // Now we can Preroll the DisplayListLayer again with a cull rect that
453+ // it does not intersect and it should continue to count these operations
454+ // even though it is not visible. No actual caching should occur yet,
455+ // even though we will surpass its threshold.
456+ preroll_context ()->cull_rect = missed_cull_rect;
457+ for (int i = 0 ; i < 10 ; i++) {
458+ preroll_context ()->raster_cached_entries ->clear ();
459+ layer->Preroll (preroll_context (), SkMatrix ());
460+ ASSERT_EQ (raster_cache_item->cache_state (), RasterCacheItem::kNone );
461+ ASSERT_TRUE (raster_cache_item->GetId ().has_value ());
462+ ASSERT_EQ (preroll_context ()->raster_cache ->GetAccessCount (
463+ raster_cache_item->GetId ().value (), SkMatrix::I ()),
464+ i + 2 );
465+ ASSERT_EQ (preroll_context ()->raster_cached_entries ->size (), size_t (1 ));
466+ ASSERT_EQ (preroll_context ()->raster_cache ->EstimatePictureCacheByteSize (),
467+ size_t (0 ));
468+ ASSERT_FALSE (raster_cache_item->TryToPrepareRasterCache (paint_context ()));
469+ ASSERT_FALSE (raster_cache_item->Draw (paint_context (), nullptr ));
470+ }
471+
472+ // Finally Preroll the DisplayListLayer again where it does intersect
473+ // the cull rect. Since we should have exhausted our access count
474+ // threshold in the loop above, these operations should result in the
475+ // DisplayList being cached.
476+ preroll_context ()->cull_rect = hit_cull_rect;
477+ preroll_context ()->raster_cached_entries ->clear ();
478+ layer->Preroll (preroll_context (), SkMatrix ());
479+ ASSERT_EQ (raster_cache_item->cache_state (), RasterCacheItem::kCurrent );
480+ ASSERT_TRUE (raster_cache_item->GetId ().has_value ());
481+ ASSERT_EQ (preroll_context ()->raster_cache ->GetAccessCount (
482+ raster_cache_item->GetId ().value (), SkMatrix::I ()),
483+ 12 );
484+ ASSERT_EQ (preroll_context ()->raster_cached_entries ->size (), size_t (1 ));
485+ ASSERT_EQ (preroll_context ()->raster_cache ->EstimatePictureCacheByteSize (),
486+ size_t (0 ));
487+ ASSERT_TRUE (raster_cache_item->TryToPrepareRasterCache (paint_context ()));
488+ ASSERT_GT (preroll_context ()->raster_cache ->EstimatePictureCacheByteSize (),
489+ size_t (0 ));
490+ ASSERT_TRUE (raster_cache_item->Draw (paint_context (), nullptr ));
491+ }
492+
401493} // namespace testing
402494} // namespace flutter
0 commit comments