Flutter Engine
The Flutter Engine
display_list_raster_cache_item.cc
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#if !SLIMPELLER
6
7#include "flutter/flow/layers/display_list_raster_cache_item.h"
8
9#include <optional>
10#include <utility>
11
12#include "flutter/display_list/benchmarking/dl_complexity.h"
13#include "flutter/display_list/display_list.h"
14#include "flutter/flow/layers/layer.h"
15#include "flutter/flow/raster_cache.h"
16#include "flutter/flow/raster_cache_item.h"
17#include "flutter/flow/raster_cache_key.h"
18#include "flutter/flow/raster_cache_util.h"
20
21namespace flutter {
22
24 const DisplayList* display_list,
25 bool will_change,
26 bool is_complex,
27 DisplayListComplexityCalculator* complexity_calculator) {
28 if (will_change) {
29 // If the display list is going to change in the future, there is no point
30 // in doing to extra work to rasterize.
31 return false;
32 }
33
34 if (display_list == nullptr ||
35 !RasterCacheUtil::CanRasterizeRect(display_list->bounds())) {
36 // No point in deciding whether the display list is worth rasterizing if it
37 // cannot be rasterized at all.
38 return false;
39 }
40
41 if (is_complex) {
42 // The caller seems to have extra information about the display list and
43 // thinks the display list is always worth rasterizing.
44 return true;
45 }
46
47 unsigned int complexity_score = complexity_calculator->Compute(display_list);
48 return complexity_calculator->ShouldBeCached(complexity_score);
49}
50
52 const sk_sp<DisplayList>& display_list,
53 const SkPoint& offset,
54 bool is_complex,
55 bool will_change)
56 : RasterCacheItem(RasterCacheKeyID(display_list->unique_id(),
58 CacheState::kCurrent),
59 display_list_(display_list),
60 offset_(offset),
61 is_complex_(is_complex),
62 will_change_(will_change) {}
63
64std::unique_ptr<DisplayListRasterCacheItem> DisplayListRasterCacheItem::Make(
65 const sk_sp<DisplayList>& display_list,
66 const SkPoint& offset,
67 bool is_complex,
68 bool will_change) {
69 return std::make_unique<DisplayListRasterCacheItem>(display_list, offset,
70 is_complex, will_change);
71}
72
74 const SkMatrix& matrix) {
76 DisplayListComplexityCalculator* complexity_calculator =
78 context->gr_context->backend())
80
81 if (!IsDisplayListWorthRasterizing(display_list(), will_change_, is_complex_,
82 complexity_calculator)) {
83 // We only deal with display lists that are worthy of rasterization.
84 return;
85 }
86
87 transformation_matrix_ = matrix;
88 transformation_matrix_.preTranslate(offset_.x(), offset_.y());
89
90 if (!transformation_matrix_.invert(nullptr)) {
91 // The matrix was singular. No point in going further.
92 return;
93 }
94
95 if (context->raster_cached_entries && context->raster_cache) {
96 context->raster_cached_entries->push_back(this);
97 cache_state_ = CacheState::kCurrent;
98 }
99 return;
100}
101
103 const SkMatrix& matrix) {
104 if (cache_state_ == CacheState::kNone || !context->raster_cache ||
105 !context->raster_cached_entries) {
106 return;
107 }
108 auto* raster_cache = context->raster_cache;
109 SkRect bounds = display_list_->bounds().makeOffset(offset_.x(), offset_.y());
110 bool visible = !context->state_stack.content_culled(bounds);
111 RasterCache::CacheInfo cache_info =
112 raster_cache->MarkSeen(key_id_, matrix, visible);
113 if (!visible ||
114 cache_info.accesses_since_visible <= raster_cache->access_threshold()) {
116 } else {
117 if (cache_info.has_image) {
118 context->renderable_state_flags |=
120 }
122 }
123 return;
124}
125
127 const DlPaint* paint) const {
128 return Draw(context, context.canvas, paint);
129}
130
132 DlCanvas* canvas,
133 const DlPaint* paint) const {
134 if (!context.raster_cache || !canvas) {
135 return false;
136 }
137 if (cache_state_ == CacheState::kCurrent) {
138 return context.raster_cache->Draw(key_id_, *canvas, paint,
140 }
141 return false;
142}
143
144static const auto* flow_type = "RasterCacheFlow::DisplayList";
145
147 const PaintContext& context,
148 bool parent_cached) const {
149 // If we don't have raster_cache we should not cache the current display_list.
150 // If the current node's ancestor has been cached we also should not cache the
151 // current node. In the current frame, the raster_cache will collect all
152 // display_list or picture_list to calculate the memory they used, we
153 // shouldn't cache the current node if the memory is more significant than the
154 // limit.
155 auto id = GetId();
156 FML_DCHECK(id.has_value());
157 if (cache_state_ == kNone || !context.raster_cache || parent_cached ||
158 !context.raster_cache->GenerateNewCacheInThisFrame() || !id.has_value()) {
159 return false;
160 }
161 SkRect bounds = display_list_->bounds().makeOffset(offset_.x(), offset_.y());
162 RasterCache::Context r_context = {
163 // clang-format off
164 .gr_context = context.gr_context,
165 .dst_color_space = context.dst_color_space,
166 .matrix = transformation_matrix_,
167 .logical_rect = bounds,
168 .flow_type = flow_type,
169 // clang-format on
170 };
171 return context.raster_cache->UpdateCacheEntry(
172 id.value(), r_context,
173 [display_list = display_list_](DlCanvas* canvas) {
175 },
176 display_list_->rtree());
177}
178} // namespace flutter
179
180#endif // !SLIMPELLER
SK_API GrBackendApi backend() const
bool invert(SkMatrix *inverse) const
Definition: SkMatrix.h:1206
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
static DisplayListComplexityCalculator * GetForBackend(GrBackendApi backend)
static DisplayListComplexityCalculator * GetForSoftware()
virtual bool ShouldBeCached(unsigned int complexity_score)=0
virtual unsigned int Compute(const DisplayList *display_list)=0
bool TryToPrepareRasterCache(const PaintContext &context, bool parent_cached=false) const override
static std::unique_ptr< DisplayListRasterCacheItem > Make(const sk_sp< DisplayList > &, const SkPoint &offset, bool is_complex, bool will_change)
void PrerollSetup(PrerollContext *context, const SkMatrix &matrix) override
DisplayListRasterCacheItem(const sk_sp< DisplayList > &display_list, const SkPoint &offset, bool is_complex=true, bool will_change=false)
void PrerollFinalize(PrerollContext *context, const SkMatrix &matrix) override
bool Draw(const PaintContext &context, const DlPaint *paint) const override
const SkRect & bounds() const
Definition: display_list.h:294
Developer-facing API for rendering anything within the engine.
Definition: dl_canvas.h:38
virtual void DrawDisplayList(const sk_sp< DisplayList > display_list, SkScalar opacity=SK_Scalar1)=0
bool content_culled(const SkRect &content_bounds) const
static constexpr int kCallerCanApplyOpacity
virtual std::optional< RasterCacheKeyID > GetId() const
const Paint & paint
Definition: color_source.cc:38
uint8_t value
#define FML_DCHECK(condition)
Definition: logging.h:103
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
@ kNone
Definition: layer.h:53
static bool IsDisplayListWorthRasterizing(const DisplayList *display_list, bool will_change, bool is_complex, DisplayListComplexityCalculator *complexity_calculator)
static const auto * flow_type
SeparatedVector2 offset
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
bool rendering_above_platform_view
Definition: layer.h:107
sk_sp< SkColorSpace > dst_color_space
Definition: layer.h:110
DlCanvas * canvas
Definition: layer.h:102
GrDirectContext * gr_context
Definition: layer.h:109
GrDirectContext * gr_context
Definition: layer.h:57
std::vector< RasterCacheItem * > * raster_cached_entries
Definition: layer.h:85
LayerStateStack & state_stack
Definition: layer.h:59
int renderable_state_flags
Definition: layer.h:83
static bool CanRasterizeRect(const SkRect &cull_rect)
GrDirectContext * gr_context
Definition: raster_cache.h:121