From bb60af08db670c0f85ba1ded7911fa79ecd125ea Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Tue, 2 Oct 2018 14:14:54 -0700 Subject: [PATCH 1/4] Allow raster caching any layer subtree We first test this with OpacityLayer. This test alone (without retained rendering) should have ~30% speedup as we'll have fewer render target switches by snapshoting in the Preroll instead of saveLayer in the Paint. In my local flutter_gallery transition perf tests, the average frame time drops from ~16ms to ~12ms. --- flow/compositor_context.cc | 2 +- flow/debug_print.cc | 4 +- flow/debug_print.h | 2 +- flow/layers/layer.h | 21 ++++-- flow/layers/layer_tree.cc | 38 +++++++---- flow/layers/layer_tree.h | 3 +- flow/layers/opacity_layer.cc | 31 ++++++++- flow/layers/opacity_layer.h | 2 + flow/layers/picture_layer.cc | 16 +++-- flow/layers/picture_layer.h | 1 - flow/raster_cache.cc | 114 ++++++++++++++++++++++++--------- flow/raster_cache.h | 49 +++++++++++--- flow/raster_cache_key.h | 22 +++++-- flow/raster_cache_unittests.cc | 22 +++---- 14 files changed, 234 insertions(+), 93 deletions(-) diff --git a/flow/compositor_context.cc b/flow/compositor_context.cc index aecd3a24cddf7..e5a725ef6478c 100644 --- a/flow/compositor_context.cc +++ b/flow/compositor_context.cc @@ -63,7 +63,7 @@ CompositorContext::ScopedFrame::~ScopedFrame() { bool CompositorContext::ScopedFrame::Raster(flow::LayerTree& layer_tree, bool ignore_raster_cache) { layer_tree.Preroll(*this, ignore_raster_cache); - layer_tree.Paint(*this); + layer_tree.Paint(*this, ignore_raster_cache); return true; } diff --git a/flow/debug_print.cc b/flow/debug_print.cc index e2d7fc3f4c882..b095a81d10da8 100644 --- a/flow/debug_print.cc +++ b/flow/debug_print.cc @@ -72,8 +72,8 @@ std::ostream& operator<<(std::ostream& os, const SkPoint& r) { return os; } -std::ostream& operator<<(std::ostream& os, const flow::RasterCacheKey& k) { - os << "Picture: " << k.picture_id() << " matrix: " << k.matrix(); +std::ostream& operator<<(std::ostream& os, const flow::PictureRasterCacheKey& k) { + os << "Picture: " << k.id() << " matrix: " << k.matrix(); return os; } diff --git a/flow/debug_print.h b/flow/debug_print.h index d58dcbed28bed..4db0748bc31cb 100644 --- a/flow/debug_print.h +++ b/flow/debug_print.h @@ -16,7 +16,7 @@ #define DEF_PRINTER(x) std::ostream& operator<<(std::ostream&, const x&); DEF_PRINTER(flow::MatrixDecomposition); -DEF_PRINTER(flow::RasterCacheKey); +DEF_PRINTER(flow::PictureRasterCacheKey); DEF_PRINTER(SkISize); DEF_PRINTER(SkMatrix); DEF_PRINTER(SkMatrix44); diff --git a/flow/layers/layer.h b/flow/layers/layer.h index a52f6e04aa86c..50fd3b63b277d 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -40,6 +40,19 @@ enum Clip { none, hardEdge, antiAlias, antiAliasWithSaveLayer }; class ContainerLayer; +struct PrerollContext { + RasterCache* raster_cache; + GrContext* gr_context; + SkColorSpace* dst_color_space; + SkRect child_paint_bounds; + + // The following allows us to paint in the end of subtree preroll + const Stopwatch& frame_time; + const Stopwatch& engine_time; + TextureRegistry& texture_registry; + const bool checkerboard_offscreen_layers; +}; + // Represents a single composited layer. Created on the UI thread but then // subquently used on the Rasterizer thread. class Layer { @@ -47,13 +60,6 @@ class Layer { Layer(); virtual ~Layer(); - struct PrerollContext { - RasterCache* raster_cache; - GrContext* gr_context; - SkColorSpace* dst_color_space; - SkRect child_paint_bounds; - }; - virtual void Preroll(PrerollContext* context, const SkMatrix& matrix); struct PaintContext { @@ -61,6 +67,7 @@ class Layer { const Stopwatch& frame_time; const Stopwatch& engine_time; TextureRegistry& texture_registry; + const RasterCache* raster_cache; const bool checkerboard_offscreen_layers; }; diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 29f9c93b52c19..a861bb091992b 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -25,11 +25,15 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, frame.canvas() ? frame.canvas()->imageInfo().colorSpace() : nullptr; frame.context().raster_cache().SetCheckboardCacheImages( checkerboard_raster_cache_images_); - Layer::PrerollContext context = { + PrerollContext context = { ignore_raster_cache ? nullptr : &frame.context().raster_cache(), frame.gr_context(), color_space, SkRect::MakeEmpty(), + frame.context().frame_time(), + frame.context().engine_time(), + frame.context().texture_registry(), + checkerboard_offscreen_layers_ }; root_layer_->Preroll(&context, frame.root_surface_transformation()); @@ -60,14 +64,16 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, } #endif -void LayerTree::Paint(CompositorContext::ScopedFrame& frame) const { +void LayerTree::Paint(CompositorContext::ScopedFrame& frame, + bool ignore_raster_cache) const { TRACE_EVENT0("flutter", "LayerTree::Paint"); Layer::PaintContext context = { - *frame.canvas(), // - frame.context().frame_time(), // - frame.context().engine_time(), // - frame.context().texture_registry(), // - checkerboard_offscreen_layers_ // + *frame.canvas(), + frame.context().frame_time(), + frame.context().engine_time(), + frame.context().texture_registry(), + ignore_raster_cache ? nullptr : &frame.context().raster_cache(), + checkerboard_offscreen_layers_ }; if (root_layer_->needs_painting()) @@ -84,24 +90,28 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return nullptr; } - Layer::PrerollContext preroll_context{ - nullptr, // raster_cache (don't consult the cache) - nullptr, // gr_context (used for the raster cache) - nullptr, // SkColorSpace* dst_color_space - SkRect::MakeEmpty(), // SkRect child_paint_bounds - }; - const Stopwatch unused_stopwatch; TextureRegistry unused_texture_registry; SkMatrix root_surface_transformation; // No root surface transformation. So assume identity. root_surface_transformation.reset(); + PrerollContext preroll_context{ + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // SkColorSpace* dst_color_space + SkRect::MakeEmpty(), // SkRect child_paint_bounds + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry // texture registry (not supported) + }; + Layer::PaintContext paint_context = { *canvas, // canvas unused_stopwatch, // frame time (dont care) unused_stopwatch, // engine time (dont care) unused_texture_registry, // texture registry (not supported) + nullptr, // raster cache false // checkerboard offscreen layers }; diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index 93d4e27cde2d5..e8591b49661c7 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -32,7 +32,8 @@ class LayerTree { scenic::ContainerNode& container); #endif - void Paint(CompositorContext::ScopedFrame& frame) const; + void Paint(CompositorContext::ScopedFrame& frame, + bool ignore_raster_cache = false) const; sk_sp Flatten(const SkRect& bounds); diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index 2272e79093864..df77e030119e4 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -10,6 +10,18 @@ OpacityLayer::OpacityLayer() = default; OpacityLayer::~OpacityLayer() = default; +void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { + ContainerLayer::Preroll(context, matrix); + if (context->raster_cache && layers().size() == 1) { + std::shared_ptr child = layers()[0]; + SkMatrix ctm = matrix; + #ifndef SUPPORT_FRACTIONAL_TRANSLATION + ctm = RasterCache::GetIntegralTransCTM(ctm); + #endif + context->raster_cache->Prepare(context, child, ctm); + } +} + void OpacityLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "OpacityLayer::Paint"); FML_DCHECK(needs_painting()); @@ -17,7 +29,24 @@ void OpacityLayer::Paint(PaintContext& context) const { SkPaint paint; paint.setAlpha(alpha_); - Layer::AutoSaveLayer save = + SkAutoCanvasRestore save(&context.canvas, true); + +#ifndef SUPPORT_FRACTIONAL_TRANSLATION + context.canvas.setMatrix( + RasterCache::GetIntegralTransCTM(context.canvas.getTotalMatrix())); +#endif + + if (layers().size() == 1 && context.raster_cache) { + const SkMatrix& ctm = context.canvas.getTotalMatrix(); + RasterCacheResult child_cache = + context.raster_cache->Get(layers()[0], ctm); + if (child_cache.is_valid()) { + child_cache.draw(context.canvas, &paint); + return; + } + } + + Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create(context, paint_bounds(), &paint); PaintChildren(context); } diff --git a/flow/layers/opacity_layer.h b/flow/layers/opacity_layer.h index b27829385046b..4733d13645233 100644 --- a/flow/layers/opacity_layer.h +++ b/flow/layers/opacity_layer.h @@ -16,6 +16,8 @@ class OpacityLayer : public ContainerLayer { void set_alpha(int alpha) { alpha_ = alpha; } + void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + void Paint(PaintContext& context) const override; // TODO(chinmaygarde): Once MZ-139 is addressed, introduce a new node in the diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 3cbf15a609ad1..76dd9904ecc78 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -21,11 +21,9 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { #ifndef SUPPORT_FRACTIONAL_TRANSLATION ctm = RasterCache::GetIntegralTransCTM(ctm); #endif - raster_cache_result_ = cache->GetPrerolledImage( + cache->Prepare( context->gr_context, sk_picture, ctm, context->dst_color_space, is_complex_, will_change_); - } else { - raster_cache_result_ = RasterCacheResult(); } SkRect bounds = sk_picture->cullRect().makeOffset(offset_.x(), offset_.y()); @@ -44,11 +42,15 @@ void PictureLayer::Paint(PaintContext& context) const { RasterCache::GetIntegralTransCTM(context.canvas.getTotalMatrix())); #endif - if (raster_cache_result_.is_valid()) { - raster_cache_result_.draw(context.canvas); - } else { - context.canvas.drawPicture(picture()); + if (context.raster_cache) { + const SkMatrix& ctm = context.canvas.getTotalMatrix(); + RasterCacheResult result = context.raster_cache->Get(*picture(), ctm); + if (result.is_valid()) { + result.draw(context.canvas); + return; + } } + context.canvas.drawPicture(picture()); } } // namespace flow diff --git a/flow/layers/picture_layer.h b/flow/layers/picture_layer.h index 12e2807c33d23..8b6f74c313839 100644 --- a/flow/layers/picture_layer.h +++ b/flow/layers/picture_layer.h @@ -39,7 +39,6 @@ class PictureLayer : public Layer { SkiaGPUObject picture_; bool is_complex_ = false; bool will_change_ = false; - RasterCacheResult raster_cache_result_; FML_DISALLOW_COPY_AND_ASSIGN(PictureLayer); }; diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index a3aef6e3d1410..ec3daacc81efd 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -6,6 +6,7 @@ #include +#include "flutter/flow/layers/layer.h" #include "flutter/flow/paint_utils.h" #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" @@ -17,13 +18,13 @@ namespace flow { -void RasterCacheResult::draw(SkCanvas& canvas) const { +void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const { SkAutoCanvasRestore auto_restore(&canvas, true); SkIRect bounds = RasterCache::GetDeviceBounds(logical_rect_, canvas.getTotalMatrix()); FML_DCHECK(bounds.size() == image_->dimensions()); canvas.resetMatrix(); - canvas.drawImage(image_, bounds.fLeft, bounds.fTop); + canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint); } RasterCache::RasterCache(size_t threshold) @@ -77,14 +78,14 @@ static bool IsPictureWorthRasterizing(SkPicture* picture, return picture->approximateOpCount() > 10; } -RasterCacheResult RasterizePicture(SkPicture* picture, - GrContext* context, - const SkMatrix& ctm, - SkColorSpace* dst_color_space, - bool checkerboard) { - TRACE_EVENT0("flutter", "RasterCachePopulate"); - - const SkRect logical_rect = picture->cullRect(); +static RasterCacheResult Rasterize( + GrContext* context, + const SkMatrix& ctm, + SkColorSpace* dst_color_space, + bool checkerboard, + const SkRect& logical_rect, + std::function draw_function +) { SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm); const SkImageInfo image_info = @@ -112,7 +113,7 @@ RasterCacheResult RasterizePicture(SkPicture* picture, canvas->clear(SK_ColorTRANSPARENT); canvas->translate(-cache_rect.left(), -cache_rect.top()); canvas->concat(ctm); - canvas->drawPicture(picture); + draw_function(canvas); if (checkerboard) { DrawCheckerboard(canvas, logical_rect); @@ -121,6 +122,25 @@ RasterCacheResult RasterizePicture(SkPicture* picture, return {surface->makeImageSnapshot(), logical_rect}; } +RasterCacheResult RasterizePicture(SkPicture* picture, + GrContext* context, + const SkMatrix& ctm, + SkColorSpace* dst_color_space, + bool checkerboard) { + TRACE_EVENT0("flutter", "RasterCachePopulate"); + + return Rasterize( + context, + ctm, + dst_color_space, + checkerboard, + picture->cullRect(), + [=](SkCanvas* canvas){ + canvas->drawPicture(picture); + } + ); +} + static inline size_t ClampSize(size_t value, size_t min, size_t max) { if (value > max) { return max; @@ -133,7 +153,35 @@ static inline size_t ClampSize(size_t value, size_t min, size_t max) { return value; } -RasterCacheResult RasterCache::GetPrerolledImage( +void RasterCache::Prepare(PrerollContext* context, std::shared_ptr layer, + const SkMatrix& ctm) { + LayerRasterCacheKey cache_key(layer, ctm); + Entry& entry = layer_cache_[cache_key]; + entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); + entry.used_this_frame = true; + if (!entry.image.is_valid()) { + entry.image = Rasterize( + context->gr_context, + ctm, + context->dst_color_space, + checkerboard_images_, + layer->paint_bounds(), + [layer, context](SkCanvas* canvas){ + Layer::PaintContext paintContext = { + *canvas, + context->frame_time, + context->engine_time, + context->texture_registry, + context->raster_cache, + context->checkerboard_offscreen_layers + }; + layer->Paint(paintContext); + } + ); + } +} + +bool RasterCache::Prepare( GrContext* context, SkPicture* picture, const SkMatrix& transformation_matrix, @@ -142,7 +190,7 @@ RasterCacheResult RasterCache::GetPrerolledImage( bool will_change) { if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) { // We only deal with pictures that are worthy of rasterization. - return {}; + return false; } // Decompose the matrix (once) for all subsequent operations. We want to make @@ -151,46 +199,48 @@ RasterCacheResult RasterCache::GetPrerolledImage( if (!matrix.IsValid()) { // The matrix was singular. No point in going further. - return {}; + return false; } - RasterCacheKey cache_key(*picture, transformation_matrix); + PictureRasterCacheKey cache_key(picture->uniqueID(), transformation_matrix); - Entry& entry = cache_[cache_key]; + Entry& entry = picture_cache_[cache_key]; entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); entry.used_this_frame = true; if (entry.access_count < threshold_ || threshold_ == 0) { // Frame threshold has not yet been reached. - return {}; + return false; } if (!entry.image.is_valid()) { entry.image = RasterizePicture(picture, context, transformation_matrix, dst_color_space, checkerboard_images_); } - - return entry.image; + return true; } -void RasterCache::SweepAfterFrame() { - std::vector::iterator> dead; +RasterCacheResult RasterCache::Get(const SkPicture& picture, const SkMatrix& ctm) const { + PictureRasterCacheKey cache_key(picture.uniqueID(), ctm); + auto it = picture_cache_.find(cache_key); + return it == picture_cache_.end() ? RasterCacheResult() : it->second.image; +} - for (auto it = cache_.begin(); it != cache_.end(); ++it) { - Entry& entry = it->second; - if (!entry.used_this_frame) { - dead.push_back(it); - } - entry.used_this_frame = false; - } +RasterCacheResult RasterCache::Get(std::shared_ptr layer, const SkMatrix& ctm) const { + LayerRasterCacheKey cache_key(layer, ctm); + auto it = layer_cache_.find(cache_key); + return it == layer_cache_.end() ? RasterCacheResult() : it->second.image; +} - for (auto it : dead) { - cache_.erase(it); - } +void RasterCache::SweepAfterFrame() { + using PictureCache = PictureRasterCacheKey::Map; + using LayerCache = LayerRasterCacheKey::Map; + SweepOneCacheAfterFrame(picture_cache_); + SweepOneCacheAfterFrame(layer_cache_); } void RasterCache::Clear() { - cache_.clear(); + picture_cache_.clear(); } void RasterCache::SetCheckboardCacheImages(bool checkerboard) { diff --git a/flow/raster_cache.h b/flow/raster_cache.h index 348ab8000da39..ac2afc567bea7 100644 --- a/flow/raster_cache.h +++ b/flow/raster_cache.h @@ -28,13 +28,15 @@ class RasterCacheResult { bool is_valid() const { return static_cast(image_); }; - void draw(SkCanvas& canvas) const; + void draw(SkCanvas& canvas, const SkPaint* paint = nullptr) const; private: sk_sp image_; SkRect logical_rect_; }; +struct PrerollContext; + class RasterCache { public: explicit RasterCache(size_t threshold = 3); @@ -56,12 +58,25 @@ class RasterCache { return result; } - RasterCacheResult GetPrerolledImage(GrContext* context, - SkPicture* picture, - const SkMatrix& transformation_matrix, - SkColorSpace* dst_color_space, - bool is_complex, - bool will_change); + // Return true if the cache is generated. + // + // We may return false and not generate the cache if + // 1. The picture is not worth rasterizing + // 2. The matrix is singular + // 3. The picture is accessed too few times + bool Prepare(GrContext* context, + SkPicture* picture, + const SkMatrix& transformation_matrix, + SkColorSpace* dst_color_space, + bool is_complex, + bool will_change); + + void Prepare(PrerollContext* context, + std::shared_ptr layer, + const SkMatrix& ctm); + + RasterCacheResult Get(const SkPicture& picture, const SkMatrix& ctm) const; + RasterCacheResult Get(std::shared_ptr layer, const SkMatrix& ctm) const; void SweepAfterFrame(); @@ -76,8 +91,26 @@ class RasterCache { RasterCacheResult image; }; + template + static void SweepOneCacheAfterFrame(Cache& cache) { + std::vector dead; + + for (auto it = cache.begin(); it != cache.end(); ++it) { + Entry& entry = it->second; + if (!entry.used_this_frame) { + dead.push_back(it); + } + entry.used_this_frame = false; + } + + for (auto it : dead) { + cache.erase(it); + } + } + const size_t threshold_; - RasterCacheKey::Map cache_; + PictureRasterCacheKey::Map picture_cache_; + LayerRasterCacheKey::Map layer_cache_; bool checkerboard_images_; fml::WeakPtrFactory weak_factory_; diff --git a/flow/raster_cache_key.h b/flow/raster_cache_key.h index 3f20072df8e3b..c6ebdf7cffcdf 100644 --- a/flow/raster_cache_key.h +++ b/flow/raster_cache_key.h @@ -14,10 +14,11 @@ namespace flow { +template class RasterCacheKey { public: - RasterCacheKey(const SkPicture& picture, const SkMatrix& ctm) - : picture_id_(picture.uniqueID()), matrix_(ctm) { + RasterCacheKey(ID id, const SkMatrix& ctm) + : id_(id), matrix_(ctm) { matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX()); matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY()); #ifndef SUPPORT_FRACTIONAL_TRANSLATION @@ -25,19 +26,19 @@ class RasterCacheKey { #endif } - uint32_t picture_id() const { return picture_id_; } + ID id() const { return id_; } const SkMatrix& matrix() const { return matrix_; } struct Hash { - std::size_t operator()(RasterCacheKey const& key) const { - return key.picture_id_; + uint32_t operator()(RasterCacheKey const& key) const { + return std::hash()(key.id_); } }; struct Equal { constexpr bool operator()(const RasterCacheKey& lhs, const RasterCacheKey& rhs) const { - return lhs.picture_id_ == rhs.picture_id_ && lhs.matrix_ == rhs.matrix_; + return lhs.id_ == rhs.id_ && lhs.matrix_ == rhs.matrix_; } }; @@ -45,7 +46,7 @@ class RasterCacheKey { using Map = std::unordered_map; private: - uint32_t picture_id_; + ID id_; // ctm where only fractional (0-1) translations are preserved: // matrix_ = ctm; @@ -54,6 +55,13 @@ class RasterCacheKey { SkMatrix matrix_; }; +// The ID is the uint32_t picture uniqueID +using PictureRasterCacheKey = RasterCacheKey; + +class Layer; + +using LayerRasterCacheKey = RasterCacheKey>; + } // namespace flow #endif // FLUTTER_FLOW_RASTER_CACHE_KEY_H_ diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc index 0033d475b4bcb..81789e0b13fae 100644 --- a/flow/raster_cache_unittests.cc +++ b/flow/raster_cache_unittests.cc @@ -33,13 +33,13 @@ TEST(RasterCache, ThresholdIsRespected) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 2 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 3 cache.SweepAfterFrame(); } @@ -55,13 +55,13 @@ TEST(RasterCache, ThresholdIsRespectedWhenZero) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 2 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 3 cache.SweepAfterFrame(); } @@ -77,19 +77,19 @@ TEST(RasterCache, SweepsRemoveUnusedFrames) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 2 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 3 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 4 cache.SweepAfterFrame(); cache.SweepAfterFrame(); // Extra frame without a preroll image access. - ASSERT_FALSE(cache.GetPrerolledImage(NULL, picture.get(), matrix, srgb.get(), + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, false)); // 5 } From 19ea1a81fc829216d094a557e906e21e843c51b9 Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Thu, 4 Oct 2018 16:04:35 -0700 Subject: [PATCH 2/4] Clang format --- flow/debug_print.cc | 8 ++-- flow/layers/layer_tree.cc | 20 +++++----- flow/layers/opacity_layer.cc | 9 ++--- flow/layers/picture_layer.cc | 5 +-- flow/raster_cache.cc | 68 ++++++++++++++-------------------- flow/raster_cache.h | 3 +- flow/raster_cache_key.h | 3 +- flow/raster_cache_unittests.cc | 44 +++++++++++----------- 8 files changed, 72 insertions(+), 88 deletions(-) diff --git a/flow/debug_print.cc b/flow/debug_print.cc index b095a81d10da8..a811e4abea875 100644 --- a/flow/debug_print.cc +++ b/flow/debug_print.cc @@ -25,9 +25,8 @@ std::ostream& operator<<(std::ostream& os, const flow::MatrixDecomposition& m) { std::ostream& operator<<(std::ostream& os, const SkMatrix& m) { SkString string; - string.printf( - "[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]", - m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); + string.printf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]", + m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); os << string.c_str(); return os; } @@ -72,7 +71,8 @@ std::ostream& operator<<(std::ostream& os, const SkPoint& r) { return os; } -std::ostream& operator<<(std::ostream& os, const flow::PictureRasterCacheKey& k) { +std::ostream& operator<<(std::ostream& os, + const flow::PictureRasterCacheKey& k) { os << "Picture: " << k.id() << " matrix: " << k.matrix(); return os; } diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index a861bb091992b..c439c6ef62f86 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -33,8 +33,7 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, frame.context().frame_time(), frame.context().engine_time(), frame.context().texture_registry(), - checkerboard_offscreen_layers_ - }; + checkerboard_offscreen_layers_}; root_layer_->Preroll(&context, frame.root_surface_transformation()); } @@ -73,8 +72,7 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, frame.context().engine_time(), frame.context().texture_registry(), ignore_raster_cache ? nullptr : &frame.context().raster_cache(), - checkerboard_offscreen_layers_ - }; + checkerboard_offscreen_layers_}; if (root_layer_->needs_painting()) root_layer_->Paint(context); @@ -97,13 +95,13 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { root_surface_transformation.reset(); PrerollContext preroll_context{ - nullptr, // raster_cache (don't consult the cache) - nullptr, // gr_context (used for the raster cache) - nullptr, // SkColorSpace* dst_color_space - SkRect::MakeEmpty(), // SkRect child_paint_bounds - unused_stopwatch, // frame time (dont care) - unused_stopwatch, // engine time (dont care) - unused_texture_registry // texture registry (not supported) + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // SkColorSpace* dst_color_space + SkRect::MakeEmpty(), // SkRect child_paint_bounds + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry // texture registry (not supported) }; Layer::PaintContext paint_context = { diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index df77e030119e4..351d3107f0d50 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -15,9 +15,9 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { if (context->raster_cache && layers().size() == 1) { std::shared_ptr child = layers()[0]; SkMatrix ctm = matrix; - #ifndef SUPPORT_FRACTIONAL_TRANSLATION - ctm = RasterCache::GetIntegralTransCTM(ctm); - #endif +#ifndef SUPPORT_FRACTIONAL_TRANSLATION + ctm = RasterCache::GetIntegralTransCTM(ctm); +#endif context->raster_cache->Prepare(context, child, ctm); } } @@ -38,8 +38,7 @@ void OpacityLayer::Paint(PaintContext& context) const { if (layers().size() == 1 && context.raster_cache) { const SkMatrix& ctm = context.canvas.getTotalMatrix(); - RasterCacheResult child_cache = - context.raster_cache->Get(layers()[0], ctm); + RasterCacheResult child_cache = context.raster_cache->Get(layers()[0], ctm); if (child_cache.is_valid()) { child_cache.draw(context.canvas, &paint); return; diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 76dd9904ecc78..9dcef880b7313 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -21,9 +21,8 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { #ifndef SUPPORT_FRACTIONAL_TRANSLATION ctm = RasterCache::GetIntegralTransCTM(ctm); #endif - cache->Prepare( - context->gr_context, sk_picture, ctm, context->dst_color_space, - is_complex_, will_change_); + cache->Prepare(context->gr_context, sk_picture, ctm, + context->dst_color_space, is_complex_, will_change_); } SkRect bounds = sk_picture->cullRect().makeOffset(offset_.x(), offset_.y()); diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index ec3daacc81efd..8100453457ca1 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -84,8 +84,7 @@ static RasterCacheResult Rasterize( SkColorSpace* dst_color_space, bool checkerboard, const SkRect& logical_rect, - std::function draw_function -) { + std::function draw_function) { SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm); const SkImageInfo image_info = @@ -129,16 +128,9 @@ RasterCacheResult RasterizePicture(SkPicture* picture, bool checkerboard) { TRACE_EVENT0("flutter", "RasterCachePopulate"); - return Rasterize( - context, - ctm, - dst_color_space, - checkerboard, - picture->cullRect(), - [=](SkCanvas* canvas){ - canvas->drawPicture(picture); - } - ); + return Rasterize(context, ctm, dst_color_space, checkerboard, + picture->cullRect(), + [=](SkCanvas* canvas) { canvas->drawPicture(picture); }); } static inline size_t ClampSize(size_t value, size_t min, size_t max) { @@ -153,41 +145,35 @@ static inline size_t ClampSize(size_t value, size_t min, size_t max) { return value; } -void RasterCache::Prepare(PrerollContext* context, std::shared_ptr layer, +void RasterCache::Prepare(PrerollContext* context, + std::shared_ptr layer, const SkMatrix& ctm) { LayerRasterCacheKey cache_key(layer, ctm); Entry& entry = layer_cache_[cache_key]; entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); entry.used_this_frame = true; if (!entry.image.is_valid()) { - entry.image = Rasterize( - context->gr_context, - ctm, - context->dst_color_space, - checkerboard_images_, - layer->paint_bounds(), - [layer, context](SkCanvas* canvas){ - Layer::PaintContext paintContext = { - *canvas, - context->frame_time, - context->engine_time, - context->texture_registry, - context->raster_cache, - context->checkerboard_offscreen_layers - }; - layer->Paint(paintContext); - } - ); + entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space, + checkerboard_images_, layer->paint_bounds(), + [layer, context](SkCanvas* canvas) { + Layer::PaintContext paintContext = { + *canvas, + context->frame_time, + context->engine_time, + context->texture_registry, + context->raster_cache, + context->checkerboard_offscreen_layers}; + layer->Paint(paintContext); + }); } } -bool RasterCache::Prepare( - GrContext* context, - SkPicture* picture, - const SkMatrix& transformation_matrix, - SkColorSpace* dst_color_space, - bool is_complex, - bool will_change) { +bool RasterCache::Prepare(GrContext* context, + SkPicture* picture, + const SkMatrix& transformation_matrix, + SkColorSpace* dst_color_space, + bool is_complex, + bool will_change) { if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) { // We only deal with pictures that are worthy of rasterization. return false; @@ -220,13 +206,15 @@ bool RasterCache::Prepare( return true; } -RasterCacheResult RasterCache::Get(const SkPicture& picture, const SkMatrix& ctm) const { +RasterCacheResult RasterCache::Get(const SkPicture& picture, + const SkMatrix& ctm) const { PictureRasterCacheKey cache_key(picture.uniqueID(), ctm); auto it = picture_cache_.find(cache_key); return it == picture_cache_.end() ? RasterCacheResult() : it->second.image; } -RasterCacheResult RasterCache::Get(std::shared_ptr layer, const SkMatrix& ctm) const { +RasterCacheResult RasterCache::Get(std::shared_ptr layer, + const SkMatrix& ctm) const { LayerRasterCacheKey cache_key(layer, ctm); auto it = layer_cache_.find(cache_key); return it == layer_cache_.end() ? RasterCacheResult() : it->second.image; diff --git a/flow/raster_cache.h b/flow/raster_cache.h index ac2afc567bea7..f15028e1d019d 100644 --- a/flow/raster_cache.h +++ b/flow/raster_cache.h @@ -76,7 +76,8 @@ class RasterCache { const SkMatrix& ctm); RasterCacheResult Get(const SkPicture& picture, const SkMatrix& ctm) const; - RasterCacheResult Get(std::shared_ptr layer, const SkMatrix& ctm) const; + RasterCacheResult Get(std::shared_ptr layer, + const SkMatrix& ctm) const; void SweepAfterFrame(); diff --git a/flow/raster_cache_key.h b/flow/raster_cache_key.h index c6ebdf7cffcdf..d681bff4b3a36 100644 --- a/flow/raster_cache_key.h +++ b/flow/raster_cache_key.h @@ -17,8 +17,7 @@ namespace flow { template class RasterCacheKey { public: - RasterCacheKey(ID id, const SkMatrix& ctm) - : id_(id), matrix_(ctm) { + RasterCacheKey(ID id, const SkMatrix& ctm) : id_(id), matrix_(ctm) { matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX()); matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY()); #ifndef SUPPORT_FRACTIONAL_TRANSLATION diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc index 81789e0b13fae..5d6c89b48e23d 100644 --- a/flow/raster_cache_unittests.cc +++ b/flow/raster_cache_unittests.cc @@ -33,14 +33,14 @@ TEST(RasterCache, ThresholdIsRespected) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 1 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 2 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 2 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 3 + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 3 cache.SweepAfterFrame(); } @@ -55,14 +55,14 @@ TEST(RasterCache, ThresholdIsRespectedWhenZero) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 1 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 2 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 2 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 3 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 3 cache.SweepAfterFrame(); } @@ -77,19 +77,19 @@ TEST(RasterCache, SweepsRemoveUnusedFrames) { sk_sp image; sk_sp srgb = SkColorSpace::MakeSRGB(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 1 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 1 cache.SweepAfterFrame(); - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 2 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 2 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 3 + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 3 cache.SweepAfterFrame(); - ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 4 + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 4 cache.SweepAfterFrame(); cache.SweepAfterFrame(); // Extra frame without a preroll image access. - ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), - true, false)); // 5 + ASSERT_FALSE(cache.Prepare(NULL, picture.get(), matrix, srgb.get(), true, + false)); // 5 } From 2eb60b1e809db45e4848aef5f4a44b718389d5fa Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Wed, 10 Oct 2018 17:09:07 -0700 Subject: [PATCH 3/4] Fixes Fuchsia build --- flow/layers/layer_tree.cc | 3 ++- flow/scene_update_context.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index c439c6ef62f86..4925d3ba82870 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -101,7 +101,8 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { SkRect::MakeEmpty(), // SkRect child_paint_bounds unused_stopwatch, // frame time (dont care) unused_stopwatch, // engine time (dont care) - unused_texture_registry // texture registry (not supported) + unused_texture_registry, // texture registry (not supported) + false, // checkerboard_offscreen_layers }; Layer::PaintContext paint_context = { diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index 576bde7fa1aff..7b63f91c9ed93 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -189,7 +189,8 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); Layer::PaintContext context = {*canvas, frame.context().frame_time(), frame.context().engine_time(), - frame.context().texture_registry(), false}; + frame.context().texture_registry(), + &frame.context().raster_cache(), false}; canvas->restoreToCount(1); canvas->save(); canvas->clear(task.background_color); From bb7e792d8514121ff691f6ff495ae228642cc04e Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Thu, 11 Oct 2018 10:56:57 -0700 Subject: [PATCH 4/4] Clang format --- flow/layers/layer_tree.cc | 16 ++++++++-------- flow/scene_update_context.cc | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 4925d3ba82870..de28918193576 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -95,14 +95,14 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { root_surface_transformation.reset(); PrerollContext preroll_context{ - nullptr, // raster_cache (don't consult the cache) - nullptr, // gr_context (used for the raster cache) - nullptr, // SkColorSpace* dst_color_space - SkRect::MakeEmpty(), // SkRect child_paint_bounds - unused_stopwatch, // frame time (dont care) - unused_stopwatch, // engine time (dont care) - unused_texture_registry, // texture registry (not supported) - false, // checkerboard_offscreen_layers + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // SkColorSpace* dst_color_space + SkRect::MakeEmpty(), // SkRect child_paint_bounds + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry, // texture registry (not supported) + false, // checkerboard_offscreen_layers }; Layer::PaintContext paint_context = { diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index 7b63f91c9ed93..a89df0ff7ae9a 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -187,10 +187,12 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { for (auto& task : paint_tasks_) { FML_DCHECK(task.surface); SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); - Layer::PaintContext context = {*canvas, frame.context().frame_time(), + Layer::PaintContext context = {*canvas, + frame.context().frame_time(), frame.context().engine_time(), frame.context().texture_registry(), - &frame.context().raster_cache(), false}; + &frame.context().raster_cache(), + false}; canvas->restoreToCount(1); canvas->save(); canvas->clear(task.background_color);