Flutter Impeller
impeller::EntityPass Class Reference

#include <entity_pass.h>

Classes

struct  StencilCoverageLayer
 

Public Types

using Element = std::variant< Entity, std::unique_ptr< EntityPass > >
 
using BackdropFilterProc = std::function< std::shared_ptr< FilterContents >(FilterInput::Ref, const Matrix &effect_transform, Entity::RenderingMode rendering_mode)>
 
using StencilCoverageStack = std::vector< StencilCoverageLayer >
 

Public Member Functions

 EntityPass ()
 
 ~EntityPass ()
 
void SetDelegate (std::shared_ptr< EntityPassDelegate > delgate)
 
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 allows the user to communicate that it's OK to not render content outside of the bounds. More...
 
std::optional< RectGetBoundsLimit () const
 Get the bounds limit, which is provided by the user when creating a SaveLayer. More...
 
size_t GetSubpassesDepth () const
 
std::unique_ptr< EntityPassClone () const
 
void AddEntity (Entity entity)
 
void SetElements (std::vector< Element > elements)
 
EntityPassAddSubpass (std::unique_ptr< EntityPass > pass)
 Appends a given pass as a subpass. More...
 
void AddSubpassInline (std::unique_ptr< EntityPass > pass)
 Merges a given pass into this pass. Useful for drawing pre-recorded pictures that don't require rendering into a separate subpass. More...
 
EntityPassGetSuperpass () const
 
bool Render (ContentContext &renderer, const RenderTarget &render_target) const
 
void IterateAllElements (const std::function< bool(Element &)> &iterator)
 Iterate all elements (entities and subpasses) in this pass, recursively including elements of child passes. The iteration order is depth-first. Whenever a subpass elements is encountered, it's included in the stream before its children. More...
 
void IterateAllEntities (const std::function< bool(Entity &)> &iterator)
 Iterate all entities in this pass, recursively including entities of child passes. The iteration order is depth-first. More...
 
void IterateAllEntities (const std::function< bool(const Entity &)> &iterator) const
 Iterate all entities in this pass, recursively including entities of child passes. The iteration order is depth-first and does not allow modification of the entities. More...
 
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-ahead optimizations. More...
 
size_t GetElementCount () const
 Return the number of elements on this pass. More...
 
void SetTransformation (Matrix xformation)
 
void SetStencilDepth (size_t stencil_depth)
 
size_t GetStencilDepth ()
 
void SetBlendMode (BlendMode blend_mode)
 
Color GetClearColor (ISize size=ISize::Infinite()) const
 
void SetBackdropFilter (BackdropFilterProc proc)
 
void SetEnableOffscreenCheckerboard (bool enabled)
 
std::optional< RectGetSubpassCoverage (const EntityPass &subpass, std::optional< Rect > coverage_limit) const
 Get the coverage of an unfiltered subpass. More...
 
std::optional< RectGetElementsCoverage (std::optional< Rect > coverage_limit) const
 

Static Public Attributes

static const std::string kCaptureDocumentName = "EntityPass"
 

Detailed Description

Definition at line 26 of file entity_pass.h.

Member Typedef Documentation

◆ BackdropFilterProc

using impeller::EntityPass::BackdropFilterProc = std::function<std::shared_ptr<FilterContents>( FilterInput::Ref, const Matrix& effect_transform, Entity::RenderingMode rendering_mode)>

Definition at line 44 of file entity_pass.h.

◆ Element

using impeller::EntityPass::Element = std::variant<Entity, std::unique_ptr<EntityPass> >

Elements are renderable items in the EntityPass. Each can either be an Entity or a child EntityPass.

When the element is a child EntityPass, it may be rendered to an offscreen texture and converted into an Entity that draws the texture into the current pass, or its children may be collapsed into the current

EntityPass. Elements are converted to Entities in GetEntityForElement().

Definition at line 37 of file entity_pass.h.

◆ StencilCoverageStack

Definition at line 51 of file entity_pass.h.

Constructor & Destructor Documentation

◆ EntityPass()

impeller::EntityPass::EntityPass ( )
default

◆ ~EntityPass()

impeller::EntityPass::~EntityPass ( )
default

Member Function Documentation

◆ AddEntity()

void impeller::EntityPass::AddEntity ( Entity  entity)

◆ AddSubpass()

