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

Commit f064fb5

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

10 files changed

+126
-86
lines changed

flow/layers/display_list_raster_cache_item.cc

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "flutter/flow/raster_cache_key.h"
1515
#include "flutter/flow/raster_cache_util.h"
1616
#include "flutter/flow/skia_gpu_object.h"
17+
#include "flutter/shell/common/pipeline.h"
1718

1819
namespace flutter {
1920

@@ -52,7 +53,7 @@ DisplayListRasterCacheItem::DisplayListRasterCacheItem(
5253
bool will_change)
5354
: RasterCacheItem(RasterCacheKeyID(display_list->unique_id(),
5455
RasterCacheKeyType::kDisplayList),
55-
CacheState::kCurrent),
56+
CacheState::kNone),
5657
display_list_(display_list),
5758
offset_(offset),
5859
is_complex_(is_complex),
@@ -81,25 +82,24 @@ void DisplayListRasterCacheItem::PrerollSetup(PrerollContext* context,
8182
return;
8283
}
8384

85+
matrix_ = matrix;
8486
transformation_matrix_ = matrix;
8587
transformation_matrix_.preTranslate(offset_.x(), offset_.y());
8688

8789
if (!transformation_matrix_.invert(nullptr)) {
8890
// The matrix was singular. No point in going further.
8991
return;
9092
}
91-
92-
if (context->raster_cached_entries && context->raster_cache) {
93-
context->raster_cached_entries->push_back(this);
94-
cache_state_ = CacheState::kCurrent;
95-
}
93+
cache_state_ = CacheState::kCurrent;
9694
return;
9795
}
9896

9997
void DisplayListRasterCacheItem::PrerollFinalize(PrerollContext* context,
10098
const SkMatrix& matrix) {
10199
if (cache_state_ == CacheState::kNone || !context->raster_cache ||
102-
!context->raster_cached_entries) {
100+
!context->raster_cached_entries ||
101+
!context->raster_cache->GenerateNewCacheInThisFrame()) {
102+
cache_state_ = CacheState::kNone;
103103
return;
104104
}
105105
auto* raster_cache = context->raster_cache;
@@ -114,14 +114,26 @@ void DisplayListRasterCacheItem::PrerollFinalize(PrerollContext* context,
114114
cache_state_ = CacheState::kNone;
115115
return;
116116
}
117+
// This display_list can be cached so we should increate the cache count.
118+
context->raster_cache->IncreateDisplayListCacheCount();
117119
context->subtree_can_inherit_opacity = true;
118120
cache_state_ = CacheState::kCurrent;
119121
} else {
120-
raster_cache->Touch(key_id_, matrix);
122+
// if the bounds with the cull rect is not intersect, we only touch the
123+
// cache entry. And should not cache the display list
124+
cache_state_ = CacheState::kNone;
125+
raster_cache->Touch(key_id_, transformation_matrix_);
126+
return;
121127
}
128+
// If the display_list can be cached we will add it to cache_entries.
129+
context->raster_cached_entries->push_back(this);
122130
return;
123131
}
124132

