Flutter Engine
 
Loading...
Searching...
No Matches
layer_tree.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
6
16#include "include/core/SkColorSpace.h"
17
18namespace flutter {
19
20LayerTree::LayerTree(const std::shared_ptr<Layer>& root_layer,
21 const DlISize& frame_size)
22 : root_layer_(root_layer), frame_size_(frame_size) {}
23
24inline SkColorSpace* GetColorSpace(DlCanvas* canvas) {
25 return canvas ? canvas->GetImageInfo().colorSpace() : nullptr;
26}
27
29 bool ignore_raster_cache,
30 DlRect cull_rect) {
31 TRACE_EVENT0("flutter", "LayerTree::Preroll");
32
33 if (!root_layer_) {
34 FML_LOG(ERROR) << "The scene did not specify any layers.";
35 return false;
36 }
37
38 SkColorSpace* color_space = GetColorSpace(frame.canvas());
39 LayerStateStack state_stack;
40 state_stack.set_preroll_delegate(cull_rect,
42
43 raster_cache_items_.clear();
44
45 PrerollContext context = {
46#if !SLIMPELLER
47 .raster_cache =
48 ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
49#endif // !SLIMPELLER
50 .gr_context = frame.gr_context(),
51 .view_embedder = frame.view_embedder(),
52 .state_stack = state_stack,
53 .dst_color_space = sk_ref_sp<SkColorSpace>(color_space),
54 .surface_needs_readback = false,
55 .raster_time = frame.context().raster_time(),
56 .ui_time = frame.context().ui_time(),
57 .texture_registry = frame.context().texture_registry(),
58 .raster_cached_entries = &raster_cache_items_,
59 };
60
61 root_layer_->Preroll(&context);
62
63 return context.surface_needs_readback;
64}
65
66#if !SLIMPELLER
68 const std::vector<RasterCacheItem*>& raster_cached_items,
69 const PaintContext* paint_context,
70 bool ignore_raster_cache) {
71 unsigned i = 0;
72 const auto item_size = raster_cached_items.size();
73 while (i < item_size) {
74 auto* item = raster_cached_items[i];
75 if (item->need_caching()) {
76 // try to cache current layer
77 // If parent failed to cache, just proceed to the next entry
78 // cache current entry, this entry's parent must not cache
79 if (item->TryToPrepareRasterCache(*paint_context, false)) {
80 // if parent cached, then foreach child layer to touch them.
81 for (unsigned j = 0; j < item->child_items(); j++) {
82 auto* child_item = raster_cached_items[i + j + 1];
83 if (child_item->need_caching()) {
84 child_item->TryToPrepareRasterCache(*paint_context, true);
85 }
86 }
87 i += item->child_items() + 1;
88 continue;
89 }
90 }
91 i++;
92 }
93}
94#endif // !SLIMPELLER
95
97 bool ignore_raster_cache) const {
98 TRACE_EVENT0("flutter", "LayerTree::Paint");
99
100 if (!root_layer_) {
101 FML_LOG(ERROR) << "The scene did not specify any layers to paint.";
102 return;
103 }
104
105 LayerStateStack state_stack;
106
107 DlCanvas* canvas = frame.canvas();
108 state_stack.set_delegate(canvas);
109
110 SkColorSpace* color_space = GetColorSpace(frame.canvas());
111
112#if !SLIMPELLER
113 RasterCache* cache =
114 ignore_raster_cache ? nullptr : &frame.context().raster_cache();
115#endif // !SLIMPELLER
116
117 PaintContext context = {
118 // clang-format off
119 .state_stack = state_stack,
120 .canvas = canvas,
121 .gr_context = frame.gr_context(),
122 .dst_color_space = sk_ref_sp(color_space),
123 .view_embedder = frame.view_embedder(),
124 .raster_time = frame.context().raster_time(),
125 .ui_time = frame.context().ui_time(),
126 .texture_registry = frame.context().texture_registry(),
127#if !SLIMPELLER
128 .raster_cache = cache,
129#endif // !SLIMPELLER
130 .impeller_enabled = !!frame.aiks_context(),
131 .aiks_context = frame.aiks_context(),
132 // clang-format on
133 };
134
135#if !SLIMPELLER
136 if (cache) {
138 TryToRasterCache(raster_cache_items_, &context, ignore_raster_cache);
139 }
140#endif // !SLIMPELLER
141
142 if (root_layer_->needs_painting(context)) {
143 root_layer_->Paint(context);
144 }
145}
146
147sk_sp<DisplayList> LayerTree::Flatten(
148 const DlRect& bounds,
149 const std::shared_ptr<TextureRegistry>& texture_registry,
150 GrDirectContext* gr_context) {
151 TRACE_EVENT0("flutter", "LayerTree::Flatten");
152
153 DisplayListBuilder builder(bounds);
154
155 const FixedRefreshRateStopwatch unused_stopwatch;
156
157 LayerStateStack preroll_state_stack;
158 // No root surface transformation. So assume identity.
159 preroll_state_stack.set_preroll_delegate(bounds);
160 PrerollContext preroll_context{
161 // clang-format off
162#if !SLIMPELLER
163 .raster_cache = nullptr,
164#endif // !SLIMPELLER
165 .gr_context = gr_context,
166 .view_embedder = nullptr,
167 .state_stack = preroll_state_stack,
168 .dst_color_space = nullptr,
169 .surface_needs_readback = false,
170 .raster_time = unused_stopwatch,
171 .ui_time = unused_stopwatch,
172 .texture_registry = texture_registry,
173 // clang-format on
174 };
175
176 LayerStateStack paint_state_stack;
177 paint_state_stack.set_delegate(&builder);
178 PaintContext paint_context = {
179 // clang-format off
180 .state_stack = paint_state_stack,
181 .canvas = &builder,
182 .gr_context = gr_context,
183 .dst_color_space = nullptr,
184 .view_embedder = nullptr,
185 .raster_time = unused_stopwatch,
186 .ui_time = unused_stopwatch,
187 .texture_registry = texture_registry,
188#if !SLIMPELLER
189 .raster_cache = nullptr,
190#endif // !SLIMPELLER
191 // clang-format on
192 };
193
194 // Even if we don't have a root layer, we still need to create an empty
195 // picture.
196 if (root_layer_) {
197 root_layer_->Preroll(&preroll_context);
198
199 // The needs painting flag may be set after the preroll. So check it after.
200 if (root_layer_->needs_painting(paint_context)) {
201 root_layer_->Paint(paint_context);
202 }
203 }
204
205 return builder.Build();
206}
207
208} // namespace flutter
impeller::AiksContext * aiks_context() const
const DlMatrix & root_surface_transformation() const
const Stopwatch & raster_time() const
std::shared_ptr< TextureRegistry > texture_registry()
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual SkImageInfo GetImageInfo() const =0
Used for fixed refresh rate cases.
Definition stopwatch.h:80
void set_delegate(DlCanvas *canvas)
void set_preroll_delegate(const DlRect &cull_rect, const DlMatrix &matrix)
sk_sp< DisplayList > Flatten(const DlRect &bounds, const std::shared_ptr< TextureRegistry > &texture_registry=nullptr, GrDirectContext *gr_context=nullptr)
void Paint(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false) const
Definition layer_tree.cc:96
static void TryToRasterCache(const std::vector< RasterCacheItem * > &raster_cached_entries, const PaintContext *paint_context, bool ignore_raster_cache=false)
Definition layer_tree.cc:67
LayerTree(const std::shared_ptr< Layer > &root_layer, const DlISize &frame_size)
Definition layer_tree.cc:20
bool Preroll(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false, DlRect cull_rect=kGiantRect)
Definition layer_tree.cc:28
#define FML_LOG(severity)
Definition logging.h:101
SkColorSpace * GetColorSpace(DlCanvas *canvas)
Definition layer_tree.cc:24
LayerStateStack & state_stack
Definition layer.h:91
GrDirectContext * gr_context
Definition layer.h:47
bool surface_needs_readback
Definition layer.h:51
#define TRACE_EVENT0(category_group, name)