EntityPass * impeller::EntityPass::AddSubpass ( std::unique_ptr< EntityPass pass)

Appends a given pass as a subpass.

Definition at line 226 of file entity_pass.cc.

226  {
227  if (!pass) {
228  return nullptr;
229  }
230  FML_DCHECK(pass->superpass_ == nullptr);
231  pass->superpass_ = this;
232 
233  if (pass->backdrop_filter_proc_) {
234  backdrop_filter_reads_from_pass_texture_ += 1;
235  }
236  if (pass->blend_mode_ > Entity::kLastPipelineBlendMode) {
237  advanced_blend_reads_from_pass_texture_ += 1;
238  }
239 
240  auto subpass_pointer = pass.get();
241  elements_.emplace_back(std::move(pass));
242  return subpass_pointer;
243 }

References impeller::Entity::kLastPipelineBlendMode.

Referenced by impeller::testing::TEST_P().

◆ AddSubpassInline()

void impeller::EntityPass::AddSubpassInline ( std::unique_ptr< EntityPass pass)

Merges a given pass into this pass. Useful for drawing pre-recorded pictures that don't require rendering into a separate subpass.

Definition at line 245 of file entity_pass.cc.

245  {
246  if (!pass) {
247  return;
248  }
249  FML_DCHECK(pass->superpass_ == nullptr);
250 
251  elements_.insert(elements_.end(),
252  std::make_move_iterator(pass->elements_.begin()),
253  std::make_move_iterator(pass->elements_.end()));
254 
255  backdrop_filter_reads_from_pass_texture_ +=
256  pass->backdrop_filter_reads_from_pass_texture_;
257  advanced_blend_reads_from_pass_texture_ +=
258  pass->advanced_blend_reads_from_pass_texture_;
259 }

Referenced by impeller::Canvas::DrawPicture().

◆ Clone()

std::unique_ptr< EntityPass > impeller::EntityPass::Clone ( ) const

Definition at line 1095 of file entity_pass.cc.

1095  {
1096  std::vector<Element> new_elements;
1097  new_elements.reserve(elements_.size());
1098 
1099  for (const auto& element : elements_) {
1100  if (auto entity = std::get_if<Entity>(&element)) {
1101  new_elements.push_back(*entity);
1102  continue;
1103  }
1104  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1105  new_elements.push_back(subpass->get()->Clone());
1106  continue;
1107  }
1108  FML_UNREACHABLE();
1109  }
1110 
1111  auto pass = std::make_unique<EntityPass>();
1112  pass->SetElements(std::move(new_elements));
1113  pass->backdrop_filter_reads_from_pass_texture_ =
1114  backdrop_filter_reads_from_pass_texture_;
1115  pass->advanced_blend_reads_from_pass_texture_ =
1116  advanced_blend_reads_from_pass_texture_;
1117  pass->backdrop_filter_proc_ = backdrop_filter_proc_;
1118  pass->blend_mode_ = blend_mode_;
1119  pass->delegate_ = delegate_;
1120  // Note: I tried also adding flood clip and bounds limit but one of the
1121  // two caused rendering in wonderous to break. It's 10:51 PM, and I'm
1122  // ready to move on.
1123  return pass;
1124 }

◆ GetBoundsLimit()

std::optional< Rect > impeller::EntityPass::GetBoundsLimit ( ) const

Get the bounds limit, which is provided by the user when creating a SaveLayer.

Definition at line 73 of file entity_pass.cc.

73  {
74  return bounds_limit_;
75 }

Referenced by impeller::OpacityPeepholePassDelegate::CanCollapseIntoParentPass().

◆ GetClearColor()

Color impeller::EntityPass::GetClearColor ( ISize  size = ISize::Infinite()) const

Definition at line 1143 of file entity_pass.cc.

1143  {
1144  Color result = Color::BlackTransparent();
1145  if (backdrop_filter_proc_) {
1146  return result;
1147  }
1148 
1149  for (const Element& element : elements_) {
1150  auto [entity_color, blend_mode] =
1151  ElementAsBackgroundColor(element, target_size);
1152  if (!entity_color.has_value()) {
1153  break;
1154  }
1155  result = result.Blend(entity_color.value(), blend_mode);
1156  }
1157  return result.Premultiply();
1158 }

References impeller::Color::Blend(), and impeller::Color::Premultiply().

◆ GetElementCount()