133+
bool DisplayListRasterCacheItem::Touch(const PaintContext* context) const {
134+
return context->raster_cache->Touch(key_id_, transformation_matrix_);
135+
}
136+
125137
bool DisplayListRasterCacheItem::Draw(const PaintContext& context,
126138
const SkPaint* paint) const {
127139
return Draw(context, context.leaf_nodes_canvas, paint);
@@ -133,31 +145,24 @@ bool DisplayListRasterCacheItem::Draw(const PaintContext& context,
133145
if (!context.raster_cache || !canvas) {
134146
return false;
135147
}
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;
148+
return context.raster_cache->Draw(key_id_, *canvas, paint);
143149
}
144150

145151
static const auto* flow_type = "RasterCacheFlow::DisplayList";
146152

147153
bool DisplayListRasterCacheItem::TryToPrepareRasterCache(
148-
const PaintContext& context,
149-
bool parent_cached) const {
154+
const PaintContext& context) const {
150155
// If we don't have raster_cache we should not cache the current display_list.
151156
// If the current node's ancestor has been cached we also should not cache the
152157
// current node. In the current frame, the raster_cache will collect all
153158
// display_list or picture_list to calculate the memory they used, we
154159
// shouldn't cache the current node if the memory is more significant than the
155160
// limit.
156-
if (cache_state_ == kNone || !context.raster_cache || parent_cached ||
157-
!context.raster_cache->GenerateNewCacheInThisFrame()) {
161+
if (cache_state_ == kNone || !context.raster_cache) {
158162
return false;
159163
}
160-
SkRect bounds = display_list_->bounds().makeOffset(offset_.x(), offset_.y());
164+
165+
SkRect bounds = display_list_->bounds();
161166
RasterCache::Context r_context = {
162167
// clang-format off
163168
.gr_context = context.gr_context,
@@ -168,10 +173,10 @@ bool DisplayListRasterCacheItem::TryToPrepareRasterCache(
168173
.checkerboard = context.checkerboard_offscreen_layers,
169174
// clang-format on
170175
};
171-
return context.raster_cache->UpdateCacheEntry(
172-
GetId().value(), r_context,
173-
[display_list = display_list_](SkCanvas* canvas) {
176+
return context.raster_cache->UpdateDisplayListCacheEntry(
177+
key_id_, r_context, [display_list = display_list_](SkCanvas* canvas) {
174178
display_list->RenderTo(canvas);
179+
return true;
175180
});
176181
}
177182
} // namespace flutter

flow/layers/display_list_raster_cache_item.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ class DisplayListRasterCacheItem : public RasterCacheItem {
3838
void PrerollFinalize(PrerollContext* context,
3939
const SkMatrix& matrix) override;
4040

41+
bool Touch(const PaintContext* context) const override;
42+
4143
bool Draw(const PaintContext& context, const SkPaint* paint) const override;
4244

4345
bool Draw(const PaintContext& context,
4446
SkCanvas* canvas,
4547
const SkPaint* paint) const override;
4648

47-
bool TryToPrepareRasterCache(const PaintContext& context,
48-
bool parent_cached = false) const override;
49+
bool TryToPrepareRasterCache(const PaintContext& context) const override;
4950

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

flow/layers/layer_raster_cache_item.cc

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

55
#include "flutter/flow/layers/layer_raster_cache_item.h"
6+
#include <cstddef>
67
#include "flutter/flow/layers/container_layer.h"
78
#include "flutter/flow/raster_cache_item.h"
89

@@ -42,18 +43,11 @@ void LayerRasterCacheItem::PrerollFinalize(PrerollContext* context,
4243
if (!context->raster_cache || !context->raster_cached_entries) {
4344
return;
4445
}
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-
}
5246
child_items_ = context->raster_cached_entries->size() - child_items_;
47+
// Determine cache current layer or cache children.
5348
if (num_cache_attempts_ >= layer_cached_threshold_) {
5449
// the layer can be cached
5550
cache_state_ = CacheState::kCurrent;
56-
context->raster_cache->MarkSeen(key_id_, matrix_);
5751
} else {
5852
num_cache_attempts_++;
5953
// access current layer
@@ -67,9 +61,25 @@ void LayerRasterCacheItem::PrerollFinalize(PrerollContext* context,
6761
RasterCacheKeyType::kLayerChildren);
6862
}
6963
cache_state_ = CacheState::kChildren;
70-
context->raster_cache->MarkSeen(layer_children_id_.value(), matrix_);
7164
}
7265
}
66+
// We've marked the cache entry that we would like to cache so it stays
67+
// alive, but if the following conditions apply then we need to set our
68+
// state back to kDoNotCache so that we don't populate the entry later.
69+
if (context->has_platform_view || context->has_texture_layer ||
70+
!SkRect::Intersects(context->cull_rect, layer_->paint_bounds())) {
71+
if (cache_state_ != CacheState::kNone) {
72+
// Only touch the entry, do not to cache the layer or children.
73+
context->raster_cache->Touch(GetId().value(), matrix_);
74+
cache_state_ = CacheState::kNone;
75+
}
76+
return;
77+
}
78+
// The layer can be cache, so we should create a entry.
79+
if (cache_state_ != CacheState::kNone) {
80+
// Create Cache entry
81+
context->raster_cache->MarkSeen(GetId().value(), matrix_);
82+
}
7383
}
7484

7585
std::optional<RasterCacheKeyID> LayerRasterCacheItem::GetId() const {
@@ -111,19 +121,20 @@ bool Rasterize(RasterCacheItem::CacheState cache_state,
111121
.leaf_nodes_canvas = canvas,
112122
.gr_context = paint_context.gr_context,
113123
.dst_color_space = paint_context.dst_color_space,
114-
.view_embedder = paint_context.view_embedder,
124+
.view_embedder = nullptr,
115125
.raster_time = paint_context.raster_time,
116126
.ui_time = paint_context.ui_time,
117127
.texture_registry = paint_context.texture_registry,
118-
.raster_cache = paint_context.raster_cache,
128+
.raster_cache = layer->subtree_has_platform_view() ? nullptr: paint_context.raster_cache,
119129
.checkerboard_offscreen_layers = paint_context.checkerboard_offscreen_layers,
120130
.frame_device_pixel_ratio = paint_context.frame_device_pixel_ratio,
121131
// clang-format on
122132
};
123-
124133
switch (cache_state) {
125134
case RasterCacheItem::CacheState::kCurrent:
126-
FML_DCHECK(layer->needs_painting(context));
135+
if (!layer->needs_painting(context)) {
136+
return false;
137+
}
127138
layer->Paint(context);
128139
break;
129140
case RasterCacheItem::CacheState::kChildren:
@@ -138,9 +149,9 @@ bool Rasterize(RasterCacheItem::CacheState cache_state,
138149

139150
static const auto* flow_type = "RasterCacheFlow::Layer";
140151

141-
bool LayerRasterCacheItem::TryToPrepareRasterCache(const PaintContext& context,
142-
bool parent_cached) const {
143-
if (!context.raster_cache || parent_cached) {
152+
bool LayerRasterCacheItem::TryToPrepareRasterCache(
153+
const PaintContext& context) const {
154+
if (!context.raster_cache) {
144155
return false;
145156
}
146157
if (cache_state_ != kNone) {
@@ -159,7 +170,7 @@ bool LayerRasterCacheItem::TryToPrepareRasterCache(const PaintContext& context,
159170
GetId().value(), r_context,
160171
[ctx = context, cache_state = cache_state_,
161172
layer = layer_](SkCanvas* canvas) {
162-
Rasterize(cache_state, layer, ctx, canvas);
173+
return Rasterize(cache_state, layer, ctx, canvas);
163174
});
164175
}
165176
}
@@ -171,23 +182,17 @@ bool LayerRasterCacheItem::Draw(const PaintContext& context,
171182
return Draw(context, context.leaf_nodes_canvas, paint);
172183
}
173184

185+
bool LayerRasterCacheItem::Touch(const PaintContext* context) const {
186+
return context->raster_cache->Touch(GetId().value(), matrix_);
187+
}
188+
174189
bool LayerRasterCacheItem::Draw(const PaintContext& context,
175190
SkCanvas* canvas,
176191
const SkPaint* paint) const {
177-
if (!context.raster_cache || !canvas) {
192+
if (!context.raster_cache || !canvas || cache_state_ == CacheState::kNone) {
178193
return false;
179194
}
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-
}
195+
return context.raster_cache->Draw(GetId().value(), *canvas, paint);
191196
}
192197

193198
} // namespace flutter

flow/layers/layer_raster_cache_item.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <memory>
99
#include <optional>
1010

11+
#include "flutter/flow/raster_cache.h"
1112
#include "flutter/flow/raster_cache_item.h"
13+
#include "include/core/SkCanvas.h"
1214

1315
namespace flutter {
1416

@@ -38,12 +40,13 @@ class LayerRasterCacheItem : public RasterCacheItem {
3840

3941
bool Draw(const PaintContext& context, const SkPaint* paint) const override;
4042

43+
bool Touch(const PaintContext* context) const override;
44+
4145
bool Draw(const PaintContext& context,
4246
SkCanvas* canvas,
4347
const SkPaint* paint) const override;
4448

45-
bool TryToPrepareRasterCache(const PaintContext& context,
46-
bool parent_cached = false) const override;
49+
bool TryToPrepareRasterCache(const PaintContext& context) const override;
4750

4851
void MarkCacheChildren() { can_cache_children_ = true; }
4952

flow/layers/layer_tree.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,13 @@ void LayerTree::TryToRasterCache(
8484
// try to cache current layer
8585
// If parent failed to cache, just proceed to the next entry
8686
// cache current entry, this entry's parent must not cache
87-
if (item->TryToPrepareRasterCache(*paint_context, false)) {
87+
if (item->TryToPrepareRasterCache(*paint_context)) {
8888
// if parent cached, then foreach child layer to touch them.
8989
for (unsigned j = 0; j < item->child_items(); j++) {
9090
auto* child_item = raster_cached_items[i + j + 1];
9191
if (child_item->need_caching()) {
92-
child_item->TryToPrepareRasterCache(*paint_context, true);
92+
// If parent has cached, we only touch this cache entry.
93+
child_item->Touch(paint_context);
9394
}
9495
}
9596
i += item->child_items() + 1;

flow/raster_cache.cc

Lines changed: 29 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,26 @@ 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-
}
101+
}
102+
return entry.image != nullptr;
103+
}
104+
105+
bool RasterCache::UpdateDisplayListCacheEntry(
106+
const RasterCacheKeyID& id,
107+
const Context& raster_cache_context,
108+
const std::function<bool(SkCanvas*)>& render_function) const {
109+
RasterCacheKey key = RasterCacheKey(id, raster_cache_context.matrix);
110+
Entry& entry = cache_[key];
111+
entry.used_this_frame = true;
112+
if (!entry.image) {
113+
entry.image = Rasterize(raster_cache_context, render_function);
114+
return true;
109115
}
110116
return entry.image != nullptr;
111117
}
@@ -130,6 +136,15 @@ int RasterCache::MarkSeen(const RasterCacheKeyID& id,
130136
return entry.access_count;
131137
}
132138

139+
void RasterCache::Erasure(const RasterCacheKeyID& id,
140+
const SkMatrix& matrix) const {
141+
RasterCacheKey cache_key = RasterCacheKey(id, matrix);
142+
auto it = cache_.find(cache_key);
143+
if (it != cache_.end()) {
144+
cache_.erase(it);
145+
}
146+
}
147+
133148
bool RasterCache::HasEntry(const RasterCacheKeyID& id,
134149
const SkMatrix& matrix) const {
135150
RasterCacheKey key = RasterCacheKey(id, matrix);

0 commit comments

Comments
 (0)