20#include "third_party/skia/include/core/SkColorSpace.h"
21#include "third_party/skia/include/core/SkImage.h"
22#include "third_party/skia/include/core/SkSurface.h"
23#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
24#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
29 const SkRect& logical_rect,
31 sk_sp<const DlRTree> rtree)
33 logical_rect_(logical_rect),
35 rtree_(
std::move(rtree)) {}
39 bool preserve_rtree)
const {
46 FML_DCHECK(std::abs(bounds.width() - image_->GetSize().width) <= 1 &&
47 std::abs(bounds.height() - image_->GetSize().height) <= 1);
50 if (!preserve_rtree || !rtree_) {
57 auto rects = rtree_->region().getRects(
true);
59 canvas.
Translate(bounds.fLeft, bounds.fTop);
63 for (
auto rect : rects) {
66 device_rect = device_rect.
Shift(-rtree_bounds.fLeft, -rtree_bounds.fTop);
74 size_t display_list_cache_limit_per_frame)
75 : access_threshold_(access_threshold),
76 display_list_cache_limit_per_frame_(display_list_cache_limit_per_frame) {}
81 sk_sp<const DlRTree> rtree,
82 const std::function<
void(
DlCanvas*)>& draw_function,
83 const std::function<
void(
DlCanvas*,
const DlRect& rect)>& draw_checkerboard)
89 const SkImageInfo image_info = SkImageInfo::MakeN32Premul(
94 ? SkSurfaces::RenderTarget(context.
gr_context, skgpu::Budgeted::kYes,
96 : SkSurfaces::Raster(image_info);
105 canvas.
Translate(-dest_rect.left(), -dest_rect.top());
107 draw_function(&canvas);
109 if (checkerboard_images_) {
114 return std::make_unique<RasterCacheResult>(
120 const Context& raster_cache_context,
121 const std::function<
void(
DlCanvas*)>& render_function,
122 sk_sp<const DlRTree> rtree)
const {
124 Entry& entry = cache_[
key];
127 entry.image =
Rasterize(raster_cache_context, std::move(rtree),
128 render_function, func);
129 if (entry.image !=
nullptr) {
132 display_list_cached_this_frame_++;
141 return entry.image !=
nullptr;
145 const SkMatrix& matrix,
146 bool visible)
const {
148 Entry& entry = cache_[
key];
149 entry.encountered_this_frame =
true;
150 entry.visible_this_frame = visible;
151 if (visible || entry.accesses_since_visible > 0) {
152 entry.accesses_since_visible++;
154 return {entry.accesses_since_visible, entry.image !=
nullptr};
158 const SkMatrix& matrix)
const {
160 auto entry = cache_.find(
key);
161 if (entry != cache_.cend()) {
162 return entry->second.accesses_since_visible;
168 const SkMatrix& matrix)
const {
170 if (cache_.find(
key) != cache_.cend()) {
179 bool preserve_rtree)
const {
181 if (it == cache_.end()) {
185 Entry& entry = it->second;
188 entry.image->draw(canvas, paint, preserve_rtree);
196 display_list_cached_this_frame_ = 0;
197 picture_metrics_ = {};
201void RasterCache::UpdateMetrics() {
202 for (
auto it = cache_.begin(); it != cache_.end(); ++it) {
203 Entry& entry = it->second;
210 entry.encountered_this_frame =
false;
215 std::vector<RasterCacheKey::Map<Entry>::iterator> dead;
217 for (
auto it = cache_.begin(); it != cache_.end(); ++it) {
218 Entry& entry = it->second;
219 if (!entry.encountered_this_frame) {
224 for (
auto it : dead) {
225 if (it->second.image) {
236 TraceStatsToTimeline();
241 picture_metrics_ = {};
246 return cache_.size();
250 size_t layer_cached_entries_count = 0;
251 for (
const auto& item : cache_) {
253 layer_cached_entries_count++;
256 return layer_cached_entries_count;
260 size_t display_list_cached_entries_count = 0;
261 for (
const auto& item : cache_) {
263 display_list_cached_entries_count++;
266 return display_list_cached_entries_count;
269void RasterCache::TraceStatsToTimeline()
const {
273 "RasterCache",
reinterpret_cast<int64_t
>(
this),
283 size_t layer_cache_bytes = 0;
284 for (
const auto& item : cache_) {
287 layer_cache_bytes += item.second.image->image_bytes();
290 return layer_cache_bytes;
294 size_t picture_cache_bytes = 0;
295 for (
const auto& item : cache_) {
298 picture_cache_bytes += item.second.image->image_bytes();
301 return picture_cache_bytes;
307 return picture_metrics_;
309 return layer_metrics_;
Developer-facing API for rendering anything within the engine.
virtual void TransformReset()=0
virtual void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr)=0
virtual void Translate(DlScalar tx, DlScalar ty)=0
virtual DlMatrix GetMatrix() const =0
void Clear(DlColor color)
virtual void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast)=0
static sk_sp< DlImage > Make(const SkImage *image)
Backend implementation of |DlCanvas| for |SkCanvas|.
void Transform(const DlMatrix &matrix) override
void Translate(DlScalar tx, DlScalar ty) override
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 EstimatePictureCacheByteSize() const
Estimate how much memory is used by picture raster cache entries in bytes.
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
RasterCache(size_t access_threshold=3, size_t picture_and_display_list_cache_limit_per_frame=RasterCacheUtil::kDefaultPictureAndDisplayListCacheLimitPerFrame)
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
void EvictUnusedCacheEntries()
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
RasterCacheResult(sk_sp< DlImage > image, const SkRect &logical_rect, const char *type, sk_sp< const DlRTree > rtree=nullptr)
virtual void draw(DlCanvas &canvas, const DlPaint *paint, bool preserve_rtree) const
void Step(const char *label=nullptr) const
FlutterVulkanImage * image
#define FML_DCHECK(condition)
const SkIRect & ToSkIRect(const DlIRect &rect)
void DrawCheckerboard(DlCanvas *canvas, const DlRect &rect)
SkMatrix ToSkMatrix(const DlMatrix &matrix)
constexpr double kMegaByteSizeInBytes
DlMatrix ToDlMatrix(const SkMatrix &matrix)
const DlRect & ToDlRect(const SkRect &rect)
const SkRect & ToSkRect(const DlRect &rect)
static constexpr DlColor kTransparent()
const SkRect & logical_rect
GrDirectContext * gr_context
const sk_sp< SkColorSpace > dst_color_space
size_t total_count() const
size_t total_bytes() const
static SkMatrix GetIntegralTransCTM(const SkMatrix &ctm)
Snap the translation components of the matrix to integers.
static SkRect GetRoundedOutDeviceBounds(const SkRect &rect, const SkMatrix &ctm)
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1,...)