size_t impeller::EntityPass::GetElementCount ( ) const

Return the number of elements on this pass.

Definition at line 1091 of file entity_pass.cc.

1091  {
1092  return elements_.size();
1093 }

Referenced by impeller::OpacityPeepholePassDelegate::CanCollapseIntoParentPass().

◆ GetElementsCoverage()

std::optional< Rect > impeller::EntityPass::GetElementsCoverage ( std::optional< Rect coverage_limit) const

Definition at line 104 of file entity_pass.cc.

105  {
106  std::optional<Rect> result;
107  for (const auto& element : elements_) {
108  std::optional<Rect> coverage;
109 
110  if (auto entity = std::get_if<Entity>(&element)) {
111  coverage = entity->GetCoverage();
112 
113  // When the coverage limit is std::nullopt, that means there is no limit,
114  // as opposed to empty coverage.
115  if (coverage.has_value() && coverage_limit.has_value()) {
116  const auto* filter = entity->GetContents()->AsFilter();
117  if (!filter || filter->IsTranslationOnly()) {
118  coverage = coverage->Intersection(coverage_limit.value());
119  }
120  }
121  } else if (auto subpass_ptr =
122  std::get_if<std::unique_ptr<EntityPass>>(&element)) {
123  auto& subpass = *subpass_ptr->get();
124 
125  std::optional<Rect> unfiltered_coverage =
126  GetSubpassCoverage(subpass, std::nullopt);
127 
128  // If the current pass elements have any coverage so far and there's a
129  // backdrop filter, then incorporate the backdrop filter in the
130  // pre-filtered coverage of the subpass.
131  if (result.has_value() && subpass.backdrop_filter_proc_) {
132  std::shared_ptr<FilterContents> backdrop_filter =
133  subpass.backdrop_filter_proc_(FilterInput::Make(result.value()),
134  subpass.xformation_,
136  if (backdrop_filter) {
137  auto backdrop_coverage = backdrop_filter->GetCoverage({});
138  backdrop_coverage->origin += result->origin;
139  if (backdrop_coverage.has_value()) {
140  if (unfiltered_coverage.has_value()) {
141  unfiltered_coverage = coverage->Union(*backdrop_coverage);
142  } else {
143  unfiltered_coverage = backdrop_coverage;
144  }
145  }
146  } else {
147  VALIDATION_LOG << "The EntityPass backdrop filter proc didn't return "
148  "a valid filter.";
149  }
150  }
151 
152  if (!unfiltered_coverage.has_value()) {
153  continue;
154  }
155 
156  // Additionally, subpass textures may be passed through filters, which may
157  // modify the coverage.
158  //
159  // Note that we currently only assume that ImageFilters (such as blurs and
160  // matrix transforms) may modify coverage, although it's technically
161  // possible ColorFilters to affect coverage as well. For example: A
162  // ColorMatrixFilter could output a completely transparent result, and
163  // we could potentially detect this case as zero coverage in the future.
164  std::shared_ptr<FilterContents> image_filter =
165  subpass.delegate_->WithImageFilter(*unfiltered_coverage,
166  subpass.xformation_);
167  if (image_filter) {
168  Entity subpass_entity;
169  subpass_entity.SetTransformation(subpass.xformation_);
170  coverage = image_filter->GetCoverage(subpass_entity);
171  } else {
172  coverage = unfiltered_coverage;
173  }
174 
175  if (coverage.has_value() && coverage_limit.has_value() &&
176  (!image_filter || image_filter->IsTranslationOnly())) {
177  coverage = coverage->Intersection(coverage_limit.value());
178  }
179  } else {
180  FML_UNREACHABLE();
181  }
182 
183  if (!result.has_value() && coverage.has_value()) {
184  result = coverage;
185  continue;
186  }
187  if (!coverage.has_value()) {
188  continue;
189  }
190  result = result->Union(coverage.value());
191  }
192  return result;
193 }

References GetSubpassCoverage(), impeller::Entity::kSubpass, impeller::FilterInput::Make(), impeller::Entity::SetTransformation(), and VALIDATION_LOG.

Referenced by GetSubpassCoverage(), and impeller::testing::TEST_P().

◆ GetStencilDepth()

size_t impeller::EntityPass::GetStencilDepth ( )

Definition at line 1134 of file entity_pass.cc.

1134  {
1135  return stencil_depth_;
1136 }

◆ GetSubpassCoverage()

std::optional< Rect > impeller::EntityPass::GetSubpassCoverage ( const EntityPass subpass,
std::optional< Rect coverage_limit 
) const

Get the coverage of an unfiltered subpass.

Definition at line 195 of file entity_pass.cc.

197  {
198  std::shared_ptr<FilterContents> image_filter =
199  subpass.delegate_->WithImageFilter(Rect(), subpass.xformation_);
200 
201  // If the filter graph transforms the basis of the subpass, then its space
202  // has deviated too much from the parent pass to safely intersect with the
203  // pass coverage limit.
204  coverage_limit =
205  (image_filter && !image_filter->IsTranslationOnly() ? std::nullopt
206  : coverage_limit);
207 
208  auto entities_coverage = subpass.GetElementsCoverage(coverage_limit);
209  // The entities don't cover anything. There is nothing to do.
210  if (!entities_coverage.has_value()) {
211  return std::nullopt;
212  }
213 
214  if (!subpass.bounds_limit_.has_value()) {
215  return entities_coverage;
216  }
217  auto user_bounds_coverage =
218  subpass.bounds_limit_->TransformBounds(subpass.xformation_);
219  return entities_coverage->Intersection(user_bounds_coverage);
220 }

References GetElementsCoverage().

Referenced by GetElementsCoverage(), and impeller::testing::TEST_P().

◆ GetSubpassesDepth()

size_t impeller::EntityPass::GetSubpassesDepth ( ) const

Definition at line 93 of file entity_pass.cc.

93  {
94  size_t max_subpass_depth = 0u;
95  for (const auto& element : elements_) {
96  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
97  max_subpass_depth =
98  std::max(max_subpass_depth, subpass->get()->GetSubpassesDepth());
99  }
100  }
101  return max_subpass_depth + 1u;
102 }

