| Flutter Impeller |

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
14 #include "impeller/entity/contents/contents.h"
15 #include "impeller/entity/contents/filters/filter_contents.h"
16 #include "impeller/entity/entity.h"
17 #include "impeller/entity/entity_pass_delegate.h"
18 #include "impeller/entity/inline_pass_context.h"
19 #include "impeller/renderer/render_target.h"
20
21 namespace impeller {
22
23 class ContentContext;
24
25 class EntityPass {
26 public:
27 /// Elements are renderable items in the `EntityPass`. Each can either be an
28 /// `Entity` or a child `EntityPass`.
29 ///
30 /// When the element is a child `EntityPass`, it may be rendered to an
31 /// offscreen texture and converted into an `Entity` that draws the texture
32 /// into the current pass, or its children may be collapsed into the current
33 ///
34 /// `EntityPass`. Elements are converted to Entities in
35 /// `GetEntityForElement()`.
36 using Element = std::variant<Entity, std::unique_ptr<EntityPass>>;
37
38 static const std::string kCaptureDocumentName;
39
40 using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
41 FilterInput::Ref,
42 const Matrix& effect_transform,
43 Entity::RenderingMode rendering_mode)>;
44
45 struct ClipCoverageLayer {
46 std::optional<Rect> coverage;
47 size_t clip_depth;
48 };
49
50 using ClipCoverageStack = std::vector<ClipCoverageLayer>;
51
52 EntityPass();
53
54 ~EntityPass();
55
56 void SetDelegate(std::shared_ptr<EntityPassDelegate> delgate);
57
58 /// @brief Set the bounds limit, which is provided by the user when creating
59 /// a SaveLayer. This is a hint that allows the user to communicate
60 /// that it's OK to not render content outside of the bounds.
61 ///
62 /// For consistency with Skia, we effectively treat this like a
63 /// rectangle clip by forcing the subpass texture size to never exceed
64 /// it.
65 void SetBoundsLimit(std::optional<Rect> bounds_limit);
66
67 /// @brief Get the bounds limit, which is provided by the user when creating
68 /// a SaveLayer.
69 std::optional<Rect> GetBoundsLimit() const;
70
71 size_t GetSubpassesDepth() const;
72
73 std::unique_ptr<EntityPass> Clone() const;
74
75 /// @brief Add an entity to the current entity pass.
76 void AddEntity(Entity entity);
77
78 void SetElements(std::vector<Element> elements);
79
80 //----------------------------------------------------------------------------
81 /// @brief Appends a given pass as a subpass.
82 ///
83 EntityPass* AddSubpass(std::unique_ptr<EntityPass> pass);
84
85 //----------------------------------------------------------------------------
86 /// @brief Merges a given pass into this pass. Useful for drawing
87 /// pre-recorded pictures that don't require rendering into a separate
88 /// subpass.
89 ///
90 void AddSubpassInline(std::unique_ptr<EntityPass> pass);
91
92 EntityPass* GetSuperpass() const;
93
94 bool Render(ContentContext& renderer,
95 const RenderTarget& render_target) const;
96
97 /// @brief Iterate all elements (entities and subpasses) in this pass,
98 /// recursively including elements of child passes. The iteration
99 /// order is depth-first. Whenever a subpass elements is encountered,
100 /// it's included in the stream before its children.
101 void IterateAllElements(const std::function<bool(Element&)>& iterator);
102
103 //----------------------------------------------------------------------------
104 /// @brief Iterate all entities in this pass, recursively including entities
105 /// of child passes. The iteration order is depth-first.
106 ///
107 void IterateAllEntities(const std::function<bool(Entity&)>& iterator);
108
109 //----------------------------------------------------------------------------
110 /// @brief Iterate all entities in this pass, recursively including entities
111 /// of child passes. The iteration order is depth-first and does not
112 /// allow modification of the entities.
113 ///
114 void IterateAllEntities(
115 const std::function<bool(const Entity&)>& iterator) const;
116
117 //----------------------------------------------------------------------------
118 /// @brief Iterate entities in this pass up until the first subpass is found.
119 /// This is useful for limiting look-ahead optimizations.
120 ///
121 /// @return Returns whether a subpass was encountered.
122 ///
123 bool IterateUntilSubpass(const std::function<bool(Entity&)>& iterator);
124
125 //----------------------------------------------------------------------------
126 /// @brief Return the number of elements on this pass.
127 ///
128 size_t GetElementCount() const;
129
130 void SetTransform(Matrix transform);
131
132 void SetClipDepth(size_t clip_depth);
133
134 size_t GetClipDepth();
135
136 void SetBlendMode(BlendMode blend_mode);
137
138 /// @brief Return the premultiplied clear color of the pass entities, if any.
139 std::optional<Color> GetClearColor(ISize size = ISize::Infinite()) const;
140
141 /// @brief Return the premultiplied clear color of the pass entities.
142 ///
143 /// If the entity pass has no clear color, this will return transparent black.
144 Color GetClearColorOrDefault(ISize size = ISize::Infinite()) const;
145
146 void SetBackdropFilter(BackdropFilterProc proc);
147
148 void SetEnableOffscreenCheckerboard(bool enabled);
149
150 //----------------------------------------------------------------------------
151 /// @brief Computes the coverage of a given subpass. This is used to
152 /// determine the texture size of a given subpass before it's rendered
153 /// to and passed through the subpass ImageFilter, if any.
154 ///
155 /// @param[in] subpass The EntityPass for which to compute
156 /// pre-filteredcoverage.
157 /// @param[in] coverage_limit Confines coverage to a specified area. This
158 /// hint is used to trim coverage to the root
159 /// framebuffer area. `std::nullopt` means there
160 /// is no limit.
161 ///
162 /// @return The screen space pixel area that the subpass contents will render
163 /// into, prior to being transformed by the subpass ImageFilter, if
164 /// any. `std::nullopt` means rendering the subpass will have no
165 /// effect on the color attachment.
166 ///
167 std::optional<Rect> GetSubpassCoverage(
168 const EntityPass& subpass,
169 std::optional<Rect> coverage_limit) const;
170
171 std::optional<Rect> GetElementsCoverage(
172 std::optional<Rect> coverage_limit) const;
173
174 private:
175 struct EntityResult {
176 enum Status {
177 /// The entity was successfully resolved and can be rendered.
178 kSuccess,
179 /// An unexpected rendering error occurred while resolving the Entity.
180 kFailure,
181 /// The entity should be skipped because rendering it will contribute
182 /// nothing to the frame.
183 kSkip,
184 };
185
186 /// @brief The resulting entity that should be rendered. If `std::nullopt`,
187 /// there is nothing to render.
188 Entity entity;
189 /// @brief This is set to `false` if there was an unexpected rendering
190 /// error while resolving the Entity.
191 Status status = kFailure;
192
193 static EntityResult Success(Entity e) { return {std::move(e), kSuccess}; }
194 static EntityResult Failure() { return {{}, kFailure}; }
195 static EntityResult Skip() { return {{}, kSkip}; }
196 };
197
198 bool RenderElement(Entity& element_entity,
199 size_t clip_depth_floor,
200 InlinePassContext& pass_context,
201 int32_t pass_depth,
202 ContentContext& renderer,
203 ClipCoverageStack& clip_coverage_stack,
204 Point global_pass_position) const;
205
206 EntityResult GetEntityForElement(const EntityPass::Element& element,
207 ContentContext& renderer,
208 Capture& capture,
209 InlinePassContext& pass_context,
210 ISize root_pass_size,
211 Point global_pass_position,
212 uint32_t pass_depth,
213 ClipCoverageStack& clip_coverage_stack,
214 size_t clip_depth_floor) const;
215
216 //----------------------------------------------------------------------------
217 /// @brief OnRender is the internal command recording routine for
218 /// `EntityPass`. Its job is to walk through each `Element` which
219 /// was appended to the scene (either an `Entity` via `AddEntity()`
220 /// or a child `EntityPass` via `AddSubpass()`) and render them to
221 /// the given `pass_target`.
222 /// @param[in] renderer The Contents context, which manages
223 /// pipeline state.
224 /// @param[in] root_pass_size The size of the texture being
225 /// rendered into at the root of the
226 /// `EntityPass` tree. This is the size
227 /// of the `RenderTarget` color
228 /// attachment passed to the public
229 /// `EntityPass::Render` method.
230 /// @param[out] pass_target Stores the render target that should
231 /// be used for rendering.
232 /// @param[in] global_pass_position The position that this `EntityPass`
233 /// will be drawn to the parent pass
234 /// relative to the root pass origin.
235 /// Used for offsetting drawn `Element`s,
236 /// whose origins are all in root
237 /// pass/screen space,
238 /// @param[in] local_pass_position The position that this `EntityPass`
239 /// will be drawn to the parent pass
240 /// relative to the parent pass origin.
241 /// Used for positioning backdrop
242 /// filters.
243 /// @param[in] pass_depth The tree depth of the `EntityPass` at
244 /// render time. Only used for labeling
245 /// and debugging purposes. This can vary
246 /// depending on whether passes are
247 /// collapsed or not.
248 /// @param[in] clip_coverage_stack A global stack of coverage rectangles
249 /// for the clip buffer at each depth.
250 /// Higher depths are more restrictive.
251 /// Used to cull Elements that we
252 /// know won't result in a visible
253 /// change.
254 /// @param[in] clip_depth_floor The clip depth that a value of
255 /// zero corresponds to in the given
256 /// `pass_target` clip buffer.
257 /// When new `pass_target`s are created
258 /// for subpasses, their clip buffers are
259 /// initialized at zero, and so this
260 /// value is used to offset Entity clip
261 /// depths to match the clip buffer.
262 /// @param[in] backdrop_filter_contents Optional. Is supplied, this contents
263 /// is rendered prior to anything else in
264 /// the `EntityPass`, offset by the
265 /// `local_pass_position`.
266 /// @param[in] collapsed_parent_pass Optional. If supplied, this
267 /// `InlinePassContext` state is used to
268 /// begin rendering elements instead of
269 /// creating a new `RenderPass`. This
270 /// "collapses" the Elements into the
271 /// parent pass.
272 ///
273 bool OnRender(ContentContext& renderer,
274 Capture& capture,
275 ISize root_pass_size,
276 EntityPassTarget& pass_target,
277 Point global_pass_position,
278 Point local_pass_position,
279 uint32_t pass_depth,
280 ClipCoverageStack& clip_coverage_stack,
281 size_t clip_depth_floor = 0,
282 std::shared_ptr<Contents> backdrop_filter_contents = nullptr,
283 const std::optional<InlinePassContext::RenderPassResult>&
284 collapsed_parent_pass = std::nullopt) const;
285
286 /// The list of renderable items in the scene. Each of these items is
287 /// evaluated and recorded to an `EntityPassTarget` by the `OnRender` method.
288 std::vector<Element> elements_;
289
290 EntityPass* superpass_ = nullptr;
291 Matrix transform_;
292 size_t clip_depth_ = 0u;
293 BlendMode blend_mode_ = BlendMode::kSourceOver;
294 bool flood_clip_ = false;
295 bool enable_offscreen_debug_checkerboard_ = false;
296 std::optional<Rect> bounds_limit_;
297
298 /// These values are incremented whenever something is added to the pass that
299 /// requires reading from the backdrop texture. Currently, this can happen in
300 /// the following scenarios:
301 /// 1. An entity with an "advanced blend" is added to the pass.
302 /// 2. A subpass with a backdrop filter is added to the pass.
303 /// These are tracked as separate values because we may ignore
304 /// blend_reads_from_pass_texture_ if the device supports framebuffer based
305 /// advanced blends.
306 uint32_t advanced_blend_reads_from_pass_texture_ = 0;
307 uint32_t backdrop_filter_reads_from_pass_texture_ = 0;
308
309 uint32_t GetTotalPassReads(ContentContext& renderer) const;
310
311 BackdropFilterProc backdrop_filter_proc_ = nullptr;
312
313 std::shared_ptr<EntityPassDelegate> delegate_ =
314 EntityPassDelegate::MakeDefault();
315
316 EntityPass(const EntityPass&) = delete;
317
318 EntityPass& operator=(const EntityPass&) = delete;
319 };
320
321 } // namespace impeller
322
323 #endif // FLUTTER_IMPELLER_ENTITY_ENTITY_PASS_H_
impeller::EntityPass::AddSubpassInline
void AddSubpassInline(std::unique_ptr< EntityPass > pass)
Merges a given pass into this pass. Useful for drawing pre-recorded pictures that don't require rende...
Definition: entity_pass.cc:224
impeller::EntityPass::IterateAllEntities
void IterateAllEntities(const std::function< bool(Entity &)> &iterator)
Iterate all entities in this pass, recursively including entities of child passes....
Definition: entity_pass.cc:1015
impeller::EntityPass::GetClipDepth
size_t GetClipDepth()
Definition: entity_pass.cc:1119
impeller::EntityPass::SetBackdropFilter
void SetBackdropFilter(BackdropFilterProc proc)
Definition: entity_pass.cc:1153
contents.h
entity_pass_delegate.h
impeller::EntityPass::BackdropFilterProc
std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)> BackdropFilterProc
Definition: entity_pass.h:43
impeller::EntityPass::GetSubpassCoverage
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:173
entity.h
impeller::EntityPass::GetSubpassesDepth
size_t GetSubpassesDepth() const
Definition: entity_pass.cc:86
impeller::EntityPass::SetBoundsLimit
void SetBoundsLimit(std::optional< Rect > bounds_limit)
Set the bounds limit, which is provided by the user when creating a SaveLayer. This is a hint that al...
Definition: entity_pass.cc:62
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::Color
Definition: color.h:124
impeller::EntityPass::EntityPass
EntityPass()
impeller::EntityPass::ClipCoverageLayer::clip_depth
size_t clip_depth
Definition: entity_pass.h:47
impeller::EntityPassDelegate::MakeDefault
static std::unique_ptr< EntityPassDelegate > MakeDefault()
Definition: entity_pass_delegate.cc:51
impeller::EntityPass::AddSubpass
EntityPass * AddSubpass(std::unique_ptr< EntityPass > pass)
Appends a given pass as a subpass.
Definition: entity_pass.cc:205
impeller::EntityPass::IterateUntilSubpass
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...
Definition: entity_pass.cc:1058
impeller::FilterInput::Ref
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:32
impeller::EntityPass::IterateAllElements
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:999
impeller::EntityPass::ClipCoverageStack
std::vector< ClipCoverageLayer > ClipCoverageStack
Definition: entity_pass.h:50
impeller::EntityPass::GetElementsCoverage
std::optional< Rect > GetElementsCoverage(std::optional< Rect > coverage_limit) const
Definition: entity_pass.cc:97
impeller::EntityPass::~EntityPass
~EntityPass()
impeller::EntityPass::SetClipDepth
void SetClipDepth(size_t clip_depth)
Definition: entity_pass.cc:1115
impeller::EntityPass::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: entity_pass.cc:1123
impeller::Entity
Definition: entity.h:21
impeller::TSize< int64_t >
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::EntityPass::SetElements
void SetElements(std::vector< Element > elements)
Definition: entity_pass.cc:82
filter_contents.h
impeller::EntityPass::GetBoundsLimit
std::optional< Rect > GetBoundsLimit() const
Get the bounds limit, which is provided by the user when creating a SaveLayer.
Definition: entity_pass.cc:66
impeller::EntityPass::GetSuperpass
EntityPass * GetSuperpass() const
Definition: entity_pass.cc:201
impeller::EntityPass
Definition: entity_pass.h:25
impeller::EntityPass::ClipCoverageLayer::coverage
std::optional< Rect > coverage
Definition: entity_pass.h:46
impeller::EntityPass::Element
std::variant< Entity, std::unique_ptr< EntityPass > > Element
Definition: entity_pass.h:36
impeller::EntityPass::GetElementCount
size_t GetElementCount() const
Return the number of elements on this pass.
Definition: entity_pass.cc:1076
impeller::RenderTarget
Definition: render_target.h:49
impeller::EntityPass::ClipCoverageLayer
Definition: entity_pass.h:45
impeller::EntityPass::SetTransform
void SetTransform(Matrix transform)
Definition: entity_pass.cc:1111
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::EntityPass::Render
bool Render(ContentContext &renderer, const RenderTarget &render_target) const
Definition: entity_pass.cc:304
impeller::TSize< int64_t >::Infinite
static constexpr TSize Infinite()
Definition: size.h:38
impeller::EntityPass::kCaptureDocumentName
static const std::string kCaptureDocumentName
Definition: entity_pass.h:38
impeller::EntityPass::SetDelegate
void SetDelegate(std::shared_ptr< EntityPassDelegate > delgate)
Definition: entity_pass.cc:55
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:26
impeller::EntityPass::SetEnableOffscreenCheckerboard
void SetEnableOffscreenCheckerboard(bool enabled)
Definition: entity_pass.cc:1162
render_target.h
impeller
Definition: aiks_context.cc:10
impeller::ContentContext
Definition: content_context.h:332
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::EntityPass::GetClearColor
std::optional< Color > GetClearColor(ISize size=ISize::Infinite()) const
Return the premultiplied clear color of the pass entities, if any.
Definition: entity_pass.cc:1132
impeller::EntityPass::GetClearColorOrDefault
Color GetClearColorOrDefault(ISize size=ISize::Infinite()) const
Return the premultiplied clear color of the pass entities.
Definition: entity_pass.cc:1128
impeller::EntityPass::AddEntity
void AddEntity(Entity entity)
Add an entity to the current entity pass.
Definition: entity_pass.cc:70
inline_pass_context.h
impeller::EntityPass::Clone
std::unique_ptr< EntityPass > Clone() const
Definition: entity_pass.cc:1080