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 #pragma once
6 
7 #include <functional>
8 #include <memory>
9 #include <optional>
10 #include <vector>
11 
12 #include "flutter/fml/macros.h"
13 #include "impeller/core/texture.h"
16 #include "impeller/entity/entity.h"
21 
22 namespace impeller {
23 
24 class ContentContext;
25 
26 class EntityPass {
27  public:
28  /// Elements are renderable items in the `EntityPass`. Each can either be an
29  /// `Entity` or a child `EntityPass`.
30  ///
31  /// When the element is a child `EntityPass`, it may be rendered to an
32  /// offscreen texture and converted into an `Entity` that draws the texture
33  /// into the current pass, or its children may be collapsed into the current
34  ///
35  /// `EntityPass`. Elements are converted to Entities in
36  /// `GetEntityForElement()`.
37  using Element = std::variant<Entity, std::unique_ptr<EntityPass>>;
38 
39  static const std::string kCaptureDocumentName;
40 
41  using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
43  const Matrix& effect_transform,
44  Entity::RenderingMode rendering_mode)>;
45 
47  std::optional<Rect> coverage;
48  size_t stencil_depth;
49  };
50 
51  using StencilCoverageStack = std::vector<StencilCoverageLayer>;
52 
53  EntityPass();
54 
55  ~EntityPass();
56 
57  void SetDelegate(std::shared_ptr<EntityPassDelegate> delgate);
58 
59  /// @brief Set the bounds limit, which is provided by the user when creating
60  /// a SaveLayer. This is a hint that allows the user to communicate
61  /// that it's OK to not render content outside of the bounds.
62  ///
63  /// For consistency with Skia, we effectively treat this like a
64  /// rectangle clip by forcing the subpass texture size to never exceed
65  /// it.
66  void SetBoundsLimit(std::optional<Rect> bounds_limit);
67 
68  /// @brief Get the bounds limit, which is provided by the user when creating
69  /// a SaveLayer.
70  std::optional<Rect> GetBoundsLimit() const;
71 
72  size_t GetSubpassesDepth() const;
73 
74  std::unique_ptr<EntityPass> Clone() const;
75 
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 SetTransformation(Matrix xformation);
131 
132  void SetStencilDepth(size_t stencil_depth);
133 
134  size_t GetStencilDepth();
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.
145 
147 
148  void SetEnableOffscreenCheckerboard(bool enabled);
149 
150  //----------------------------------------------------------------------------
151  /// @brief Get the coverage of an unfiltered subpass.
152  ///
153  std::optional<Rect> GetSubpassCoverage(
154  const EntityPass& subpass,
155  std::optional<Rect> coverage_limit) const;
156 
157  std::optional<Rect> GetElementsCoverage(
158  std::optional<Rect> coverage_limit) const;
159 
160  private:
161  struct EntityResult {
162  enum Status {
163  /// The entity was successfully resolved and can be rendered.
164  kSuccess,
165  /// An unexpected rendering error occurred while resolving the Entity.
166  kFailure,
167  /// The entity should be skipped because rendering it will contribute
168  /// nothing to the frame.
169  kSkip,
170  };
171 
172  /// @brief The resulting entity that should be rendered. If `std::nullopt`,
173  /// there is nothing to render.
174  Entity entity;
175  /// @brief This is set to `false` if there was an unexpected rendering
176  /// error while resolving the Entity.
177  Status status = kFailure;
178 
179  static EntityResult Success(const Entity& e) { return {e, kSuccess}; }
180  static EntityResult Failure() { return {{}, kFailure}; }
181  static EntityResult Skip() { return {{}, kSkip}; }
182  };
183 
184  EntityResult GetEntityForElement(const EntityPass::Element& element,
185  ContentContext& renderer,
186  Capture& capture,
187  InlinePassContext& pass_context,
188  ISize root_pass_size,
189  Point global_pass_position,
190  uint32_t pass_depth,
191  StencilCoverageStack& stencil_coverage_stack,
192  size_t stencil_depth_floor) const;
193 
194  //----------------------------------------------------------------------------
195  /// @brief OnRender is the internal command recording routine for
196  /// `EntityPass`. Its job is to walk through each `Element` which
197  /// was appended to the scene (either an `Entity` via `AddEntity()`
198  /// or a child `EntityPass` via `AddSubpass()`) and render them to
199  /// the given `pass_target`.
200  /// @param[in] renderer The Contents context, which manages
201  /// pipeline state.
202  /// @param[in] root_pass_size The size of the texture being
203  /// rendered into at the root of the
204  /// `EntityPass` tree. This is the size
205  /// of the `RenderTarget` color
206  /// attachment passed to the public
207  /// `EntityPass::Render` method.
208  /// @param[out] pass_target Stores the render target that should
209  /// be used for rendering.
210  /// @param[in] global_pass_position The position that this `EntityPass`
211  /// will be drawn to the parent pass
212  /// relative to the root pass origin.
213  /// Used for offsetting drawn `Element`s,
214  /// whose origins are all in root
215  /// pass/screen space,
216  /// @param[in] local_pass_position The position that this `EntityPass`
217  /// will be drawn to the parent pass
218  /// relative to the parent pass origin.
219  /// Used for positioning backdrop
220  /// filters.
221  /// @param[in] pass_depth The tree depth of the `EntityPass` at
222  /// render time. Only used for labeling
223  /// and debugging purposes. This can vary
224  /// depending on whether passes are
225  /// collapsed or not.
226  /// @param[in] stencil_coverage_stack A global stack of coverage rectangles
227  /// for the stencil buffer at each depth.
228  /// Higher depths are more restrictive.
229  /// Used to cull Elements that we
230  /// know won't result in a visible
231  /// change.
232  /// @param[in] stencil_depth_floor The stencil depth that a value of
233  /// zero corresponds to in the given
234  /// `pass_target` stencil buffer.
235  /// When new `pass_target`s are created
236  /// for subpasses, their stencils are
237  /// initialized at zero, and so this
238  /// value is used to offset Entity clip
239  /// depths to match the stencil.
240  /// @param[in] backdrop_filter_contents Optional. Is supplied, this contents
241  /// is rendered prior to anything else in
242  /// the `EntityPass`, offset by the
243  /// `local_pass_position`.
244  /// @param[in] collapsed_parent_pass Optional. If supplied, this
245  /// `InlinePassContext` state is used to
246  /// begin rendering elements instead of
247  /// creating a new `RenderPass`. This
248  /// "collapses" the Elements into the
249  /// parent pass.
250  ///
251  bool OnRender(ContentContext& renderer,
252  Capture& capture,
253  ISize root_pass_size,
254  EntityPassTarget& pass_target,
255  Point global_pass_position,
256  Point local_pass_position,
257  uint32_t pass_depth,
258  StencilCoverageStack& stencil_coverage_stack,
259  size_t stencil_depth_floor = 0,
260  std::shared_ptr<Contents> backdrop_filter_contents = nullptr,
261  const std::optional<InlinePassContext::RenderPassResult>&
262  collapsed_parent_pass = std::nullopt) const;
263 
264  /// The list of renderable items in the scene. Each of these items is
265  /// evaluated and recorded to an `EntityPassTarget` by the `OnRender` method.
266  std::vector<Element> elements_;
267 
268  EntityPass* superpass_ = nullptr;
269  Matrix xformation_;
270  size_t stencil_depth_ = 0u;
271  BlendMode blend_mode_ = BlendMode::kSourceOver;
272  bool flood_clip_ = false;
273  bool enable_offscreen_debug_checkerboard_ = false;
274  std::optional<Rect> bounds_limit_;
275 
276  /// These values are incremented whenever something is added to the pass that
277  /// requires reading from the backdrop texture. Currently, this can happen in
278  /// the following scenarios:
279  /// 1. An entity with an "advanced blend" is added to the pass.
280  /// 2. A subpass with a backdrop filter is added to the pass.
281  /// These are tracked as separate values because we may ignore
282  /// blend_reads_from_pass_texture_ if the device supports framebuffer based
283  /// advanced blends.
284  uint32_t advanced_blend_reads_from_pass_texture_ = 0;
285  uint32_t backdrop_filter_reads_from_pass_texture_ = 0;
286 
287  uint32_t GetTotalPassReads(ContentContext& renderer) const;
288 
289  BackdropFilterProc backdrop_filter_proc_ = nullptr;
290 
291  std::shared_ptr<EntityPassDelegate> delegate_ =
293 
294  FML_DISALLOW_COPY_AND_ASSIGN(EntityPass);
295 };
296 
297 } // namespace impeller
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:245
impeller::BlendMode
BlendMode
Definition: color.h:57
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:1030
impeller::EntityPass::SetTransformation
void SetTransformation(Matrix xformation)
Definition: entity_pass.cc:1126
impeller::EntityPass::SetBackdropFilter
void SetBackdropFilter(BackdropFilterProc proc)
Definition: entity_pass.cc:1168
lazy_glyph_atlas.h
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:44
impeller::EntityPass::GetSubpassCoverage
std::optional< Rect > GetSubpassCoverage(const EntityPass &subpass, std::optional< Rect > coverage_limit) const
Get the coverage of an unfiltered subpass.
Definition: entity_pass.cc:195
entity.h
impeller::EntityPass::GetSubpassesDepth
size_t GetSubpassesDepth() const
Definition: entity_pass.cc:93
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:69
impeller::EntityPass::StencilCoverageLayer::stencil_depth
size_t stencil_depth
Definition: entity_pass.h:48
impeller::Color
Definition: color.h:122
impeller::EntityPass::EntityPass
EntityPass()
impeller::EntityPassDelegate::MakeDefault
static std::unique_ptr< EntityPassDelegate > MakeDefault()
Definition: entity_pass_delegate.cc:48
impeller::EntityPass::AddSubpass
EntityPass * AddSubpass(std::unique_ptr< EntityPass > pass)
Appends a given pass as a subpass.
Definition: entity_pass.cc:226
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:1073
impeller::FilterInput::Ref
std::shared_ptr< FilterInput > Ref
Definition: filter_input.h:31
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:1014
impeller::EntityPass::GetElementsCoverage
std::optional< Rect > GetElementsCoverage(std::optional< Rect > coverage_limit) const
Definition: entity_pass.cc:104
impeller::EntityPass::~EntityPass
~EntityPass()
impeller::EntityPass::SetStencilDepth
void SetStencilDepth(size_t stencil_depth)
Definition: entity_pass.cc:1130
impeller::EntityPass::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: entity_pass.cc:1138
impeller::Entity
Definition: entity.h:21
impeller::TSize< int64_t >
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::EntityPass::StencilCoverageStack
std::vector< StencilCoverageLayer > StencilCoverageStack
Definition: entity_pass.h:51
impeller::EntityPass::SetElements
void SetElements(std::vector< Element > elements)
Definition: entity_pass.cc:89
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:73
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::EntityPass::GetSuperpass
EntityPass * GetSuperpass() const
Definition: entity_pass.cc:222
impeller::EntityPass
Definition: entity_pass.h:26
impeller::EntityPass::GetStencilDepth
size_t GetStencilDepth()
Definition: entity_pass.cc:1134
impeller::EntityPass::Element
std::variant< Entity, std::unique_ptr< EntityPass > > Element
Definition: entity_pass.h:37
impeller::EntityPass::GetElementCount
size_t GetElementCount() const
Return the number of elements on this pass.
Definition: entity_pass.cc:1091
impeller::RenderTarget
Definition: render_target.h:48
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:136
impeller::EntityPass::StencilCoverageLayer
Definition: entity_pass.h:46
impeller::EntityPass::Render
bool Render(ContentContext &renderer, const RenderTarget &render_target) const
Definition: entity_pass.cc:323
texture.h
impeller::TSize< int64_t >::Infinite
static constexpr TSize Infinite()
Definition: size.h:37
impeller::EntityPass::kCaptureDocumentName
static const std::string kCaptureDocumentName
Definition: entity_pass.h:39
impeller::EntityPass::SetDelegate
void SetDelegate(std::shared_ptr< EntityPassDelegate > delgate)
Definition: entity_pass.cc:62
impeller::Entity::RenderingMode
RenderingMode
Definition: entity.h:26
impeller::EntityPass::SetEnableOffscreenCheckerboard
void SetEnableOffscreenCheckerboard(bool enabled)
Definition: entity_pass.cc:1177
render_target.h
impeller::EntityPass::StencilCoverageLayer::coverage
std::optional< Rect > coverage
Definition: entity_pass.h:47
impeller
Definition: aiks_context.cc:10
impeller::ContentContext
Definition: content_context.h:344
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:36
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:1147
impeller::EntityPass::GetClearColorOrDefault
Color GetClearColorOrDefault(ISize size=ISize::Infinite()) const
Return the premultiplied clear color of the pass entities.
Definition: entity_pass.cc:1143
impeller::EntityPass::AddEntity
void AddEntity(Entity entity)
Definition: entity_pass.cc:77
inline_pass_context.h
impeller::EntityPass::Clone
std::unique_ptr< EntityPass > Clone() const
Definition: entity_pass.cc:1095