21#include "third_party/skia/include/core/SkColorSpace.h"
22#include "third_party/skia/include/core/SkImage.h"
23#include "third_party/skia/include/core/SkSurface.h"
24#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
25#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
30 const SkRect& logical_rect,
32 sk_sp<const DlRTree> rtree)
34 logical_rect_(logical_rect),
36 rtree_(
std::move(rtree)) {}
40 bool preserve_rtree)
const {
47 FML_DCHECK(std::abs(bounds.width() - image_->GetSize().width) <= 1 &&
48 std::abs(bounds.height() - image_->GetSize().height) <= 1);
51 if (!preserve_rtree || !rtree_) {
58 auto rects = rtree_->region().getRects(
true);
60 canvas.
Translate(bounds.fLeft, bounds.fTop);
64 for (
auto rect : rects) {
67 device_rect = device_rect.
Shift(-rtree_bounds.fLeft, -rtree_bounds.fTop);
75 size_t display_list_cache_limit_per_frame)
76 : access_threshold_(access_threshold),
77 display_list_cache_limit_per_frame_(display_list_cache_limit_per_frame) {}
82 sk_sp<const DlRTree> rtree,
83 const std::function<
void(
DlCanvas*)>& draw_function,
84 const std::function<
void(
DlCanvas*,
const DlRect& rect)>& draw_checkerboard)
90 const SkImageInfo image_info = SkImageInfo::MakeN32Premul(
95 ? SkSurfaces::RenderTarget(context.
gr_context, skgpu::Budgeted::kYes,
97 : SkSurfaces::Raster(image_info);
106 canvas.
Translate(-dest_rect.left(), -dest_rect.top());
108 draw_function(&canvas);
110 if (checkerboard_images_) {
115 return std::make_unique<RasterCacheResult>(
121 const Context& raster_cache_context,
122 const std::function<
void(
DlCanvas*)>& render_function,
123 sk_sp<const DlRTree> rtree)
const {
125 Entry& entry = cache_[
key];
128 entry.image =
Rasterize(raster_cache_context, std::move(rtree),
129 render_function, func);
130 if (entry.image !=
nullptr) {
133 display_list_cached_this_frame_++;
142 return entry.image !=
nullptr;
146 const SkMatrix& matrix,
147 bool visible)
const {
149 Entry& entry = cache_[
key];
150 entry.encountered_this_frame =
true;
151 entry.visible_this_frame = visible;
152 if (visible || entry.accesses_since_visible > 0) {
153 entry.accesses_since_visible++;
155 return {entry.accesses_since_visible, entry.image !=
nullptr};
159 const SkMatrix& matrix)
const {
161 auto entry = cache_.find(
key);
162 if (entry != cache_.cend()) {
163 return entry->second.accesses_since_visible;
169 const SkMatrix& matrix)
const {
171 if (cache_.find(
key) != cache_.cend()) {
180 bool preserve_rtree)
const {
182 if (it == cache_.end()) {
186 Entry& entry = it->second;
189 entry.image->draw(canvas, paint, preserve_rtree);
197 display_list_cached_this_frame_ = 0;
198 picture_metrics_ = {};
202void RasterCache::UpdateMetrics() {
203 for (
auto it = cache_.begin(); it != cache_.end(); ++it) {
204 Entry& entry = it->second;
211 entry.encountered_this_frame =
false;
216 std::vector<RasterCacheKey::Map<Entry>::iterator> dead;
218 for (
auto it = cache_.begin(); it != cache_.end(); ++it) {
219 Entry& entry = it->second;
220 if (!entry.encountered_this_frame) {
225 for (
auto it : dead) {
226 if (it->second.image) {
237 TraceStatsToTimeline();
242 picture_metrics_ = {};
247 return cache_.size();
251 size_t layer_cached_entries_count = 0;
252 for (
const auto& item : cache_) {
254 layer_cached_entries_count++;
257 return layer_cached_entries_count;
261 size_t display_list_cached_entries_count = 0;
262 for (
const auto& item : cache_) {
264 display_list_cached_entries_count++;
267 return display_list_cached_entries_count;
270void RasterCache::TraceStatsToTimeline()
const {
274 "RasterCache",
reinterpret_cast<int64_t
>(
this),
284 size_t layer_cache_bytes = 0;
285 for (
const auto& item : cache_) {
288 layer_cache_bytes += item.second.image->image_bytes();
291 return layer_cache_bytes;
295 size_t picture_cache_bytes = 0;
296 for (
const auto& item : cache_) {
299 picture_cache_bytes += item.second.image->image_bytes();
302 return picture_cache_bytes;
308 return picture_metrics_;
310 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)
impeller::ShaderType type
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,...)