◆ GetSuperpass()

EntityPass * impeller::EntityPass::GetSuperpass ( ) const

Definition at line 222 of file entity_pass.cc.

222  {
223  return superpass_;
224 }

Referenced by impeller::Canvas::Restore().

◆ IterateAllElements()

void impeller::EntityPass::IterateAllElements ( const std::function< bool(Element &)> &  iterator)

Iterate all elements (entities and subpasses) in this pass, recursively including elements of child passes. The iteration order is depth-first. Whenever a subpass elements is encountered, it's included in the stream before its children.

Definition at line 1014 of file entity_pass.cc.

1015  {
1016  if (!iterator) {
1017  return;
1018  }
1019 
1020  for (auto& element : elements_) {
1021  if (!iterator(element)) {
1022  return;
1023  }
1024  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1025  subpass->get()->IterateAllElements(iterator);
1026  }
1027  }
1028 }

◆ IterateAllEntities() [1/2]

void impeller::EntityPass::IterateAllEntities ( const std::function< bool(const Entity &)> &  iterator) const

Iterate all entities in this pass, recursively including entities of child passes. The iteration order is depth-first and does not allow modification of the entities.

Definition at line 1051 of file entity_pass.cc.

1052  {
1053  if (!iterator) {
1054  return;
1055  }
1056 
1057  for (const auto& element : elements_) {
1058  if (auto entity = std::get_if<Entity>(&element)) {
1059  if (!iterator(*entity)) {
1060  return;
1061  }
1062  continue;
1063  }
1064  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1065  const EntityPass* entity_pass = subpass->get();
1066  entity_pass->IterateAllEntities(iterator);
1067  continue;
1068  }
1069  FML_UNREACHABLE();
1070  }
1071 }

References IterateAllEntities().

◆ IterateAllEntities() [2/2]

void impeller::EntityPass::IterateAllEntities ( const std::function< bool(Entity &)> &  iterator)

Iterate all entities in this pass, recursively including entities of child passes. The iteration order is depth-first.

Definition at line 1030 of file entity_pass.cc.

1031  {
1032  if (!iterator) {
1033  return;
1034  }
1035 
1036  for (auto& element : elements_) {
1037  if (auto entity = std::get_if<Entity>(&element)) {
1038  if (!iterator(*entity)) {
1039  return;
1040  }
1041  continue;
1042  }
1043  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1044  subpass->get()->IterateAllEntities(iterator);
1045  continue;
1046  }
1047  FML_UNREACHABLE();
1048  }
1049 }

