Flutter Engine
 
Loading...
Searching...
No Matches
raster_cache.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_FLOW_RASTER_CACHE_H_
6#define FLUTTER_FLOW_RASTER_CACHE_H_
7
8#if !SLIMPELLER
9
10#include <memory>
11#include <unordered_map>
12
17#include "flutter/fml/macros.h"
20#include "third_party/skia/include/core/SkMatrix.h"
21#include "third_party/skia/include/core/SkRect.h"
22
23class GrDirectContext;
24class SkColorSpace;
25
26namespace flutter {
27
29
31 public:
32 RasterCacheResult(sk_sp<DlImage> image,
33 const SkRect& logical_rect,
34 const char* type,
35 sk_sp<const DlRTree> rtree = nullptr);
36
37 virtual ~RasterCacheResult() = default;
38
39 virtual void draw(DlCanvas& canvas,
40 const DlPaint* paint,
41 bool preserve_rtree) const;
42
43 virtual SkISize image_dimensions() const {
44 return image_ ? ToSkISize(image_->GetSize()) : SkISize::Make(0, 0);
45 };
46
47 virtual int64_t image_bytes() const {
48 return image_ ? image_->GetApproximateByteSize() : 0;
49 };
50
51 private:
52 sk_sp<DlImage> image_;
53 SkRect logical_rect_;
55 sk_sp<const DlRTree> rtree_;
56};
57
58class Layer;
59class RasterCacheItem;
60struct PrerollContext;
61struct PaintContext;
62
64 /**
65 * The number of cache entries with images evicted in this frame.
66 */
67 size_t eviction_count = 0;
68
69 /**
70 * The size of all of the images evicted in this frame.
71 */
72 size_t eviction_bytes = 0;
73
74 /**
75 * The number of cache entries with images used in this frame.
76 */
77 size_t in_use_count = 0;
78
79 /**
80 * The size of all of the images used in this frame.
81 */
82 size_t in_use_bytes = 0;
83
84 /**
85 * The total cache entries that had images during this frame.
86 */
87 size_t total_count() const { return in_use_count; }
88
89 /**
90 * The size of all of the cached images during this frame.
91 */
92 size_t total_bytes() const { return in_use_bytes; }
93};
94
95/**
96 * RasterCache is used to cache rasterized layers or display lists to improve
97 * performance.
98 *
99 * Life cycle of RasterCache methods:
100 * - Preroll stage
101 * - LayerTree::Preroll - for each Layer in the tree:
102 * - RasterCacheItem::PrerollSetup
103 * At the start of each layer's preroll, add cache items to
104 * `PrerollContext::raster_cached_entries`.
105 * - RasterCacheItem::PrerollFinalize
106 * At the end of each layer's preroll, may mark cache entries as
107 * encountered by the current frame.
108 * - Paint stage
109 * - RasterCache::EvictUnusedCacheEntries
110 * Evict cached images that are no longer used.
111 * - LayerTree::TryToPrepareRasterCache
112 * Create cache image for each cache entry if it does not exist.
113 * - LayerTree::Paint - for each layer in the tree:
114 * If layers or display lists are cached as cached images, the method
115 * `RasterCache::Draw` will be used to draw those cache images.
116 * - RasterCache::EndFrame:
117 * Computes used counts and memory then reports cache metrics.
118 */
120 public:
121 struct Context {
122 GrDirectContext* gr_context;
123 const sk_sp<SkColorSpace> dst_color_space;
124 const SkMatrix& matrix;
125 const SkRect& logical_rect;
126 const char* flow_type;
127 };
128 struct CacheInfo {
130 const bool has_image;
131 };
132
133 std::unique_ptr<RasterCacheResult> Rasterize(
134 const RasterCache::Context& context,
135 sk_sp<const DlRTree> rtree,
136 const std::function<void(DlCanvas*)>& draw_function,
137 const std::function<void(DlCanvas*, const DlRect& rect)>&
138 draw_checkerboard) const;
139
140 explicit RasterCache(
141 size_t access_threshold = 3,
142 size_t picture_and_display_list_cache_limit_per_frame =
144
145 virtual ~RasterCache() = default;
146
147 // Draws this item if it should be rendered from the cache and returns
148 // true iff it was successfully drawn. Typically this should only fail
149 // if the item was disabled due to conditions discovered during |Preroll|
150 // or if the attempt to populate the entry failed due to bounds overflow
151 // conditions.
152 // If |preserve_rtree| is true, the raster cache will preserve the original
153 // RTree of cached content by blitting individual rectangles from the cached
154 // image to the canvas according to the original layer R-Tree (if present).
155 // This is to ensure that the target surface R-Tree will not be clobbered with
156 // one large blit as it can affect platform view overlays and hit testing.
157 bool Draw(const RasterCacheKeyID& id,
158 DlCanvas& canvas,
159 const DlPaint* paint,
160 bool preserve_rtree = false) const;
161
162 bool HasEntry(const RasterCacheKeyID& id, const SkMatrix&) const;
163
164 void BeginFrame();
165
167
168 void EndFrame();
169
170 void Clear();
171
172 const RasterCacheMetrics& picture_metrics() const { return picture_metrics_; }
173 const RasterCacheMetrics& layer_metrics() const { return layer_metrics_; }
174
175 size_t GetCachedEntriesCount() const;
176
177 /**
178 * Return the number of map entries in the layer cache regardless of whether
179 * the entries have been populated with an image.
180 */
181 size_t GetLayerCachedEntriesCount() const;
182
183 /**
184 * Return the number of map entries in the picture (DisplayList) cache
185 * regardless of whether the entries have been populated with an image.
186 */
187 size_t GetPictureCachedEntriesCount() const;
188
189 /**
190 * @brief Estimate how much memory is used by picture raster cache entries in
191 * bytes.
192 *
193 * Only SkImage's memory usage is counted as other objects are often much
194 * smaller compared to SkImage. SkImageInfo::computeMinByteSize is used to
195 * estimate the SkImage memory usage.
196 */
197 size_t EstimatePictureCacheByteSize() const;
198
199 /**
200 * @brief Estimate how much memory is used by layer raster cache entries in
201 * bytes.
202 *
203 * Only SkImage's memory usage is counted as other objects are often much
204 * smaller compared to SkImage. SkImageInfo::computeMinByteSize is used to
205 * estimate the SkImage memory usage.
206 */
207 size_t EstimateLayerCacheByteSize() const;
208
209 /**
210 * @brief Return the number of frames that a picture must be prepared
211 * before it will be cached. If the number is 0, then no picture will
212 * ever be cached.
213 *
214 * If the number is one, then it must be prepared and drawn on 1 frame
215 * and it will then be cached on the next frame if it is prepared.
216 */
217 size_t access_threshold() const { return access_threshold_; }
218
220 // Disabling caching when access_threshold is zero is historic behavior.
221 return access_threshold_ != 0 && display_list_cached_this_frame_ <
222 display_list_cache_limit_per_frame_;
223 }
224
225 /**
226 * @brief The entry whose RasterCacheKey is generated by RasterCacheKeyID
227 * and matrix is marked as encountered by the current frame. The entry
228 * will be created if it does not exist. Optionally the entry will be marked
229 * as visible in the current frame if the caller determines that it
230 * intersects the cull rect. The access_count of the entry will be
231 * increased if it is visible, or if it was ever visible.
232 * @return the number of times the entry has been hit since it was created.
233 * For a new entry that will be 1 if it is visible, or zero if non-visible.
234 */
235 CacheInfo MarkSeen(const RasterCacheKeyID& id,
236 const SkMatrix& matrix,
237 bool visible) const;
238
239 /**
240 * Returns the access count (i.e. accesses_since_visible) for the given
241 * entry in the cache, or -1 if no such entry exists.
242 */
243 int GetAccessCount(const RasterCacheKeyID& id, const SkMatrix& matrix) const;
244
245 bool UpdateCacheEntry(const RasterCacheKeyID& id,
246 const Context& raster_cache_context,
247 const std::function<void(DlCanvas*)>& render_function,
248 sk_sp<const DlRTree> rtree = nullptr) const;
249
250 private:
251 struct Entry {
252 bool encountered_this_frame = false;
253 bool visible_this_frame = false;
254 size_t accesses_since_visible = 0;
255 std::unique_ptr<RasterCacheResult> image;
256 };
257
258 void UpdateMetrics();
259
260 RasterCacheMetrics& GetMetricsForKind(RasterCacheKeyKind kind);
261
262 const size_t access_threshold_;
263 const size_t display_list_cache_limit_per_frame_;
264 mutable size_t display_list_cached_this_frame_ = 0;
265 RasterCacheMetrics layer_metrics_;
266 RasterCacheMetrics picture_metrics_;
267 mutable RasterCacheKey::Map<Entry> cache_;
268 bool checkerboard_images_ = false;
269
270 void TraceStatsToTimeline() const;
271
272 friend class RasterCacheItem;
274
276};
277
278} // namespace flutter
279
280#else // !SLIMPELLER
281
282class RasterCache;
283
284#endif // !SLIMPELLER
285
286#endif // FLUTTER_FLOW_RASTER_CACHE_H_
GLenum type
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual ~RasterCache()=default
bool Draw(const RasterCacheKeyID &id, DlCanvas &canvas, const DlPaint *paint, bool preserve_rtree=false) const
CacheInfo MarkSeen(const RasterCacheKeyID &id, const SkMatrix &matrix, bool visible) const
The entry whose RasterCacheKey is generated by RasterCacheKeyID and matrix is marked as encountered b...
size_t access_threshold() const
Return the number of frames that a picture must be prepared before it will be cached....
const RasterCacheMetrics & picture_metrics() const
size_t EstimatePictureCacheByteSize() const
Estimate how much memory is used by picture raster cache entries in bytes.
const RasterCacheMetrics & layer_metrics() const
bool HasEntry(const RasterCacheKeyID &id, const SkMatrix &) const
bool UpdateCacheEntry(const RasterCacheKeyID &id, const Context &raster_cache_context, const std::function< void(DlCanvas *)> &render_function, sk_sp< const DlRTree > rtree=nullptr) const
bool GenerateNewCacheInThisFrame() const
int GetAccessCount(const RasterCacheKeyID &id, const SkMatrix &matrix) const
size_t GetCachedEntriesCount() const
size_t GetPictureCachedEntriesCount() const
size_t EstimateLayerCacheByteSize() const
Estimate how much memory is used by layer raster cache entries in bytes.
size_t GetLayerCachedEntriesCount() const
std::unique_ptr< RasterCacheResult > Rasterize(const RasterCache::Context &context, sk_sp< const DlRTree > rtree, const std::function< void(DlCanvas *)> &draw_function, const std::function< void(DlCanvas *, const DlRect &rect)> &draw_checkerboard) const
virtual SkISize image_dimensions() const
virtual void draw(DlCanvas &canvas, const DlPaint *paint, bool preserve_rtree) const
virtual int64_t image_bytes() const
virtual ~RasterCacheResult()=default
To do anything rendering related with Impeller, you need a context.
Definition context.h:65
FlutterVulkanImage * image
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
RasterCacheLayerStrategy
const SkISize & ToSkISize(const DlISize &size)
const sk_sp< SkColorSpace > dst_color_space
static constexpr int kDefaultPictureAndDisplayListCacheLimitPerFrame