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

Commit 4157626

Browse files
committed
raster cache process analysis
1 parent 5d1fddc commit 4157626

11 files changed

+114
-83
lines changed

flow/layers/display_list_raster_cache_item.cc

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ DisplayListRasterCacheItem::DisplayListRasterCacheItem(
5252
bool will_change)
5353
: RasterCacheItem(RasterCacheKeyID(display_list->unique_id(),
5454
RasterCacheKeyType::kDisplayList),
55-
CacheState::kCurrent),
55+
CacheState::kNone),
5656
display_list_(display_list),
5757
offset_(offset),
5858
is_complex_(is_complex),
@@ -70,6 +70,9 @@ std::unique_ptr<DisplayListRasterCacheItem> DisplayListRasterCacheItem::Make(
7070
void DisplayListRasterCacheItem::PrerollSetup(PrerollContext* context,
7171
const SkMatrix& matrix) {
7272
cache_state_ = CacheState::kNone;
73+
if (!context->raster_cache->GenerateNewCacheInThisFrame()) {
74+
return;
75+
}
7376
DisplayListComplexityCalculator* complexity_calculator =
7477
context->gr_context ? DisplayListComplexityCalculator::GetForBackend(
7578
context->gr_context->backend())
@@ -81,18 +84,15 @@ void DisplayListRasterCacheItem::PrerollSetup(PrerollContext* context,
8184
return;
8285
}
8386

87+
matrix_ = matrix;
8488
transformation_matrix_ = matrix;
8589
transformation_matrix_.preTranslate(offset_.x(), offset_.y());
8690

8791
if (!transformation_matrix_.invert(nullptr)) {
8892
// The matrix was singular. No point in going further.
8993
return;
9094
}
91-
92-
if (context->raster_cached_entries && context->raster_cache) {
93-
context->raster_cached_entries->push_back(this);
94-
cache_state_ = CacheState::kCurrent;
95-
}
95+
cache_state_ = CacheState::kCurrent;
9696
return;
9797
}
9898

@@ -108,17 +108,32 @@ void DisplayListRasterCacheItem::PrerollFinalize(PrerollContext* context,
108108
// if the rect is intersect we will get the entry access_count to confirm if
109109
// it great than the threshold. Otherwise we only increase the entry
110110
// access_count.
111+
cache_state_ = CacheState::kNone;
111112
if (context->cull_rect.intersect(bounds)) {
112-
if (raster_cache->MarkSeen(key_id_, transformation_matrix_) <
113+
// Thought MarkDisplayListSeen we only get the access cout or create entry.
114+
// Don't increase the access_count or use_this_frame = true.
115+
if (raster_cache->MarkDisplayListSeen(key_id_, transformation_matrix_) <
113116
raster_cache->access_threshold()) {
114-
cache_state_ = CacheState::kNone;
115117
return;
116118
}
119+
// We need to make sure that we create a maximum of three images per frame.
120+
// This display_list can be cached and current entry doesn't create image,
121+
// so we should increate the cache count.
122+
if (!raster_cache->HasCached(key_id_, transformation_matrix_)) {
123+
context->raster_cache->IncreaseDisplayListCacheCount();
124+
cache_state_ = CacheState::kCurrent;
125+
}
117126
context->subtree_can_inherit_opacity = true;
118-
cache_state_ = CacheState::kCurrent;
119127
} else {
120-
raster_cache->Touch(key_id_, matrix);
128+
// if the bounds with the cull rect is not intersect, we only touch the
129+
// cache entry. And should not cache the display list
130+
if (!raster_cache->HasCached(key_id_, transformation_matrix_)) {
131+
raster_cache->Touch(key_id_, transformation_matrix_);
132+
}
133+
return;
121134
}
135+
// If the display_list can be cached we will add it to cache_entries.
136+
context->raster_cached_entries->push_back(this);
122137
return;
123138
}
124139

@@ -133,13 +148,8 @@ bool DisplayListRasterCacheItem::Draw(const PaintContext& context,
133148
if (!context.raster_cache || !canvas) {
134149
return false;
135150
}
136-
if (cache_state_ == CacheState::kCurrent) {
137-
return context.raster_cache->Draw(key_id_, *canvas, paint);
138-
}
139-
// This display_list doesn't cache itself, this only increase the entry
140-
// access_count;
141-
context.raster_cache->Touch(key_id_, canvas->getTotalMatrix());
142-
return false;
151+
152+
return context.raster_cache->Draw(key_id_, *canvas, paint);
143153
}
144154

145155
static const auto* flow_type = "RasterCacheFlow::DisplayList";
@@ -153,11 +163,12 @@ bool DisplayListRasterCacheItem::TryToPrepareRasterCache(
153163
// display_list or picture_list to calculate the memory they used, we
154164
// shouldn't cache the current node if the memory is more significant than the
155165
// limit.
156-
if (cache_state_ == kNone || !context.raster_cache || parent_cached ||
157-
!context.raster_cache->GenerateNewCacheInThisFrame()) {
166+
if (cache_state_ == CacheState::kNone || !context.raster_cache ||
167+
parent_cached) {
158168
return false;
159169
}
160-
SkRect bounds = display_list_->bounds().makeOffset(offset_.x(), offset_.y());
170+
171+
SkRect bounds = display_list_->bounds();
161172
RasterCache::Context r_context = {
162173
// clang-format off
163174
.gr_context = context.gr_context,
@@ -169,9 +180,9 @@ bool DisplayListRasterCacheItem::TryToPrepareRasterCache(
169180
// clang-format on
170181
};
171182
return context.raster_cache->UpdateCacheEntry(
172-
GetId().value(), r_context,
173-
[display_list = display_list_](SkCanvas* canvas) {
183+
key_id_, r_context, [display_list = display_list_](SkCanvas* canvas) {
174184
display_list->RenderTo(canvas);
185+
return true;
175186
});
176187
}
177188
} // namespace flutter

flow/layers/display_list_raster_cache_item.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DisplayListRasterCacheItem : public RasterCacheItem {
4545
const SkPaint* paint) const override;
4646

4747
bool TryToPrepareRasterCache(const PaintContext& context,
48-
bool parent_cached = false) const override;
48+
bool parent_cached) const override;
4949

5050
void ModifyMatrix(SkPoint offset) const {
5151
matrix_ = matrix_.preTranslate(offset.x(), offset.y());

flow/layers/layer_raster_cache_item.cc

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,11 @@ void LayerRasterCacheItem::PrerollFinalize(PrerollContext* context,
4242
if (!context->raster_cache || !context->raster_cached_entries) {
4343
return;
4444
}
45-
// We've marked the cache entry that we would like to cache so it stays
46-
// alive, but if the following conditions apply then we need to set our
47-
// state back to kDoNotCache so that we don't populate the entry later.
48-
if (context->has_platform_view || context->has_texture_layer ||
49-
!SkRect::Intersects(context->cull_rect, layer_->paint_bounds())) {
50-
return;
51-
}
5245
child_items_ = context->raster_cached_entries->size() - child_items_;
46+
// Determine cache current layer or cache children.
5347
if (num_cache_attempts_ >= layer_cached_threshold_) {
5448
// the layer can be cached
5549
cache_state_ = CacheState::kCurrent;
56-
context->raster_cache->MarkSeen(key_id_, matrix_);
5750
} else {
5851
num_cache_attempts_++;
5952
// access current layer
@@ -67,9 +60,25 @@ void LayerRasterCacheItem::PrerollFinalize(PrerollContext* context,
6760
RasterCacheKeyType::kLayerChildren);
6861
}
6962
cache_state_ = CacheState::kChildren;
70-
context->raster_cache->MarkSeen(layer_children_id_.value(), matrix_);
7163
}
7264
}
65+
// We've marked the cache entry that we would like to cache so it stays
66+
// alive, but if the following conditions apply then we need to set our
67+
// state back to kDoNotCache so that we don't populate the entry later.
68+
if (context->has_platform_view || context->has_texture_layer ||
69+
!SkRect::Intersects(context->cull_rect, layer_->paint_bounds())) {
70+
if (cache_state_ != CacheState::kNone) {
71+
// Only touch the entry, do not to cache the layer or children.
72+
context->raster_cache->Touch(GetId().value(), matrix_);
73+
cache_state_ = CacheState::kNone;
74+
}
75+
return;
76+
}
77+
// The layer can be cache, so we should create a entry.
78+
if (cache_state_ != CacheState::kNone) {
79+
// Create Cache entry
80+
context->raster_cache->MarkSeen(GetId().value(), matrix_);
81+
}
7382
}
7483

7584
std::optional<RasterCacheKeyID> LayerRasterCacheItem::GetId() const {
@@ -111,19 +120,20 @@ bool Rasterize(RasterCacheItem::CacheState cache_state,
111120
.leaf_nodes_canvas = canvas,
112121
.gr_context = paint_context.gr_context,
113122
.dst_color_space = paint_context.dst_color_space,
114-
.view_embedder = paint_context.view_embedder,
123+
.view_embedder = nullptr,
115124
.raster_time = paint_context.raster_time,
116125
.ui_time = paint_context.ui_time,
117126
.texture_registry = paint_context.texture_registry,
118-
.raster_cache = paint_context.raster_cache,
127+
.raster_cache = layer->subtree_has_platform_view() ? nullptr: paint_context.raster_cache,
119128
.checkerboard_offscreen_layers = paint_context.checkerboard_offscreen_layers,
120129
.frame_device_pixel_ratio = paint_context.frame_device_pixel_ratio,
121130
// clang-format on
122131
};
123-
124132
switch (cache_state) {
125133
case RasterCacheItem::CacheState::kCurrent:
126-
FML_DCHECK(layer->needs_painting(context));
134+
if (!layer->needs_painting(context)) {
135+
return false;
136+
}
127137
layer->Paint(context);
128138
break;
129139
case RasterCacheItem::CacheState::kChildren:
@@ -140,7 +150,11 @@ static const auto* flow_type = "RasterCacheFlow::Layer";
140150

141151
bool LayerRasterCacheItem::TryToPrepareRasterCache(const PaintContext& context,
142152
bool parent_cached) const {
143-
if (!context.raster_cache || parent_cached) {
153+
if (!context.raster_cache) {
154+
return false;
155+
}
156+
if (parent_cached) {
157+
context.raster_cache->Touch(GetId().value(), matrix_);
144158
return false;
145159
}
146160
if (cache_state_ != kNone) {
@@ -159,7 +173,7 @@ bool LayerRasterCacheItem::TryToPrepareRasterCache(const PaintContext& context,
159173
GetId().value(), r_context,
160174
[ctx = context, cache_state = cache_state_,
161175
layer = layer_](SkCanvas* canvas) {
162-
Rasterize(cache_state, layer, ctx, canvas);
176+
return Rasterize(cache_state, layer, ctx, canvas);
163177
});
164178
}
165179
}
@@ -174,20 +188,10 @@ bool LayerRasterCacheItem::Draw(const PaintContext& context,
174188
bool LayerRasterCacheItem::Draw(const PaintContext& context,
175189
SkCanvas* canvas,
176190
const SkPaint* paint) const {
177-
if (!context.raster_cache || !canvas) {
191+
if (!context.raster_cache || !canvas || cache_state_ == CacheState::kNone) {
178192
return false;
179193
}
180-
switch (cache_state_) {
181-
case RasterCacheItem::kNone:
182-
return false;
183-
case RasterCacheItem::kCurrent: {
184-
return context.raster_cache->Draw(key_id_, *canvas, paint);
185-
}
186-
case RasterCacheItem::kChildren: {
187-
return context.raster_cache->Draw(layer_children_id_.value(), *canvas,
188-
paint);
189-
}
190-
}
194+
return context.raster_cache->Draw(GetId().value(), *canvas, paint);
191195
}
192196

193197
} // namespace flutter

flow/layers/layer_raster_cache_item.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class LayerRasterCacheItem : public RasterCacheItem {
4343
const SkPaint* paint) const override;
4444

4545
bool TryToPrepareRasterCache(const PaintContext& context,
46-
bool parent_cached = false) const override;
46+
bool parent_cached) const override;
4747

4848
void MarkCacheChildren() { can_cache_children_ = true; }
4949

flow/raster_cache.cc

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ RasterCache::RasterCache(size_t access_threshold,
5151
/// @note Procedure doesn't copy all closures.
5252
std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
5353
const RasterCache::Context& context,
54-
const std::function<void(SkCanvas*)>& draw_function) {
54+
const std::function<bool(SkCanvas*)>& draw_function) {
5555
TRACE_EVENT0("flutter", "RasterCachePopulate");
5656

5757
SkRect dest_rect =
@@ -76,7 +76,10 @@ std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
7676
canvas->clear(SK_ColorTRANSPARENT);
7777
canvas->translate(-dest_rect.left(), -dest_rect.top());
7878
canvas->concat(context.matrix);
79-
draw_function(canvas);
79+
80+
if (!draw_function(canvas)) {
81+
return nullptr;
82+
}
8083

8184
if (context.checkerboard) {
8285
DrawCheckerboard(canvas, context.logical_rect);
@@ -89,23 +92,12 @@ std::unique_ptr<RasterCacheResult> RasterCache::Rasterize(
8992
bool RasterCache::UpdateCacheEntry(
9093
const RasterCacheKeyID& id,
9194
const Context& raster_cache_context,
92-
const std::function<void(SkCanvas*)>& render_function) const {
95+
const std::function<bool(SkCanvas*)>& render_function) const {
9396
RasterCacheKey key = RasterCacheKey(id, raster_cache_context.matrix);
9497
Entry& entry = cache_[key];
9598
entry.used_this_frame = true;
9699
if (!entry.image) {
97100
entry.image = Rasterize(raster_cache_context, render_function);
98-
if (entry.image != nullptr) {
99-
switch (id.type()) {
100-
case RasterCacheKeyType::kDisplayList: {
101-
display_list_cached_this_frame_++;
102-
break;
103-
}
104-
default:
105-
break;
106-
}
107-
return true;
108-
}
109101
}
110102
return entry.image != nullptr;
111103
}
@@ -130,6 +122,13 @@ int RasterCache::MarkSeen(const RasterCacheKeyID& id,
130122
return entry.access_count;
131123
}
132124

125+
int RasterCache::MarkDisplayListSeen(const RasterCacheKeyID& id,
126+
const SkMatrix& matrix) const {
127+
RasterCacheKey key = RasterCacheKey(id, matrix);
128+
Entry& entry = cache_[key];
129+
return entry.access_count;
130+
}
131+
133132
bool RasterCache::HasEntry(const RasterCacheKeyID& id,
134133
const SkMatrix& matrix) const {
135134
RasterCacheKey key = RasterCacheKey(id, matrix);
@@ -139,6 +138,16 @@ bool RasterCache::HasEntry(const RasterCacheKeyID& id,
139138
return false;
140139
}
141140

141+
bool RasterCache::HasCached(const RasterCacheKeyID& id,
142+
const SkMatrix& matrix) const {
143+
RasterCacheKey key = RasterCacheKey(id, matrix);
144+
auto it = cache_.find(key);
145+
if (it != cache_.end()) {
146+
return it->second.image != nullptr;
147+
}
148+
return false;
149+
}
150+
142151
bool RasterCache::Draw(const RasterCacheKeyID& id,
143152
SkCanvas& canvas,
144153
const SkPaint* paint) const {

flow/raster_cache.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class RasterCache {
105105

106106
static std::unique_ptr<RasterCacheResult> Rasterize(
107107
const RasterCache::Context& context,
108-
const std::function<void(SkCanvas*)>& draw_function);
108+
const std::function<bool(SkCanvas*)>& draw_function);
109109

110110
explicit RasterCache(
111111
size_t access_threshold = 3,
@@ -123,6 +123,8 @@ class RasterCache {
123123
SkCanvas& canvas,
124124
const SkPaint* paint) const;
125125

126+
void IncreaseDisplayListCacheCount() { display_list_cached_this_frame_++; }
127+
126128
bool Touch(const RasterCacheKeyID& id, const SkMatrix& matrix) const;
127129

128130
bool HasEntry(const RasterCacheKeyID& id, const SkMatrix&) const;
@@ -198,11 +200,15 @@ class RasterCache {
198200
* a new entry that will be 1.
199201
*/
200202
int MarkSeen(const RasterCacheKeyID& id, const SkMatrix& matrix) const;
203+
int MarkDisplayListSeen(const RasterCacheKeyID& id,
204+
const SkMatrix& matrix) const;
205+
206+
bool HasCached(const RasterCacheKeyID& id, const SkMatrix& matrix) const;
201207

202208
bool UpdateCacheEntry(
203209
const RasterCacheKeyID& id,
204210
const Context& raster_cache_context,
205-
const std::function<void(SkCanvas*)>& render_function) const;
211+
const std::function<bool(SkCanvas*)>& render_function) const;
206212

207213
private:
208214
struct Entry {

flow/raster_cache_item.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class RasterCacheItem {
5555
virtual std::optional<RasterCacheKeyID> GetId() const { return key_id_; }
5656

5757
virtual bool TryToPrepareRasterCache(const PaintContext& context,
58-
bool parent_cached = false) const = 0;
58+
bool parent_cached) const = 0;
5959

6060
unsigned child_items() const { return child_items_; }
6161

flow/raster_cache_key.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class RasterCacheKeyID {
2525
RasterCacheKeyID(uint16_t id, RasterCacheKeyType type)
2626
: ids_({id}), type_(type) {}
2727

28-
RasterCacheKeyID(const std::vector<uint64_t> ids, RasterCacheKeyType type)
28+
RasterCacheKeyID(const std::vector<uint64_t>& ids, RasterCacheKeyType type)
2929
: ids_(ids), type_(type) {}
3030

3131
const std::vector<uint64_t>& ids() const { return ids_; }

flow/raster_cache_unittests.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ TEST(RasterCache, AccessThresholdOfZeroDisablesCachingForSkPicture) {
127127
SkMatrix matrix = SkMatrix::I();
128128

129129
auto display_list = GetSampleDisplayList();
130-
;
131130

132131
SkCanvas dummy_canvas;
133132
SkPaint paint;

0 commit comments

Comments
 (0)