Referenced by IterateAllEntities(), and Render().

◆ IterateUntilSubpass()

bool impeller::EntityPass::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-ahead optimizations.

Returns
Returns whether a subpass was encountered.

Definition at line 1073 of file entity_pass.cc.

1074  {
1075  if (!iterator) {
1076  return true;
1077  }
1078 
1079  for (auto& element : elements_) {
1080  if (auto entity = std::get_if<Entity>(&element)) {
1081  if (!iterator(*entity)) {
1082  return false;
1083  }
1084  continue;
1085  }
1086  return true;
1087  }
1088  return false;
1089 }

Referenced by impeller::OpacityPeepholePassDelegate::CanCollapseIntoParentPass().

◆ Render()

bool impeller::EntityPass::Render ( ContentContext renderer,
const RenderTarget render_target 
) const

Definition at line 323 of file entity_pass.cc.

324  {
325  auto capture =
326  renderer.GetContext()->capture.GetDocument(kCaptureDocumentName);
327 
328  renderer.GetRenderTargetCache()->Start();
329 
330  auto root_render_target = render_target;
331 
332  if (root_render_target.GetColorAttachments().find(0u) ==
333  root_render_target.GetColorAttachments().end()) {
334  VALIDATION_LOG << "The root RenderTarget must have a color attachment.";
335  return false;
336  }
337 
338  capture.AddRect("Coverage",
339  Rect::MakeSize(root_render_target.GetRenderTargetSize()),
340  {.readonly = true});
341 
342  fml::ScopedCleanupClosure reset_state([&renderer]() {
343  renderer.GetLazyGlyphAtlas()->ResetTextFrames();
344  renderer.GetRenderTargetCache()->End();
345  });
346 
347  IterateAllEntities([lazy_glyph_atlas =
348  renderer.GetLazyGlyphAtlas()](const Entity& entity) {
349  if (auto contents = entity.GetContents()) {
350  contents->PopulateGlyphAtlas(lazy_glyph_atlas, entity.DeriveTextScale());
351  }
352  return true;
353  });
354 
355  StencilCoverageStack stencil_coverage_stack = {StencilCoverageLayer{
356  .coverage = Rect::MakeSize(root_render_target.GetRenderTargetSize()),
357  .stencil_depth = 0}};
358 
359  bool supports_onscreen_backdrop_reads =
360  renderer.GetDeviceCapabilities().SupportsReadFromOnscreenTexture() &&
361  // If the backend doesn't have `SupportsReadFromResolve`, we need to flip
362  // between two textures when restoring a previous MSAA pass.
363  renderer.GetDeviceCapabilities().SupportsReadFromResolve();
364  bool reads_from_onscreen_backdrop = GetTotalPassReads(renderer) > 0;
365  // In this branch path, we need to render everything to an offscreen texture
366  // and then blit the results onto the onscreen texture. If using this branch,
367  // there's no need to set up a stencil attachment on the root render target.
368  if (!supports_onscreen_backdrop_reads && reads_from_onscreen_backdrop) {
369  auto offscreen_target = CreateRenderTarget(
370  renderer, root_render_target.GetRenderTargetSize(), true,
371  GetClearColor(render_target.GetRenderTargetSize()));
372 
373  if (!OnRender(renderer, // renderer
374  capture, // capture
375  offscreen_target.GetRenderTarget()
376  .GetRenderTargetSize(), // root_pass_size
377  offscreen_target, // pass_target
378  Point(), // global_pass_position
379  Point(), // local_pass_position
380  0, // pass_depth
381  stencil_coverage_stack // stencil_coverage_stack
382  )) {
383  // Validation error messages are triggered for all `OnRender()` failure
384  // cases.
385  return false;
386  }
387 
388  auto command_buffer = renderer.GetContext()->CreateCommandBuffer();
389  command_buffer->SetLabel("EntityPass Root Command Buffer");
390 
391  // If the context supports blitting, blit the offscreen texture to the
392  // onscreen texture. Otherwise, draw it to the parent texture using a
393  // pipeline (slower).
394  if (renderer.GetContext()
395  ->GetCapabilities()
396  ->SupportsTextureToTextureBlits()) {
397  auto blit_pass = command_buffer->CreateBlitPass();
398  blit_pass->AddCopy(
399  offscreen_target.GetRenderTarget().GetRenderTargetTexture(),
400  root_render_target.GetRenderTargetTexture());
401 
402  if (!blit_pass->EncodeCommands(
403  renderer.GetContext()->GetResourceAllocator())) {
404  VALIDATION_LOG << "Failed to encode root pass blit command.";
405  return false;
406  }
407  } else {
408  auto render_pass = command_buffer->CreateRenderPass(root_render_target);
409  render_pass->SetLabel("EntityPass Root Render Pass");
410 
411  {
412  auto size_rect = Rect::MakeSize(
413  offscreen_target.GetRenderTarget().GetRenderTargetSize());
414  auto contents = TextureContents::MakeRect(size_rect);
415  contents->SetTexture(
416  offscreen_target.GetRenderTarget().GetRenderTargetTexture());
417  contents->SetSourceRect(size_rect);
418  contents->SetLabel("Root pass blit");
419 
420  Entity entity;
421  entity.SetContents(contents);
422  entity.SetBlendMode(BlendMode::kSource);
423 
424  entity.Render(renderer, *render_pass);
425  }
426 
427  if (!render_pass->EncodeCommands()) {
428  VALIDATION_LOG << "Failed to encode root pass command buffer.";
429  return false;
430  }
431  }
432  if (!command_buffer->SubmitCommands()) {
433  VALIDATION_LOG << "Failed to submit root pass command buffer.";
434  return false;
435  }
436 
437  return true;
438  }
439 
440  // If we make it this far, that means the context is capable of rendering
441  // everything directly to the onscreen texture.
442 
443  // The safety check for fetching this color attachment is at the beginning of
444  // this method.
445  auto color0 = root_render_target.GetColorAttachments().find(0u)->second;
446 
447  // If a root stencil was provided by the caller, then verify that it has a
448  // configuration which can be used to render this pass.
449  auto stencil_attachment = root_render_target.GetStencilAttachment();
450  if (stencil_attachment.has_value()) {
451  auto stencil_texture = stencil_attachment->texture;
452  if (!stencil_texture) {
453  VALIDATION_LOG << "The root RenderTarget must have a stencil texture.";
454  return false;
455  }
456 
457  auto stencil_storage_mode =
458  stencil_texture->GetTextureDescriptor().storage_mode;
459  if (reads_from_onscreen_backdrop &&
460  stencil_storage_mode == StorageMode::kDeviceTransient) {
461  VALIDATION_LOG << "The given root RenderTarget stencil needs to be read, "
462  "but it's marked as transient.";
463  return false;
464  }
465  }
466  // Setup a new root stencil with an optimal configuration if one wasn't
467  // provided by the caller.
468  else {
469  root_render_target.SetupStencilAttachment(
470  *renderer.GetContext(), *renderer.GetRenderTargetCache(),
471  color0.texture->GetSize(),
472  renderer.GetContext()->GetCapabilities()->SupportsOffscreenMSAA(),
473  "ImpellerOnscreen",
474  GetDefaultStencilConfig(reads_from_onscreen_backdrop));
475  }
476 
477  // Set up the clear color of the root pass.
478  color0.clear_color = GetClearColor(render_target.GetRenderTargetSize());
479  root_render_target.SetColorAttachment(color0, 0);
480 
481  EntityPassTarget pass_target(
482  root_render_target,
483  renderer.GetDeviceCapabilities().SupportsReadFromResolve());
484 
485  return OnRender( //
486  renderer, // renderer
487  capture, // capture
488  root_render_target.GetRenderTargetSize(), // root_pass_size
489  pass_target, // pass_target
490  Point(), // global_pass_position
491  Point(), // local_pass_position
492  0, // pass_depth
493  stencil_coverage_stack); // stencil_coverage_stack
494 }

