Flutter Engine
The Flutter Engine
layer.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_LAYERS_LAYER_H_
6#define FLUTTER_FLOW_LAYERS_LAYER_H_
7
8#include <algorithm>
9#include <memory>
10#include <unordered_set>
11#include <vector>
12
13#include "flutter/common/graphics/texture.h"
14#include "flutter/common/macros.h"
15#include "flutter/display_list/dl_canvas.h"
16#include "flutter/flow/diff_context.h"
17#include "flutter/flow/embedded_views.h"
18#include "flutter/flow/layer_snapshot_store.h"
19#include "flutter/flow/layers/layer_state_stack.h"
20#include "flutter/flow/raster_cache.h"
21#include "flutter/flow/stopwatch.h"
22#include "flutter/fml/build_config.h"
23#include "flutter/fml/compiler_specific.h"
24#include "flutter/fml/logging.h"
25#include "flutter/fml/macros.h"
26#include "flutter/fml/trace_event.h"
35
36class GrDirectContext;
37
38namespace flutter {
39
40namespace testing {
41class MockLayer;
42} // namespace testing
43
44class ContainerLayer;
45class DisplayListLayer;
46class PerformanceOverlayLayer;
47class TextureLayer;
48class RasterCacheItem;
49
50static constexpr SkRect kGiantRect = SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
51
52// This should be an exact copy of the Clip enum in painting.dart.
54
62
63 // These allow us to paint in the end of subtree Preroll.
66 std::shared_ptr<TextureRegistry> texture_registry;
67
68 // These allow us to track properties like elevation, opacity, and the
69 // presence of a platform view during Preroll.
70 bool has_platform_view = false;
71 // These allow us to track properties like elevation, opacity, and the
72 // presence of a texture layer during Preroll.
73 bool has_texture_layer = false;
74
75 // The list of flags that describe which rendering state attributes
76 // (such as opacity, ColorFilter, ImageFilter) a given layer can
77 // render itself without requiring the parent to perform a protective
78 // saveLayer with those attributes.
79 // For containers, the flags will be set to the intersection (logical
80 // and) of all of the state bits that all of the children can render
81 // or to 0 if some of the children overlap and, as such, cannot apply
82 // those attributes individually and separately.
84
85 std::vector<RasterCacheItem*>* raster_cached_entries;
86};
87
89 // When splitting the scene into multiple canvases (e.g when embedding
90 // a platform view on iOS) during the paint traversal we apply any state
91 // changes which affect children (i.e. saveLayer attributes) to the
92 // state_stack and any local rendering state changes for leaf layers to
93 // the canvas or builder.
94 // When we switch a canvas or builder (when painting a PlatformViewLayer)
95 // the new canvas receives all of the stateful changes from the state_stack
96 // to put it into the exact same state that the outgoing canvas had at the
97 // time it was swapped out.
98 // The state stack lazily applies saveLayer calls to its current canvas,
99 // allowing leaf layers to report that they can handle rendering some of
100 // its state attributes themselves via the |applyState| method.
103
104 // Whether current canvas is an overlay canvas. Used to determine if the
105 // raster cache is painting to a surface that will be displayed above a
106 // platform view, in which case it will attempt to preserve the R-Tree.
108
114 std::shared_ptr<TextureRegistry> texture_registry;
115 NOT_SLIMPELLER(const RasterCache* raster_cache);
116
117 // Snapshot store to collect leaf layer snapshots. The store is non-null
118 // only when leaf layer tracing is enabled.
121 bool impeller_enabled = false;
123};
124
125// Represents a single composited layer. Created on the UI thread but then
126// subsequently used on the Rasterizer thread.
127class Layer {
128 public:
129 // The state attribute flags that represent which attributes a
130 // layer can render if it plans to use a saveLayer call in its
131 // |Paint| method.
132 static constexpr int kSaveLayerRenderFlags =
136
137 // The state attribute flags that represent which attributes a
138 // layer can render if it will be rendering its content/children
139 // from a cached representation.
140 static constexpr int kRasterCacheRenderFlags =
142
143 Layer();
144 virtual ~Layer();
145
146 void AssignOldLayer(Layer* old_layer) {
147 original_layer_id_ = old_layer->original_layer_id_;
148 }
149
150 // Used to establish link between old layer and new layer that replaces it.
151 // If this method returns true, it is assumed that this layer replaces the old
152 // layer in tree and is able to diff with it.
153 virtual bool IsReplacing(DiffContext* context, const Layer* old_layer) const {
154 return original_layer_id_ == old_layer->original_layer_id_;
155 }
156
157 // Performs diff with given layer
158 virtual void Diff(DiffContext* context, const Layer* old_layer) {}
159
160 // Used when diffing retained layer; In case the layer is identical, it
161 // doesn't need to be diffed, but the paint region needs to be stored in diff
162 // context so that it can be used in next frame
163 virtual void PreservePaintRegion(DiffContext* context) {
164 // retained layer means same instance so 'this' is used to index into both
165 // current and old region
166 context->SetLayerPaintRegion(this, context->GetOldLayerPaintRegion(this));
167 }
168
169 virtual void Preroll(PrerollContext* context) = 0;
170
171 // Used during Preroll by layers that employ a saveLayer to manage the
172 // PrerollContext settings with values affected by the saveLayer mechanism.
173 // This object must be created before calling Preroll on the children to
174 // set up the state for the children and then restore the state upon
175 // destruction.
177 public:
178 [[nodiscard]] static AutoPrerollSaveLayerState Create(
179 PrerollContext* preroll_context,
180 bool save_layer_is_active = true,
181 bool layer_itself_performs_readback = false);
182
184
185 private:
187 bool save_layer_is_active,
188 bool layer_itself_performs_readback);
189
190 PrerollContext* preroll_context_;
191 bool save_layer_is_active_;
192 bool layer_itself_performs_readback_;
193
194 bool prev_surface_needs_readback_;
195 };
196
197 virtual void Paint(PaintContext& context) const = 0;
198
199 virtual void PaintChildren(PaintContext& context) const { FML_DCHECK(false); }
200
201 bool subtree_has_platform_view() const { return subtree_has_platform_view_; }
203 subtree_has_platform_view_ = value;
204 }
205
206 // Returns the paint bounds in the layer's local coordinate system
207 // as determined during Preroll(). The bounds should include any
208 // transform, clip or distortions performed by the layer itself,
209 // but not any similar modifications inherited from its ancestors.
210 const SkRect& paint_bounds() const { return paint_bounds_; }
211
212 // This must be set by the time Preroll() returns otherwise the layer will
213 // be assumed to have empty paint bounds (paints no content).
214 // The paint bounds should be independent of the context outside of this
215 // layer as the layer may be painted under different conditions than
216 // the Preroll context. The most common example of this condition is
217 // that we might Preroll the layer with a cull_rect established by a
218 // clip layer above it but then we might be asked to paint anyway if
219 // another layer above us needs to cache its children. During the
220 // paint operation that arises due to the caching, the clip will
221 // be the bounds of the layer needing caching, not the cull_rect
222 // that we saw in the overall Preroll operation.
224 paint_bounds_ = paint_bounds;
225 }
226
227 // Determines if the layer has any content.
228 bool is_empty() const { return paint_bounds_.isEmpty(); }
229
230 // Determines if the Paint() method is necessary based on the properties
231 // of the indicated PaintContext object.
232 bool needs_painting(PaintContext& context) const {
233 if (subtree_has_platform_view_) {
234 // Workaround for the iOS embedder. The iOS embedder expects that
235 // if we preroll it, then we will later call its Paint() method.
236 // Now that we preroll all layers without any culling, we may
237 // call its Preroll() without calling its Paint(). For now, we
238 // will not perform paint culling on any subtree that has a
239 // platform view.
240 // See https://github.com/flutter/flutter/issues/81419
241 return true;
242 }
243 return !context.state_stack.painting_is_nop() &&
244 !context.state_stack.content_culled(paint_bounds_);
245 }
246
247 // Propagated unique_id of the first layer in "chain" of replacement layers
248 // that can be diffed.
249 uint64_t original_layer_id() const { return original_layer_id_; }
250
251 uint64_t unique_id() const { return unique_id_; }
252
253#if !SLIMPELLER
256 }
257#endif // !SLIMPELLER
258 virtual const ContainerLayer* as_container_layer() const { return nullptr; }
260 return nullptr;
261 }
262 virtual const TextureLayer* as_texture_layer() const { return nullptr; }
264 return nullptr;
265 }
266 virtual const testing::MockLayer* as_mock_layer() const { return nullptr; }
267
268 private:
269 SkRect paint_bounds_;
270 uint64_t unique_id_;
271 uint64_t original_layer_id_;
272 bool subtree_has_platform_view_ = false;
273
274 static uint64_t NextUniqueID();
275
276 FML_DISALLOW_COPY_AND_ASSIGN(Layer);
277};
278
279} // namespace flutter
280
281#endif // FLUTTER_FLOW_LAYERS_LAYER_H_
void SetLayerPaintRegion(const Layer *layer, const PaintRegion &region)
PaintRegion GetOldLayerPaintRegion(const Layer *layer) const
Developer-facing API for rendering anything within the engine.
Definition: dl_canvas.h:38
Collects snapshots of layers during frame rasterization.
static constexpr int kCallerCanApplyColorFilter
bool content_culled(const SkRect &content_bounds) const
static constexpr int kCallerCanApplyImageFilter
static constexpr int kCallerCanApplyOpacity
static AutoPrerollSaveLayerState Create(PrerollContext *preroll_context, bool save_layer_is_active=true, bool layer_itself_performs_readback=false)
Definition: layer.cc:40
virtual void Diff(DiffContext *context, const Layer *old_layer)
Definition: layer.h:158
virtual void Preroll(PrerollContext *context)=0
uint64_t original_layer_id() const
Definition: layer.h:249
virtual RasterCacheKeyID caching_key_id() const
Definition: layer.h:254
virtual ~Layer()
bool is_empty() const
Definition: layer.h:228
virtual void PreservePaintRegion(DiffContext *context)
Definition: layer.h:163
const SkRect & paint_bounds() const
Definition: layer.h:210
virtual const testing::MockLayer * as_mock_layer() const
Definition: layer.h:266
static constexpr int kSaveLayerRenderFlags
Definition: layer.h:132
void set_subtree_has_platform_view(bool value)
Definition: layer.h:202
void AssignOldLayer(Layer *old_layer)
Definition: layer.h:146
static constexpr int kRasterCacheRenderFlags
Definition: layer.h:140
virtual void PaintChildren(PaintContext &context) const
Definition: layer.h:199
virtual bool IsReplacing(DiffContext *context, const Layer *old_layer) const
Definition: layer.h:153
virtual const PerformanceOverlayLayer * as_performance_overlay_layer() const
Definition: layer.h:263
bool subtree_has_platform_view() const
Definition: layer.h:201
bool needs_painting(PaintContext &context) const
Definition: layer.h:232
virtual const DisplayListLayer * as_display_list_layer() const
Definition: layer.h:259
virtual void Paint(PaintContext &context) const =0
virtual const ContainerLayer * as_container_layer() const
Definition: layer.h:258
virtual const TextureLayer * as_texture_layer() const
Definition: layer.h:262
uint64_t unique_id() const
Definition: layer.h:251
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:223
uint8_t value
#define FML_DCHECK(condition)
Definition: logging.h:103
Clip
Definition: layer.h:53
@ kAntiAlias
Definition: layer.h:53
@ kAntiAliasWithSaveLayer
Definition: layer.h:53
@ kNone
Definition: layer.h:53
@ kHardEdge
Definition: layer.h:53
static constexpr SkRect kGiantRect
Definition: layer.h:50
bool isEmpty() const
Definition: SkRect.h:693
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646
bool enable_leaf_layer_tracing
Definition: layer.h:120
NOT_SLIMPELLER(const RasterCache *raster_cache)
ExternalViewEmbedder * view_embedder
Definition: layer.h:111
impeller::AiksContext * aiks_context
Definition: layer.h:122
bool rendering_above_platform_view
Definition: layer.h:107
sk_sp< SkColorSpace > dst_color_space
Definition: layer.h:110
const Stopwatch & raster_time
Definition: layer.h:112
const Stopwatch & ui_time
Definition: layer.h:113
LayerSnapshotStore * layer_snapshot_store
Definition: layer.h:119
std::shared_ptr< TextureRegistry > texture_registry
Definition: layer.h:114
DlCanvas * canvas
Definition: layer.h:102
GrDirectContext * gr_context
Definition: layer.h:109
LayerStateStack & state_stack
Definition: layer.h:101
GrDirectContext * gr_context
Definition: layer.h:57
std::vector< RasterCacheItem * > * raster_cached_entries
Definition: layer.h:85
std::shared_ptr< TextureRegistry > texture_registry
Definition: layer.h:66
const Stopwatch & ui_time
Definition: layer.h:65
const Stopwatch & raster_time
Definition: layer.h:64
sk_sp< SkColorSpace > dst_color_space
Definition: layer.h:60
NOT_SLIMPELLER(RasterCache *raster_cache)
LayerStateStack & state_stack
Definition: layer.h:59
bool surface_needs_readback
Definition: layer.h:61
int renderable_state_flags
Definition: layer.h:83
ExternalViewEmbedder * view_embedder
Definition: layer.h:58