Flutter Engine
The Flutter Engine
entity_pass.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_IMPELLER_ENTITY_ENTITY_PASS_H_
6#define FLUTTER_IMPELLER_ENTITY_ENTITY_PASS_H_
7
8#include <cstdint>
9#include <functional>
10#include <memory>
11#include <optional>
12#include <vector>
13
21
22namespace impeller {
23
24class ContentContext;
25
26/// Specifies how much to trust the bounds rectangle provided for a list
27/// of contents. Used by both |EntityPass| and |Canvas::SaveLayer|.
29 /// @brief The caller makes no claims related to the size of the bounds.
31
32 /// @brief The caller claims the bounds are a reasonably tight estimate
33 /// of the coverage of the contents and should contain all of the
34 /// contents.
36
37 /// @brief The caller claims the bounds are a subset of an estimate of
38 /// the reasonably tight bounds but likely clips off some of the
39 /// contents.
41};
42
44 public:
45 /// Elements are renderable items in the `EntityPass`. Each can either be an
46 /// `Entity` or a child `EntityPass`.
47 ///
48 /// When the element is a child `EntityPass`, it may be rendered to an
49 /// offscreen texture and converted into an `Entity` that draws the texture
50 /// into the current pass, or its children may be collapsed into the current
51 ///
52 /// `EntityPass`. Elements are converted to Entities in
53 /// `GetEntityForElement()`.
54 using Element = std::variant<Entity, std::unique_ptr<EntityPass>>;
55
56 using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
58 const Matrix& effect_transform,
59 Entity::RenderingMode rendering_mode)>;
60
62
64
65 void SetDelegate(std::shared_ptr<EntityPassDelegate> delgate);
66
67 /// @brief Set the bounds limit, which is provided by the user when creating
68 /// a SaveLayer. This is a hint that allows the user to communicate
69 /// that it's OK to not render content outside of the bounds.
70 ///
71 /// For consistency with Skia, we effectively treat this like a
72 /// rectangle clip by forcing the subpass texture size to never exceed
73 /// it.
74 ///
75 /// The entity pass will assume that these bounds cause a clipping
76 /// effect on the layer unless this call is followed up with a
77 /// call to |SetBoundsClipsContent()| specifying otherwise.
78 void SetBoundsLimit(
79 std::optional<Rect> bounds_limit,
81
82 /// @brief Get the bounds limit, which is provided by the user when creating
83 /// a SaveLayer.
84 std::optional<Rect> GetBoundsLimit() const;
85
86 /// @brief Indicates if the bounds limit set using |SetBoundsLimit()|
87 /// might clip the contents of the pass.
89
90 /// @brief Indicates if the bounds limit set using |SetBoundsLimit()|
91 /// is a reasonably tight estimate of the bounds of the contents.
92 bool GetBoundsLimitIsSnug() const;
93
94 size_t GetSubpassesDepth() const;
95
96 /// @brief Add an entity to the current entity pass.
97 void AddEntity(Entity entity);
98
99 void PushClip(Entity entity);
100
101 void PopClips(size_t num_clips, uint64_t depth);
102
103 void PopAllClips(uint64_t depth);
104
105 void SetElements(std::vector<Element> elements);
106
107 //----------------------------------------------------------------------------
108 /// @brief Appends a given pass as a subpass.
109 ///
110 EntityPass* AddSubpass(std::unique_ptr<EntityPass> pass);
111
112 EntityPass* GetSuperpass() const;
113
115 const RenderTarget& render_target) const;
116
117 /// @brief Iterate all elements (entities and subpasses) in this pass,
118 /// recursively including elements of child passes. The iteration
119 /// order is depth-first. Whenever a subpass elements is encountered,
120 /// it's included in the stream before its children.
121 void IterateAllElements(const std::function<bool(Element&)>& iterator);
122
124 const std::function<bool(const Element&)>& iterator) const;
125
126 //----------------------------------------------------------------------------
127 /// @brief Iterate all entities in this pass, recursively including entities
128 /// of child passes. The iteration order is depth-first.
129 ///
130 void IterateAllEntities(const std::function<bool(Entity&)>& iterator);
131
132 //----------------------------------------------------------------------------
133 /// @brief Iterate all entities in this pass, recursively including entities
134 /// of child passes. The iteration order is depth-first and does not
135 /// allow modification of the entities.
136 ///
138 const std::function<bool(const Entity&)>& iterator) const;
139
140 //----------------------------------------------------------------------------
141 /// @brief Iterate entities in this pass up until the first subpass is found.
142 /// This is useful for limiting look-ahead optimizations.
143 ///
144 /// @return Returns whether a subpass was encountered.
145 ///
146 bool IterateUntilSubpass(const std::function<bool(Entity&)>& iterator);
147
148 //----------------------------------------------------------------------------
149 /// @brief Return the number of elements on this pass.
150 ///
151 size_t GetElementCount() const;
152
154
155 void SetClipHeight(size_t clip_height);
156
157 size_t GetClipHeight() const;
158
159 void SetClipDepth(size_t clip_depth);
160
161 uint32_t GetClipDepth() const;
162
163 void SetBlendMode(BlendMode blend_mode);
164
165 /// @brief Return the premultiplied clear color of the pass entities, if any.
166 std::optional<Color> GetClearColor(ISize size = ISize::Infinite()) const;
167
168 /// @brief Return the premultiplied clear color of the pass entities.
169 ///
170 /// If the entity pass has no clear color, this will return transparent black.
172
174
175 int32_t GetRequiredMipCount() const { return required_mip_count_; }
176
177 void SetRequiredMipCount(int32_t mip_count) {
178 required_mip_count_ = mip_count;
179 }
180
181 //----------------------------------------------------------------------------
182 /// @brief Computes the coverage of a given subpass. This is used to
183 /// determine the texture size of a given subpass before it's rendered
184 /// to and passed through the subpass ImageFilter, if any.
185 ///
186 /// @param[in] subpass The EntityPass for which to compute
187 /// pre-filteredcoverage.
188 /// @param[in] coverage_limit Confines coverage to a specified area. This
189 /// hint is used to trim coverage to the root
190 /// framebuffer area. `std::nullopt` means there
191 /// is no limit.
192 ///
193 /// @return The screen space pixel area that the subpass contents will render
194 /// into, prior to being transformed by the subpass ImageFilter, if
195 /// any. `std::nullopt` means rendering the subpass will have no
196 /// effect on the color attachment.
197 ///
198 std::optional<Rect> GetSubpassCoverage(
199 const EntityPass& subpass,
200 std::optional<Rect> coverage_limit) const;
201
202 std::optional<Rect> GetElementsCoverage(
203 std::optional<Rect> coverage_limit) const;
204
205 private:
206 struct EntityResult {
207 enum Status {
208 /// The entity was successfully resolved and can be rendered.
209 kSuccess,
210 /// An unexpected rendering error occurred while resolving the Entity.
211 kFailure,
212 /// The entity should be skipped because rendering it will contribute
213 /// nothing to the frame.
214 kSkip,
215 };
216
217 /// @brief The resulting entity that should be rendered. If `std::nullopt`,
218 /// there is nothing to render.
219 Entity entity;
220 /// @brief This is set to `false` if there was an unexpected rendering
221 /// error while resolving the Entity.
222 Status status = kFailure;
223
224 static EntityResult Success(Entity e) { return {std::move(e), kSuccess}; }
225 static EntityResult Failure() { return {{}, kFailure}; }
226 static EntityResult Skip() { return {{}, kSkip}; }
227 };
228
229 bool RenderElement(Entity& element_entity,
230 size_t clip_height_floor,
231 InlinePassContext& pass_context,
232 int32_t pass_depth,
233 ContentContext& renderer,
234 EntityPassClipStack& clip_coverage_stack,
235 Point global_pass_position) const;
236
237 EntityResult GetEntityForElement(const EntityPass::Element& element,
238 ContentContext& renderer,
239 InlinePassContext& pass_context,
240 ISize root_pass_size,
241 Point global_pass_position,
242 uint32_t pass_depth,
243 EntityPassClipStack& clip_coverage_stack,
244 size_t clip_height_floor) const;
245
246 //----------------------------------------------------------------------------
247 /// @brief OnRender is the internal command recording routine for
248 /// `EntityPass`. Its job is to walk through each `Element` which
249 /// was appended to the scene (either an `Entity` via `AddEntity()`
250 /// or a child `EntityPass` via `AddSubpass()`) and render them to
251 /// the given `pass_target`.
252 /// @param[in] renderer The Contents context, which manages
253 /// pipeline state.
254 /// @param[in] root_pass_size The size of the texture being
255 /// rendered into at the root of the
256 /// `EntityPass` tree. This is the size
257 /// of the `RenderTarget` color
258 /// attachment passed to the public
259 /// `EntityPass::Render` method.
260 /// @param[out] pass_target Stores the render target that should
261 /// be used for rendering.
262 /// @param[in] global_pass_position The position that this `EntityPass`
263 /// will be drawn to the parent pass
264 /// relative to the root pass origin.
265 /// Used for offsetting drawn `Element`s,
266 /// whose origins are all in root
267 /// pass/screen space,
268 /// @param[in] local_pass_position The position that this `EntityPass`
269 /// will be drawn to the parent pass
270 /// relative to the parent pass origin.
271 /// Used for positioning backdrop
272 /// filters.
273 /// @param[in] pass_depth The tree depth of the `EntityPass` at
274 /// render time. Only used for labeling
275 /// and debugging purposes. This can vary
276 /// depending on whether passes are
277 /// collapsed or not.
278 /// @param[in] clip_coverage_stack A global stack of coverage rectangles
279 /// for the clip buffer at each depth.
280 /// Higher depths are more restrictive.
281 /// Used to cull Elements that we
282 /// know won't result in a visible
283 /// change.
284 /// @param[in] clip_height_floor The clip depth that a value of
285 /// zero corresponds to in the given
286 /// `pass_target` clip buffer.
287 /// When new `pass_target`s are created
288 /// for subpasses, their clip buffers are
289 /// initialized at zero, and so this
290 /// value is used to offset Entity clip
291 /// depths to match the clip buffer.
292 /// @param[in] backdrop_filter_contents Optional. Is supplied, this contents
293 /// is rendered prior to anything else in
294 /// the `EntityPass`, offset by the
295 /// `local_pass_position`.
296 /// @param[in] collapsed_parent_pass Optional. If supplied, this
297 /// `InlinePassContext` state is used to
298 /// begin rendering elements instead of
299 /// creating a new `RenderPass`. This
300 /// "collapses" the Elements into the
301 /// parent pass.
302 ///
303 bool OnRender(ContentContext& renderer,
304 ISize root_pass_size,
305 EntityPassTarget& pass_target,
306 Point global_pass_position,
307 Point local_pass_position,
308 uint32_t pass_depth,
309 EntityPassClipStack& clip_coverage_stack,
310 size_t clip_height_floor = 0,
311 std::shared_ptr<Contents> backdrop_filter_contents = nullptr,
312 const std::optional<InlinePassContext::RenderPassResult>&
313 collapsed_parent_pass = std::nullopt) const;
314
315 /// The list of renderable items in the scene. Each of these items is
316 /// evaluated and recorded to an `EntityPassTarget` by the `OnRender` method.
317 std::vector<Element> elements_;
318
319 /// The stack of currently active clips (during Aiks recording time). Each
320 /// entry is an index into the `elements_` list. The depth value of a clip is
321 /// the max of all the entities it affects, so assignment of the depth value
322 /// is deferred until clip restore or end of the EntityPass.
323 std::vector<size_t> active_clips_;
324
325 EntityPass* superpass_ = nullptr;
326 Matrix transform_;
327 size_t clip_height_ = 0u;
328 uint32_t clip_depth_ = 1u;
329 BlendMode blend_mode_ = BlendMode::kSourceOver;
330 bool flood_clip_ = false;
331 std::optional<Rect> bounds_limit_;
333 int32_t required_mip_count_ = 1;
334
335 /// These values indicate whether something has been added to the EntityPass
336 /// that requires reading from the backdrop texture. Currently, this can
337 /// happen in the following scenarios:
338 /// 1. An entity with an "advanced blend" is added to the pass.
339 /// 2. A subpass with a backdrop filter is added to the pass.
340 /// These are tracked as separate values because we may ignore
341 /// `blend_reads_from_pass_texture_` if the device supports framebuffer based
342 /// advanced blends.
343 bool advanced_blend_reads_from_pass_texture_ = false;
344 bool backdrop_filter_reads_from_pass_texture_ = false;
345
346 bool DoesBackdropGetRead(ContentContext& renderer) const;
347
348 BackdropFilterProc backdrop_filter_proc_ = nullptr;
349
350 std::shared_ptr<EntityPassDelegate> delegate_ =
352
353 EntityPass(const EntityPass&) = delete;
354
355 EntityPass& operator=(const EntityPass&) = delete;
356};
357
358} // namespace impeller
359
360#endif // FLUTTER_IMPELLER_ENTITY_ENTITY_PASS_H_
static std::unique_ptr< EntityPassDelegate > MakeDefault()
bool IterateUntilSubpass(const std::function< bool(Entity &)> &iterator)
Iterate entities in this pass up until the first subpass is found. This is useful for limiting look-a...
void SetElements(std::vector< Element > elements)
Definition: entity_pass.cc:139
void IterateAllElements(const std::function< bool(Element &)> &iterator)
Iterate all elements (entities and subpasses) in this pass, recursively including elements of child p...
Definition: entity_pass.cc:995
std::variant< Entity, std::unique_ptr< EntityPass > > Element
Definition: entity_pass.h:54
size_t GetElementCount() const
Return the number of elements on this pass.
void SetRequiredMipCount(int32_t mip_count)
Definition: entity_pass.h:177
bool GetBoundsLimitMightClipContent() const
Indicates if the bounds limit set using |SetBoundsLimit()| might clip the contents of the pass.
Definition: entity_pass.cc:69
void SetBoundsLimit(std::optional< Rect > bounds_limit, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown)
Set the bounds limit, which is provided by the user when creating a SaveLayer. This is a hint that al...
Definition: entity_pass.cc:58
Color GetClearColorOrDefault(ISize size=ISize::Infinite()) const
Return the premultiplied clear color of the pass entities.
void SetClipDepth(size_t clip_depth)
void AddEntity(Entity entity)
Add an entity to the current entity pass.
Definition: entity_pass.cc:100
size_t GetClipHeight() const
void SetBackdropFilter(BackdropFilterProc proc)
bool GetBoundsLimitIsSnug() const
Indicates if the bounds limit set using |SetBoundsLimit()| is a reasonably tight estimate of the boun...
Definition: entity_pass.cc:88
std::optional< Rect > GetBoundsLimit() const
Get the bounds limit, which is provided by the user when creating a SaveLayer.
Definition: entity_pass.cc:65
EntityPass * GetSuperpass() const
Definition: entity_pass.cc:263
size_t GetSubpassesDepth() const
Definition: entity_pass.cc:143
void PopClips(size_t num_clips, uint64_t depth)
Definition: entity_pass.cc:117
int32_t GetRequiredMipCount() const
Definition: entity_pass.h:175
void SetClipHeight(size_t clip_height)
std::optional< Color > GetClearColor(ISize size=ISize::Infinite()) const
Return the premultiplied clear color of the pass entities, if any.
void SetBlendMode(BlendMode blend_mode)
void SetTransform(Matrix transform)
void IterateAllEntities(const std::function< bool(Entity &)> &iterator)
Iterate all entities in this pass, recursively including entities of child passes....
std::optional< Rect > GetSubpassCoverage(const EntityPass &subpass, std::optional< Rect > coverage_limit) const
Computes the coverage of a given subpass. This is used to determine the texture size of a given subpa...
Definition: entity_pass.cc:231
void PopAllClips(uint64_t depth)
Definition: entity_pass.cc:135
EntityPass * AddSubpass(std::unique_ptr< EntityPass > pass)
Appends a given pass as a subpass.
Definition: entity_pass.cc:267
void SetDelegate(std::shared_ptr< EntityPassDelegate > delgate)
Definition: entity_pass.cc:51
bool Render(ContentContext &renderer, const RenderTarget &render_target) const
Definition: entity_pass.cc:354
std::optional< Rect > GetElementsCoverage(std::optional< Rect > coverage_limit) const
Definition: entity_pass.cc:154
void PushClip(Entity entity)
Definition: entity_pass.cc:112
uint32_t GetClipDepth() const
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)> BackdropFilterProc
Definition: entity_pass.h:59
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
@ kSuccess
Definition: embedder.h:73
Dart_NativeFunction function
Definition: fuchsia.cc:51
Definition: dart.idl:42
static TTSTestCase Failure(const TTSTestCase &original)
@ kFailure
Failed to make the egl context for the surface current.
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
TPoint< Scalar > Point
Definition: point.h:322
BlendMode
Definition: color.h:59
ContentBoundsPromise
Definition: entity_pass.h:28
@ kUnknown
The caller makes no claims related to the size of the bounds.
@ kMayClipContents
The caller claims the bounds are a subset of an estimate of the reasonably tight bounds but likely cl...
@ kContainsContents
The caller claims the bounds are a reasonably tight estimate of the coverage of the contents and shou...
ISize64 ISize
Definition: size.h:140
SK_API sk_sp< PrecompileColorFilter > Matrix()
Task::Status Status
Definition: TaskList.cpp:15
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
static constexpr TSize Infinite()
Definition: size.h:38