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

Commit 36d70fd

Browse files
committed
Collection Need RasterCache Layer in Preroll
1 parent bff7d76 commit 36d70fd

File tree

7 files changed

+115
-7
lines changed

7 files changed

+115
-7
lines changed

flow/layers/container_layer.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ void ContainerLayer::DiffChildren(DiffContext* context,
104104
}
105105

106106
void ContainerLayer::Add(std::shared_ptr<Layer> layer) {
107+
layer->SetLevel(level() + 1);
108+
layer->SetAncestors(GetAncestors());
109+
layer->AddAncestor(unique_id());
107110
layers_.emplace_back(std::move(layer));
108111
}
109112

@@ -188,6 +191,18 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {
188191
}
189192
}
190193

194+
void ContainerLayer::TryToPrepareRasterCache(PrerollContext* context,
195+
const SkMatrix& ctm) {
196+
if (!context->has_platform_view && !context->has_texture_layer &&
197+
context->raster_cache &&
198+
SkRect::Intersects(context->cull_rect, this->paint_bounds())) {
199+
context->raster_cache->Prepare(context, this, ctm);
200+
} else if (context->raster_cache) {
201+
// Don't evict raster cache entry during partial repaint
202+
context->raster_cache->Touch(this, ctm);
203+
}
204+
}
205+
191206
void ContainerLayer::TryToPrepareRasterCache(PrerollContext* context,
192207
Layer* layer,
193208
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: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
4242
Layer::AutoPrerollSaveLayerState save =
4343
Layer::AutoPrerollSaveLayerState::Create(context);
4444

45+
AutoGatherLayers raster_cache_layers(context->raster_cached_layers);
46+
4547
SkRect child_bounds = SkRect::MakeEmpty();
4648
PrerollChildren(context, matrix, &child_bounds);
4749

@@ -63,7 +65,8 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
6365
// times to consider its properties and children to be stable
6466
// from frame to frame so we try to cache the layer itself
6567
// for maximum performance.
66-
TryToPrepareRasterCache(context, this, matrix);
68+
// TryToPrepareRasterCache(context, this, matrix);
69+
raster_cache_layers.SetCurrentLayer(this);
6770
} else {
6871
// This ImageFilterLayer is not yet considered stable so we
6972
// increment the count to measure how many times it has been
@@ -84,7 +87,8 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
8487
// stable between frames and also avoiding a rendering surface
8588
// switch during the Paint phase even if they are not stable.
8689
// This benefit is seen most during animations.
87-
TryToPrepareRasterCache(context, GetCacheableChild(), matrix);
90+
// TryToPrepareRasterCache(context, GetCacheableChild(), matrix);
91+
raster_cache_layers.SetCurrentLayer(GetCacheableChild());
8892
}
8993
}
9094
}

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: 53 additions & 5 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,6 +36,11 @@ 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.
@@ -80,12 +87,32 @@ struct PrerollContext {
8087
// than to remember the value so that it can choose the right strategy
8188
// for its |Paint| method.
8289
bool subtree_can_inherit_opacity = false;
90+
91+
std::vector<Layer*> raster_cached_layers;
8392
};
8493

85-
class PictureLayer;
86-
class DisplayListLayer;
87-
class PerformanceOverlayLayer;
88-
class TextureLayer;
94+
class AutoGatherLayers {
95+
public:
96+
explicit AutoGatherLayers(std::vector<Layer*>& layers)
97+
: current_layer_(nullptr),
98+
layers_(layers),
99+
initial_size_(layers.size()) {}
100+
101+
void SetCurrentLayer(Layer* current_layer) { current_layer_ = current_layer; }
102+
103+
~AutoGatherLayers() {
104+
if (current_layer_) {
105+
layers_.resize(
106+
initial_size_); // remove all child layers added in the meanwhile
107+
layers_.push_back(current_layer_);
108+
}
109+
}
110+
111+
private:
112+
Layer* current_layer_;
113+
std::vector<Layer*>& layers_;
114+
size_t initial_size_;
115+
};
89116

90117
// Represents a single composited layer. Created on the UI thread but then
91118
// subquently used on the Rasterizer thread.
@@ -108,6 +135,9 @@ class Layer {
108135
// Performs diff with given layer
109136
virtual void Diff(DiffContext* context, const Layer* old_layer) {}
110137

138+
virtual void TryToPrepareRasterCache(PrerollContext* context,
139+
const SkMatrix& ctm);
140+
111141
// Used when diffing retained layer; In case the layer is identical, it
112142
// doesn't need to be diffed, but the paint region needs to be stored in diff
113143
// context so that it can be used in next frame
@@ -178,7 +208,7 @@ class Layer {
178208

179209
class AutoCachePaint {
180210
public:
181-
AutoCachePaint(PaintContext& context) : context_(context) {
211+
explicit AutoCachePaint(PaintContext& context) : context_(context) {
182212
needs_paint_ = context.inherited_opacity < SK_Scalar1;
183213
if (needs_paint_) {
184214
paint_.setAlphaf(context.inherited_opacity);
@@ -329,6 +359,21 @@ class Layer {
329359

330360
uint64_t unique_id() const { return unique_id_; }
331361

362+
void SetLevel(unsigned value) { level_ = value; }
363+
unsigned level() const { return level_; }
364+
365+
void SetAncestors(const std::unordered_set<uint64_t>& ancestors) {
366+
ancestors_ = ancestors;
367+
}
368+
369+
void AddAncestor(uint64_t id) { ancestors_.insert(id); }
370+
371+
const std::unordered_set<uint64_t> GetAncestors() const { return ancestors_; }
372+
373+
bool HasAncestor(uint64_t id) {
374+
return ancestors_.find(id) != ancestors_.end();
375+
}
376+
332377
virtual const PictureLayer* as_picture_layer() const { return nullptr; }
333378
virtual const DisplayListLayer* as_display_list_layer() const {
334379
return nullptr;
@@ -345,6 +390,9 @@ class Layer {
345390
uint64_t original_layer_id_;
346391
bool subtree_has_platform_view_;
347392
bool layer_can_inherit_opacity_;
393+
std::unordered_set<uint64_t> ancestors_ = {};
394+
395+
unsigned level_ = 0;
348396

349397
static uint64_t NextUniqueID();
350398

flow/layers/layer_tree.cc

Lines changed: 30 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,37 @@ 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+
auto& need_raster_cache_layers = context->raster_cached_layers;
65+
std::sort(
66+
need_raster_cache_layers.begin(), need_raster_cache_layers.end(),
67+
[](const Layer* a, const Layer* b) { return a->level() < b->level(); });
68+
69+
const int length = need_raster_cache_layers.size();
70+
for (int i = 0; i < length; i++) {
71+
auto* current_layer = need_raster_cache_layers[i];
72+
// check the ancestor has raster cached
73+
bool current_layer_need_raster_cache = true;
74+
for (int j = i - 1; j >= 0; j--) {
75+
auto* low_level_layer = need_raster_cache_layers[j];
76+
// if the ancestor also need raster cache, skip current layer
77+
if (current_layer->HasAncestor(low_level_layer->unique_id())) {
78+
current_layer_need_raster_cache = false;
79+
break;
80+
}
81+
}
82+
if (current_layer_need_raster_cache) {
83+
current_layer->TryToPrepareRasterCache(context, ctm);
84+
}
85+
}
86+
}
87+
5888
void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
5989
bool ignore_raster_cache) const {
6090
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)