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

Commit 0c52ffe

Browse files
committed
DisplayList cache threshold; CacheLayer change to a interface;
1 parent d728981 commit 0c52ffe

16 files changed

+255
-183
lines changed

flow/layers/cacheable_layer.h

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
#ifndef FLUTTER_FLOW_LAYERS_CACHEABL_LAYER_H_
6-
#define FLUTTER_FLOW_LAYERS_CACHEABL_LAYER_H_
5+
#ifndef FLUTTER_FLOW_LAYERS_CACHEABLE_LAYER_H_
6+
#define FLUTTER_FLOW_LAYERS_CACHEABLE_LAYER_H_
77

88
#include <memory>
99
#include "flutter/flow/embedded_views.h"
@@ -14,21 +14,89 @@
1414

1515
namespace flutter {
1616

17-
class CacheableLayer : public Layer {
17+
class Cacheable {
1818
public:
19+
Cacheable() = default;
20+
1921
enum class CacheType { kNone, kCurrent, kChildren };
2022

21-
virtual void TryToPrepareRasterCache(
23+
class AutoCache {
24+
public:
25+
static AutoCache Create(Cacheable* cacheable,
26+
PrerollContext* context,
27+
const SkMatrix& matrix) {
28+
return AutoCache(cacheable, context, matrix);
29+
}
30+
31+
~AutoCache() {
32+
cacheable_entry_->num_child_entries =
33+
context_->raster_cached_entries.size() - current_index_;
34+
// Get current layer's cache type
35+
auto cache_type = layer_->NeedCaching(context_, matrix_);
36+
// we should modify some parmas of the entry, like need_cache or matrix
37+
layer_->ConfigCacheType(cacheable_entry_, cache_type);
38+
cacheable_entry_->has_platform_view = context_->has_platform_view;
39+
cacheable_entry_->has_texture_layer = context_->has_texture_layer;
40+
}
41+
42+
private:
43+
AutoCache(Cacheable* cacheable,
44+
PrerollContext* context,
45+
const SkMatrix& matrix)
46+
: layer_(cacheable), context_(context), matrix_(matrix) {
47+
cacheable_entry_ =
48+
context_->raster_cached_entries
49+
.emplace_back(RasterCacheableEntry::MarkLayerCacheable(
50+
layer_, *context_, matrix_))
51+
.get();
52+
current_index_ = context_->raster_cached_entries.size();
53+
}
54+
55+
int current_index_;
56+
RasterCacheableEntry* cacheable_entry_ = nullptr;
57+
Cacheable* layer_ = nullptr;
58+
PrerollContext* context_ = nullptr;
59+
const SkMatrix& matrix_;
60+
};
61+
62+
void TryToPrepareRasterCache(
63+
Layer* layer,
2264
PrerollContext* context,
2365
const SkMatrix& matrix,
24-
RasterCacheLayerStrategy strategy = RasterCacheLayerStrategy::kLayer) {}
66+
RasterCacheLayerStrategy strategy = RasterCacheLayerStrategy::kLayer) {
67+
if (context->raster_cache) {
68+
if (!context->has_platform_view && !context->has_texture_layer &&
69+
SkRect::Intersects(context->cull_rect, layer->paint_bounds())) {
70+
context->raster_cache->Prepare(context, layer, matrix, strategy);
71+
} else {
72+
// Don't evict raster cache entry during partial repaint
73+
context->raster_cache->Touch(layer, matrix, strategy);
74+
}
75+
}
76+
}
77+
78+
virtual Layer* asLayer() = 0;
2579

2680
virtual CacheType NeedCaching(PrerollContext* context,
2781
const SkMatrix& ctm) = 0;
2882

29-
virtual ~CacheableLayer() = default;
83+
// Usually, we have this case to do:
84+
// 1. CacheType::kNone, which mean we don't need to cache this layer, so we
85+
// set the entry's need_caching to false
86+
// 2. CacheType::kChildren, which mean we need to cache the layer's children,
87+
// so we mark children need cache
88+
virtual void ConfigCacheType(RasterCacheableEntry* entry, CacheType type) {
89+
if (type == Cacheable::CacheType::kNone) {
90+
entry->need_caching = false;
91+
} else if (type == Cacheable::CacheType::kChildren) {
92+
// Replace Cacheable child
93+
entry->MarkLayerChildrenNeedCached();
94+
}
95+
}
96+
97+
virtual ~Cacheable() = default;
3098
};
3199

32100
} // namespace flutter
33101

34-
#endif // FLUTTER_FLOW_LAYERS_CACHEABL_LAYER_H_
102+
#endif // FLUTTER_FLOW_LAYERS_CACHEABLE_LAYER_H_

flow/layers/color_filter_layer.cc

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,18 @@ void ColorFilterLayer::Preroll(PrerollContext* context,
2929
const SkMatrix& matrix) {
3030
Layer::AutoPrerollSaveLayerState save =
3131
Layer::AutoPrerollSaveLayerState::Create(context);
32-
auto cacheable_entry =
33-
RasterCacheableEntry::MarkLayerCacheable(this, *context, matrix);
34-
context->raster_cached_entries.push_back(cacheable_entry);
35-
36-
auto current_index = context->raster_cached_entries.size();
32+
Cacheable::AutoCache::Create(this, context, matrix);
3733

3834
ContainerLayer::Preroll(context, matrix);
39-
40-
cacheable_entry->num_child_entries =
41-
context->raster_cached_entries.size() - current_index;
42-
auto cache_type = NeedCaching(context, matrix);
43-
if (cache_type == CacheableLayer::CacheType::kChildren) {
44-
cacheable_entry->MarkLayerChildrenNeedCached();
45-
}
4635
}
4736

48-
CacheableLayer::CacheType ColorFilterLayer::NeedCaching(PrerollContext* context,
49-
const SkMatrix& ctm) {
37+
Cacheable::CacheType ColorFilterLayer::NeedCaching(PrerollContext* context,
38+
const SkMatrix& ctm) {
5039
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
51-
return CacheableLayer::CacheType::kCurrent;
40+
return Cacheable::CacheType::kCurrent;
5241
} else {
5342
render_count_++;
54-
return CacheableLayer::CacheType::kChildren;
43+
return Cacheable::CacheType::kChildren;
5544
}
5645
}
5746

flow/layers/color_filter_layer.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
#ifndef FLUTTER_FLOW_LAYERS_COLOR_FILTER_LAYER_H_
66
#define FLUTTER_FLOW_LAYERS_COLOR_FILTER_LAYER_H_
77

8+
#include "flutter/flow/layers/cacheable_layer.h"
89
#include "flutter/flow/layers/container_layer.h"
10+
#include "flutter/flow/raster_cacheable_entry.h"
911
#include "third_party/skia/include/core/SkColorFilter.h"
10-
1112
namespace flutter {
1213

13-
class ColorFilterLayer : public ContainerLayer {
14+
class ColorFilterLayer : public ContainerLayer, public Cacheable {
1415
public:
1516
explicit ColorFilterLayer(sk_sp<SkColorFilter> filter);
1617

@@ -20,8 +21,10 @@ class ColorFilterLayer : public ContainerLayer {
2021

2122
void Paint(PaintContext& context) const override;
2223

23-
CacheableLayer::CacheType NeedCaching(PrerollContext* context,
24-
const SkMatrix& ctm) override;
24+
Cacheable::CacheType NeedCaching(PrerollContext* context,
25+
const SkMatrix& ctm) override;
26+
27+
Layer* asLayer() override { return this; }
2528

2629
private:
2730
sk_sp<SkColorFilter> filter_;

flow/layers/container_layer.cc

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,4 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {
189189
}
190190
}
191191

192-
void ContainerLayer::TryToPrepareRasterCache(
193-
PrerollContext* context,
194-
const SkMatrix& matrix,
195-
RasterCacheLayerStrategy strategy) {
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, matrix, strategy);
200-
} else if (context->raster_cache) {
201-
// Don't evict raster cache entry during partial repaint
202-
context->raster_cache->Touch(this, matrix, strategy);
203-
}
204-
}
205-
206192
} // namespace flutter

flow/layers/container_layer.h

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
#define FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
77

88
#include <vector>
9+
#include "flutter/flow/layers/layer.h"
910

10-
#include "flutter/flow/layers/cacheable_layer.h"
1111
namespace flutter {
1212

13-
class ContainerLayer : public CacheableLayer {
13+
class ContainerLayer : public Layer {
1414
public:
1515
ContainerLayer();
1616

@@ -26,31 +26,13 @@ class ContainerLayer : public CacheableLayer {
2626

2727
virtual void DiffChildren(DiffContext* context,
2828
const ContainerLayer* old_layer);
29+
2930
void PaintChildren(PaintContext& context) const;
31+
3032
const ContainerLayer* as_container_layer() const override { return this; }
3133

3234
const SkRect& child_paint_bounds() const { return child_paint_bounds_; }
3335

34-
CacheableLayer::CacheType NeedCaching(PrerollContext* context,
35-
const SkMatrix& ctm) override {
36-
return CacheableLayer::CacheType::kNone;
37-
}
38-
39-
// Try to prepare the raster cache for a given layer.
40-
//
41-
// The raster cache would fail if either of the followings is true:
42-
// 1. The context has a platform view.
43-
// 2. The context does not have a valid raster cache.
44-
// 3. The layer's paint bounds does not intersect with the cull rect.
45-
//
46-
// We make this a static function instead of a member function that directly
47-
// uses the "this" pointer as the layer because we sometimes need to raster
48-
// cache a child layer and one can't access its child's protected method.
49-
void TryToPrepareRasterCache(PrerollContext* context,
50-
const SkMatrix& matrix,
51-
RasterCacheLayerStrategy strategy =
52-
RasterCacheLayerStrategy::kLayer) override;
53-
5436
protected:
5537
void PrerollChildren(PrerollContext* context,
5638
const SkMatrix& child_matrix,

flow/layers/display_list_layer.cc

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,28 +92,35 @@ bool DisplayListLayer::Compare(DiffContext::Statistics& statistics,
9292
void DisplayListLayer::Preroll(PrerollContext* context,
9393
const SkMatrix& matrix) {
9494
TRACE_EVENT0("flutter", "DisplayListLayer::Preroll");
95-
auto cacheable_entry = RasterCacheableEntry::MarkDisplayListCacheable(
96-
this->display_list(), *context, matrix, offset_);
97-
context->raster_cached_entries.push_back(cacheable_entry);
95+
auto& cacheable_entry = context->raster_cached_entries.emplace_back(
96+
RasterCacheableEntry::MarkDisplayListCacheable(
97+
this->display_list(), *context, matrix, offset_));
98+
99+
DisplayList* disp_list = display_list();
100+
SkRect bounds = disp_list->bounds().makeOffset(offset_.x(), offset_.y());
101+
set_paint_bounds(bounds);
102+
98103
cacheable_entry->need_caching = NeedCaching(context, matrix);
99104
}
100105

101106
bool DisplayListLayer::NeedCaching(PrerollContext* context,
102107
const SkMatrix& ctm) {
103-
DisplayList* disp_list = display_list();
104-
SkRect bounds = disp_list->bounds().makeOffset(offset_.x(), offset_.y());
105-
set_paint_bounds(bounds);
106108
if (auto* cache = context->raster_cache) {
107109
TRACE_EVENT0("flutter", "DisplayListLayer::RasterCache (Preroll)");
108110
// For display_list_layer if the context has raster_cache, we will try to
109111
// collection it when we raster cache it, we will to decision Prepare or
110112
// Touch cache
111-
if (context->cull_rect.intersect(bounds) &&
112-
cache->ShouldBeCached(context, disp_list, is_complex_, will_change_,
113-
ctm)) {
114-
// if current Layer can be cached, we change the
115-
// subtree_can_inherit_opacity to true
116-
context->subtree_can_inherit_opacity = true;
113+
if (context->cull_rect.intersect(paint_bounds())) {
114+
if (cache->ShouldBeCached(context, display_list(), is_complex_,
115+
will_change_, ctm)) {
116+
SkMatrix transformation_matrix = ctm;
117+
transformation_matrix.preTranslate(offset_.x(), offset_.y());
118+
119+
context->raster_cached_entries.back()->matrix = transformation_matrix;
120+
// if current Layer can be cached, we change the
121+
// subtree_can_inherit_opacity to true
122+
context->subtree_can_inherit_opacity = true;
123+
}
117124
}
118125
return true;
119126
}

flow/layers/image_filter_layer.cc

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "flutter/flow/layers/image_filter_layer.h"
66
#include "flutter/flow/layers/layer.h"
7+
#include "flutter/flow/raster_cacheable_entry.h"
78

89
namespace flutter {
910

@@ -44,24 +45,11 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
4445
Layer::AutoPrerollSaveLayerState save =
4546
Layer::AutoPrerollSaveLayerState::Create(context);
4647

47-
auto cacheable_entry =
48-
RasterCacheableEntry::MarkLayerCacheable(this, *context, matrix);
49-
context->raster_cached_entries.emplace_back(cacheable_entry);
50-
auto current_index = context->raster_cached_entries.size();
48+
Cacheable::AutoCache::Create(this, context, matrix);
5149

5250
SkRect child_bounds = SkRect::MakeEmpty();
5351
PrerollChildren(context, matrix, &child_bounds);
5452

55-
cacheable_entry->num_child_entries =
56-
context->raster_cached_entries.size() - current_index;
57-
auto cache_type = NeedCaching(context, matrix);
58-
if (cache_type == CacheableLayer::CacheType::kNone) {
59-
cacheable_entry->need_caching = false;
60-
} else if (cache_type == CacheableLayer::CacheType::kChildren) {
61-
// Replace Cacheable child
62-
cacheable_entry->MarkLayerChildrenNeedCached();
63-
}
64-
6553
if (!filter_) {
6654
set_paint_bounds(child_bounds);
6755
return;
@@ -75,10 +63,10 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
7563
set_paint_bounds(child_bounds);
7664
}
7765

78-
CacheableLayer::CacheType ImageFilterLayer::NeedCaching(PrerollContext* context,
79-
const SkMatrix& ctm) {
66+
Cacheable::CacheType ImageFilterLayer::NeedCaching(PrerollContext* context,
67+
const SkMatrix& ctm) {
8068
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
81-
return CacheableLayer::CacheType::kCurrent;
69+
return Cacheable::CacheType::kCurrent;
8270
}
8371
transformed_filter_ = nullptr;
8472
// This ImageFilterLayer is not yet considered stable so we
@@ -100,9 +88,9 @@ CacheableLayer::CacheType ImageFilterLayer::NeedCaching(PrerollContext* context,
10088
// stable between frames and also avoiding a rendering surface
10189
// switch during the Paint phase even if they are not stable.
10290
// This benefit is seen most during animations.
103-
return CacheableLayer::CacheType::kChildren;
91+
return Cacheable::CacheType::kChildren;
10492
}
105-
return CacheableLayer::CacheType::kNone;
93+
return Cacheable::CacheType::kNone;
10694
}
10795

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

flow/layers/image_filter_layer.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
#include "flutter/flow/layers/cacheable_layer.h"
99
#include "flutter/flow/layers/container_layer.h"
10+
#include "flutter/flow/raster_cacheable_entry.h"
1011
#include "third_party/skia/include/core/SkImageFilter.h"
1112

1213
namespace flutter {
1314

14-
class ImageFilterLayer : public ContainerLayer {
15+
class ImageFilterLayer : public ContainerLayer, public Cacheable {
1516
public:
1617
explicit ImageFilterLayer(sk_sp<SkImageFilter> filter);
1718

@@ -21,8 +22,10 @@ class ImageFilterLayer : public ContainerLayer {
2122

2223
void Paint(PaintContext& context) const override;
2324

24-
CacheableLayer::CacheType NeedCaching(PrerollContext* context,
25-
const SkMatrix& ctm) override;
25+
Cacheable::CacheType NeedCaching(PrerollContext* context,
26+
const SkMatrix& ctm) override;
27+
28+
Layer* asLayer() override { return this; }
2629

2730
private:
2831
// The ImageFilterLayer might cache the filtered output of this layer

0 commit comments

Comments
 (0)