Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3ea7e25

Browse files
committed
Collection Need RasterCache Layer in Preroll
1 parent bff7d76 commit 3ea7e25

File tree

8 files changed

+105
-34
lines changed

8 files changed

+105
-34
lines changed

flow/layers/container_layer.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {
188188
}
189189
}
190190

191+
void ContainerLayer::TryToPrepareRasterCache(PrerollContext* context,
192+
const SkMatrix& ctm) {
193+
if (!context->has_platform_view && !context->has_texture_layer &&
194+
context->raster_cache &&
195+
SkRect::Intersects(context->cull_rect, this->paint_bounds())) {
196+
context->raster_cache->Prepare(context, this, ctm);
197+
} else if (context->raster_cache) {
198+
// Don't evict raster cache entry during partial repaint
199+
context->raster_cache->Touch(this, ctm);
200+
}
201+
}
202+
191203
void ContainerLayer::TryToPrepareRasterCache(PrerollContext* context,
192204
Layer* layer,
193205
const SkMatrix& matrix) {

flow/layers/container_layer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class ContainerLayer : public Layer {
2020

2121
virtual void Add(std::shared_ptr<Layer> layer);
2222

23+
void TryToPrepareRasterCache(PrerollContext* context,
24+
const SkMatrix& ctm) override;
25+
2326
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
2427
void Paint(PaintContext& context) const override;
2528

flow/layers/image_filter_layer.cc

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,22 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
3939
void ImageFilterLayer::Preroll(PrerollContext* context,
4040
const SkMatrix& matrix) {
4141
TRACE_EVENT0("flutter", "ImageFilterLayer::Preroll");
42+
4243
Layer::AutoPrerollSaveLayerState save =
4344
Layer::AutoPrerollSaveLayerState::Create(context);
4445

46+
context->raster_cached_entries.emplace_back(RasterCacheEntry(this));
47+
auto current_index = context->raster_cached_entries.size();
48+
49+
auto& cache_entry = context->raster_cached_entries.back();
50+
4551
SkRect child_bounds = SkRect::MakeEmpty();
4652
PrerollChildren(context, matrix, &child_bounds);
4753

54+
cache_entry.num_child_entries =
55+
context->raster_cached_entries.size() - current_index;
56+
cache_entry.need_caching = IsNeedCached(context, matrix);
57+
4858
if (!filter_) {
4959
set_paint_bounds(child_bounds);
5060
return;
@@ -56,37 +66,36 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
5666
child_bounds = SkRect::Make(filter_output_bounds);
5767

5868
set_paint_bounds(child_bounds);
69+
}
5970

60-
transformed_filter_ = nullptr;
71+
bool ImageFilterLayer::IsNeedCached(PrerollContext* context,
72+
const SkMatrix& ctm) {
6173
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
62-
// We have rendered this same ImageFilterLayer object enough
63-
// times to consider its properties and children to be stable
64-
// from frame to frame so we try to cache the layer itself
65-
// for maximum performance.
66-
TryToPrepareRasterCache(context, this, matrix);
67-
} else {
68-
// This ImageFilterLayer is not yet considered stable so we
69-
// increment the count to measure how many times it has been
70-
// seen from frame to frame.
71-
render_count_++;
72-
73-
// Now we will try to pre-render the children into the cache.
74-
// To apply the filter to pre-rendered children, we must first
75-
// modify the filter to be aware of the transform under which
76-
// the cached bitmap was produced. Some SkImageFilter
77-
// instances can do this operation on some transforms and some
78-
// (filters or transforms) cannot. We can only cache the children
79-
// and apply the filter on the fly if this operation succeeds.
80-
transformed_filter_ = filter_->makeWithLocalMatrix(matrix);
81-
if (transformed_filter_) {
82-
// With a modified SkImageFilter we can now try to cache the
83-
// children to avoid their rendering costs if they remain
84-
// stable between frames and also avoiding a rendering surface
85-
// switch during the Paint phase even if they are not stable.
86-
// This benefit is seen most during animations.
87-
TryToPrepareRasterCache(context, GetCacheableChild(), matrix);
88-
}
74+
return true;
75+
}
76+
transformed_filter_ = nullptr;
77+
// This ImageFilterLayer is not yet considered stable so we
78+
// increment the count to measure how many times it has been
79+
// seen from frame to frame.
80+
render_count_++;
81+
82+
// Now we will try to pre-render the children into the cache.
83+
// To apply the filter to pre-rendered children, we must first
84+
// modify the filter to be aware of the transform under which
85+
// the cached bitmap was produced. Some SkImageFilter
86+
// instances can do this operation on some transforms and some
87+
// (filters or transforms) cannot. We can only cache the children
88+
// and apply the filter on the fly if this operation succeeds.
89+
transformed_filter_ = filter_->makeWithLocalMatrix(ctm);
90+
if (transformed_filter_) {
91+
// With a modified SkImageFilter we can now try to cache the
92+
// children to avoid their rendering costs if they remain
93+
// stable between frames and also avoiding a rendering surface
94+
// switch during the Paint phase even if they are not stable.
95+
// This benefit is seen most during animations.
96+
return true;
8997
}
98+
return false;
9099
}
91100

92101
void ImageFilterLayer::Paint(PaintContext& context) const {

flow/layers/image_filter_layer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class ImageFilterLayer : public MergedContainerLayer {
2020

2121
void Paint(PaintContext& context) const override;
2222

23+
bool IsNeedCached(PrerollContext* context, const SkMatrix& ctm) override;
24+
2325
private:
2426
// The ImageFilterLayer might cache the filtered output of this layer
2527
// if the layer remains stable (if it is not animating for instance).

flow/layers/layer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
// found in the LICENSE file.
44

55
#include "flutter/flow/layers/layer.h"
6+
#include <algorithm>
67

78
#include "flutter/flow/paint_utils.h"
9+
#include "flutter/flow/raster_cache.h"
10+
#include "include/core/SkMatrix.h"
811
#include "third_party/skia/include/core/SkColorFilter.h"
912

1013
namespace flutter {
@@ -29,6 +32,9 @@ uint64_t Layer::NextUniqueID() {
2932

3033
void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {}
3134

35+
void Layer::TryToPrepareRasterCache(PrerollContext* context,
36+
const SkMatrix& ctm) {}
37+
3238
Layer::AutoPrerollSaveLayerState::AutoPrerollSaveLayerState(
3339
PrerollContext* preroll_context,
3440
bool save_layer_is_active,

flow/layers/layer.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
#ifndef FLUTTER_FLOW_LAYERS_LAYER_H_
66
#define FLUTTER_FLOW_LAYERS_LAYER_H_
77

8+
#include <algorithm>
89
#include <memory>
10+
#include <unordered_set>
911
#include <vector>
1012

1113
#include "flutter/common/graphics/texture.h"
@@ -34,11 +36,24 @@ namespace testing {
3436
class MockLayer;
3537
} // namespace testing
3638

39+
class PictureLayer;
40+
class DisplayListLayer;
41+
class PerformanceOverlayLayer;
42+
class TextureLayer;
43+
3744
static constexpr SkRect kGiantRect = SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
3845

3946
// This should be an exact copy of the Clip enum in painting.dart.
4047
enum Clip { none, hardEdge, antiAlias, antiAliasWithSaveLayer };
4148

49+
struct RasterCacheEntry {
50+
explicit RasterCacheEntry(Layer* layer)
51+
: layer(layer), num_child_entries(0), need_caching(false) {}
52+
53+
Layer* layer;
54+
unsigned num_child_entries;
55+
bool need_caching;
56+
};
4257
struct PrerollContext {
4358
RasterCache* raster_cache;
4459
GrDirectContext* gr_context;
@@ -80,12 +95,9 @@ struct PrerollContext {
8095
// than to remember the value so that it can choose the right strategy
8196
// for its |Paint| method.
8297
bool subtree_can_inherit_opacity = false;
83-
};
8498

85-
class PictureLayer;
86-
class DisplayListLayer;
87-
class PerformanceOverlayLayer;
88-
class TextureLayer;
99+
std::vector<RasterCacheEntry> raster_cached_entries;
100+
};
89101

90102
// Represents a single composited layer. Created on the UI thread but then
91103
// subquently used on the Rasterizer thread.
@@ -105,9 +117,16 @@ class Layer {
105117
return original_layer_id_ == old_layer->original_layer_id_;
106118
}
107119

120+
virtual bool IsNeedCached(PrerollContext* context, const SkMatrix& ctm) {
121+
return false;
122+
}
123+
108124
// Performs diff with given layer
109125
virtual void Diff(DiffContext* context, const Layer* old_layer) {}
110126

127+
virtual void TryToPrepareRasterCache(PrerollContext* context,
128+
const SkMatrix& ctm);
129+
111130
// Used when diffing retained layer; In case the layer is identical, it
112131
// doesn't need to be diffed, but the paint region needs to be stored in diff
113132
// context so that it can be used in next frame
@@ -178,7 +197,7 @@ class Layer {
178197

179198
class AutoCachePaint {
180199
public:
181-
AutoCachePaint(PaintContext& context) : context_(context) {
200+
explicit AutoCachePaint(PaintContext& context) : context_(context) {
182201
needs_paint_ = context.inherited_opacity < SK_Scalar1;
183202
if (needs_paint_) {
184203
paint_.setAlphaf(context.inherited_opacity);
@@ -345,6 +364,9 @@ class Layer {
345364
uint64_t original_layer_id_;
346365
bool subtree_has_platform_view_;
347366
bool layer_can_inherit_opacity_;
367+
std::unordered_set<uint64_t> ancestors_ = {};
368+
369+
unsigned level_ = 0;
348370

349371
static uint64_t NextUniqueID();
350372

flow/layers/layer_tree.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66

77
#include "flutter/flow/frame_timings.h"
88
#include "flutter/flow/layers/layer.h"
9+
#include "flutter/flow/raster_cache.h"
910
#include "flutter/fml/time/time_point.h"
1011
#include "flutter/fml/trace_event.h"
12+
#include "include/core/SkMatrix.h"
1113
#include "third_party/skia/include/core/SkPictureRecorder.h"
1214
#include "third_party/skia/include/utils/SkNWayCanvas.h"
1315

@@ -52,9 +54,22 @@ bool LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
5254
device_pixel_ratio_};
5355

5456
root_layer_->Preroll(&context, frame.root_surface_transformation());
57+
58+
RasterCache(&context, frame.root_surface_transformation());
59+
5560
return context.surface_needs_readback;
5661
}
5762

63+
void LayerTree::RasterCache(PrerollContext* context, const SkMatrix& ctm) {
64+
for (unsigned i = 0; i < context->raster_cached_entries.size(); i++) {
65+
auto& entry = context->raster_cached_entries[i];
66+
if (entry.need_caching) {
67+
entry.layer->TryToPrepareRasterCache(context, ctm);
68+
i += entry.num_child_entries;
69+
}
70+
}
71+
}
72+
5873
void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
5974
bool ignore_raster_cache) const {
6075
TRACE_EVENT0("flutter", "LayerTree::Paint");

flow/layers/layer_tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class LayerTree {
3232
bool ignore_raster_cache = false,
3333
SkRect cull_rect = kGiantRect);
3434

35+
void RasterCache(PrerollContext* context, const SkMatrix& ctm);
36+
3537
void Paint(CompositorContext::ScopedFrame& frame,
3638
bool ignore_raster_cache = false) const;
3739

0 commit comments

Comments
 (0)