References impeller::ContentContext::GetContext(), impeller::ContentContext::GetLazyGlyphAtlas(), impeller::ContentContext::GetRenderTargetCache(), IterateAllEntities(), kCaptureDocumentName, impeller::TRect< Scalar >::MakeSize(), and VALIDATION_LOG.

Referenced by impeller::EntityPlayground::OpenPlaygroundHere().

◆ SetBackdropFilter()

void impeller::EntityPass::SetBackdropFilter ( BackdropFilterProc  proc)

Definition at line 1160 of file entity_pass.cc.

1160  {
1161  if (superpass_) {
1162  VALIDATION_LOG << "Backdrop filters cannot be set on EntityPasses that "
1163  "have already been appended to another pass.";
1164  }
1165 
1166  backdrop_filter_proc_ = std::move(proc);
1167 }

References VALIDATION_LOG.

◆ SetBlendMode()

void impeller::EntityPass::SetBlendMode ( BlendMode  blend_mode)

Definition at line 1138 of file entity_pass.cc.

1138  {
1139  blend_mode_ = blend_mode;
1140  flood_clip_ = Entity::IsBlendModeDestructive(blend_mode);
1141 }

◆ SetBoundsLimit()

void impeller::EntityPass::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 allows the user to communicate that it's OK to not render content outside of the bounds.

