From 6a320ce6aef61ba963b43fdeb46fa88d23af8bfd Mon Sep 17 00:00:00 2001 From: liyuqian Date: Fri, 8 Feb 2019 17:40:38 -0800 Subject: [PATCH] Throttle picture raster cache (flutter/engine#7759) This decreases worst_frame_rasterizer_time_millis from 30ms to 10ms when we enabled picture raster cache in tiles_scroll (i.e., lower the threshold from 10 to 5). --- engine/src/flutter/flow/raster_cache.cc | 12 ++++++++++-- engine/src/flutter/flow/raster_cache.h | 14 +++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/engine/src/flutter/flow/raster_cache.cc b/engine/src/flutter/flow/raster_cache.cc index 0827a2de405..fe42639fe78 100644 --- a/engine/src/flutter/flow/raster_cache.cc +++ b/engine/src/flutter/flow/raster_cache.cc @@ -36,8 +36,11 @@ void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const { canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint); } -RasterCache::RasterCache(size_t threshold) - : threshold_(threshold), checkerboard_images_(false), weak_factory_(this) {} +RasterCache::RasterCache(size_t threshold, size_t picture_cache_limit_per_frame) + : threshold_(threshold), + picture_cache_limit_per_frame_(picture_cache_limit_per_frame), + checkerboard_images_(false), + weak_factory_(this) {} RasterCache::~RasterCache() = default; @@ -182,6 +185,9 @@ bool RasterCache::Prepare(GrContext* context, SkColorSpace* dst_color_space, bool is_complex, bool will_change) { + if (picture_cached_this_frame_ >= picture_cache_limit_per_frame_) { + return false; + } if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) { // We only deal with pictures that are worthy of rasterization. return false; @@ -211,6 +217,7 @@ bool RasterCache::Prepare(GrContext* context, entry.image = RasterizePicture(picture, context, transformation_matrix, dst_color_space, checkerboard_images_); } + picture_cached_this_frame_++; return true; } @@ -232,6 +239,7 @@ void RasterCache::SweepAfterFrame() { using LayerCache = LayerRasterCacheKey::Map; SweepOneCacheAfterFrame(picture_cache_); SweepOneCacheAfterFrame(layer_cache_); + picture_cached_this_frame_ = 0; } void RasterCache::Clear() { diff --git a/engine/src/flutter/flow/raster_cache.h b/engine/src/flutter/flow/raster_cache.h index cb4383f41fb..74ce010b07c 100644 --- a/engine/src/flutter/flow/raster_cache.h +++ b/engine/src/flutter/flow/raster_cache.h @@ -42,7 +42,15 @@ struct PrerollContext; class RasterCache { public: - explicit RasterCache(size_t threshold = 3); + // The default max number of picture raster caches to be generated per frame. + // Generating too many caches in one frame may cause jank on that frame. This + // limit allows us to throttle the cache and distribute the work across + // multiple frames. + static constexpr int kDefaultPictureCacheLimitPerFrame = 3; + + explicit RasterCache( + size_t threshold = 3, + size_t picture_cache_limit_per_frame = kDefaultPictureCacheLimitPerFrame); ~RasterCache(); @@ -67,6 +75,8 @@ class RasterCache { // 1. The picture is not worth rasterizing // 2. The matrix is singular // 3. The picture is accessed too few times + // 4. There are too many pictures to be cached in the current frame. + // (See also kDefaultPictureCacheLimitPerFrame.) bool Prepare(GrContext* context, SkPicture* picture, const SkMatrix& transformation_matrix, @@ -110,6 +120,8 @@ class RasterCache { } const size_t threshold_; + const size_t picture_cache_limit_per_frame_; + size_t picture_cached_this_frame_ = 0; PictureRasterCacheKey::Map picture_cache_; LayerRasterCacheKey::Map layer_cache_; bool checkerboard_images_;