For consistency with Skia, we effectively treat this like a rectangle clip by forcing the subpass texture size to never exceed it.

Definition at line 69 of file entity_pass.cc.

69  {
70  bounds_limit_ = bounds_limit;
71 }

◆ SetDelegate()

void impeller::EntityPass::SetDelegate ( std::shared_ptr< EntityPassDelegate delgate)

Definition at line 62 of file entity_pass.cc.

62  {
63  if (!delegate) {
64  return;
65  }
66  delegate_ = std::move(delegate);
67 }

◆ SetElements()

void impeller::EntityPass::SetElements ( std::vector< Element elements)

Definition at line 89 of file entity_pass.cc.

89  {
90  elements_ = std::move(elements);
91 }

◆ SetEnableOffscreenCheckerboard()

void impeller::EntityPass::SetEnableOffscreenCheckerboard ( bool  enabled)

Definition at line 1169 of file entity_pass.cc.

1169  {
1170  enable_offscreen_debug_checkerboard_ = enabled;
1171 }

◆ SetStencilDepth()

void impeller::EntityPass::SetStencilDepth ( size_t  stencil_depth)

Definition at line 1130 of file entity_pass.cc.

1130  {
1131  stencil_depth_ = stencil_depth;
1132 }

◆ SetTransformation()

void impeller::EntityPass::SetTransformation ( Matrix  xformation)

Definition at line 1126 of file entity_pass.cc.

1126  {
1127  xformation_ = xformation;
1128 }

Member Data Documentation

◆ kCaptureDocumentName

const std::string impeller::EntityPass::kCaptureDocumentName = "EntityPass"
static

Definition at line 39 of file entity_pass.h.

Referenced by Render().


The documentation for this class was generated from the following files:
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::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:23
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
impeller::EntityPass::EntityPass
EntityPass()
impeller::FilterInput::Make
static FilterInput::Ref Make(Variant input, bool msaa_enabled=true)
Definition: filter_input.cc:19
impeller::Entity::IsBlendModeDestructive
static bool IsBlendModeDestructive(BlendMode blend_mode)
Returns true if the blend mode is "destructive", meaning that even fully transparent source colors wo...
Definition: entity.cc:138
impeller::CreateRenderTarget
static EntityPassTarget CreateRenderTarget(ContentContext &renderer, ISize size, bool readable, const Color &clear_color)
Definition: entity_pass.cc:270
impeller::StorageMode::kDeviceTransient
@ kDeviceTransient
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::EntityPass::StencilCoverageStack
std::vector< StencilCoverageLayer > StencilCoverageStack
Definition: entity_pass.h:51
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::EntityPass::Element
std::variant< Entity, std::unique_ptr< EntityPass > > Element
Definition: entity_pass.h:37
impeller::GetDefaultStencilConfig
static RenderTarget::AttachmentConfig GetDefaultStencilConfig(bool readable)
Definition: entity_pass.cc:261
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::Entity::RenderingMode::kSubpass
@ kSubpass
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:52
impeller::EntityPass::GetClearColor
Color GetClearColor(ISize size=ISize::Infinite()) const
Definition: entity_pass.cc:1143
impeller::Color::BlackTransparent
static constexpr Color BlackTransparent()
Definition: color.h:260
impeller::EntityPass::kCaptureDocumentName
static const std::string kCaptureDocumentName
Definition: entity_pass.h:39
impeller::TextureContents::MakeRect
static std::shared_ptr< TextureContents > MakeRect(Rect destination)
A common case factory that marks the texture contents as having a destination rectangle....
Definition: texture_contents.cc:28
impeller::BlendMode::kSource
@ kSource