Flutter Impeller
impeller::InlinePassContext Class Reference

#include <inline_pass_context.h>

Classes

struct  RenderPassResult
 

Public Member Functions

 InlinePassContext (const ContentContext &renderer, EntityPassTarget &pass_target, uint32_t entity_count, std::optional< RenderPassResult > collapsed_parent_pass=std::nullopt)
 
 ~InlinePassContext ()
 
bool IsValid () const
 
bool IsActive () const
 
std::shared_ptr< TextureGetTexture ()
 
bool EndPass ()
 
EntityPassTargetGetPassTarget () const
 
uint32_t GetPassCount () const
 
RenderPassResult GetRenderPass (uint32_t pass_depth)
 

Detailed Description

Definition at line 17 of file inline_pass_context.h.

Constructor & Destructor Documentation

◆ InlinePassContext()

impeller::InlinePassContext::InlinePassContext ( const ContentContext renderer,
EntityPassTarget pass_target,
uint32_t  entity_count,
std::optional< RenderPassResult collapsed_parent_pass = std::nullopt 
)

Definition at line 20 of file inline_pass_context.cc.

25  : renderer_(renderer),
26  pass_target_(pass_target),
27  entity_count_(entity_count),
28  is_collapsed_(collapsed_parent_pass.has_value()) {
29  if (collapsed_parent_pass.has_value()) {
30  pass_ = collapsed_parent_pass.value().pass;
31  }
32 }

◆ ~InlinePassContext()

impeller::InlinePassContext::~InlinePassContext ( )

Definition at line 34 of file inline_pass_context.cc.

34  {
35  if (!is_collapsed_) {
36  EndPass();
37  }
38 }

References EndPass().

Member Function Documentation

◆ EndPass()

bool impeller::InlinePassContext::EndPass ( )

Definition at line 55 of file inline_pass_context.cc.

55  {
56  if (!IsActive()) {
57  return true;
58  }
59  FML_DCHECK(command_buffer_);
60 
61  if (!pass_->EncodeCommands()) {
62  VALIDATION_LOG << "Failed to encode and submit command buffer while ending "
63  "render pass.";
64  return false;
65  }
66 
67  const std::shared_ptr<Texture>& target_texture =
69  if (target_texture->GetMipCount() > 1) {
70  fml::Status mip_status = AddMipmapGeneration(
71  command_buffer_, renderer_.GetContext(), target_texture);
72  if (!mip_status.ok()) {
73  return false;
74  }
75  }
76  if (!renderer_.GetContext()
77  ->GetCommandQueue()
78  ->Submit({std::move(command_buffer_)})
79  .ok()) {
80  return false;
81  }
82 
83  pass_ = nullptr;
84  command_buffer_ = nullptr;
85 
86  return true;
87 }

References impeller::AddMipmapGeneration(), impeller::ContentContext::GetContext(), GetPassTarget(), impeller::EntityPassTarget::GetRenderTarget(), impeller::RenderTarget::GetRenderTargetTexture(), IsActive(), and VALIDATION_LOG.

Referenced by ~InlinePassContext().

◆ GetPassCount()

uint32_t impeller::InlinePassContext::GetPassCount ( ) const

Definition at line 204 of file inline_pass_context.cc.

204  {
205  return pass_count_;
206 }

◆ GetPassTarget()

EntityPassTarget & impeller::InlinePassContext::GetPassTarget ( ) const

Definition at line 89 of file inline_pass_context.cc.

89  {
90  return pass_target_;
91 }

Referenced by EndPass().

◆ GetRenderPass()

InlinePassContext::RenderPassResult impeller::InlinePassContext::GetRenderPass ( uint32_t  pass_depth)

Create a new render pass if one isn't active. This path will run the first time this method is called, but it'll also run if the pass has been previously ended via EndPass.

Definition at line 93 of file inline_pass_context.cc.

94  {
95  if (IsActive()) {
96  return {.pass = pass_};
97  }
98 
99  /// Create a new render pass if one isn't active. This path will run the first
100  /// time this method is called, but it'll also run if the pass has been
101  /// previously ended via `EndPass`.
102 
103  command_buffer_ = renderer_.GetContext()->CreateCommandBuffer();
104  if (!command_buffer_) {
105  VALIDATION_LOG << "Could not create command buffer.";
106  return {};
107  }
108 
109  if (pass_target_.GetRenderTarget().GetColorAttachments().empty()) {
110  VALIDATION_LOG << "Color attachment unexpectedly missing from the "
111  "EntityPass render target.";
112  return {};
113  }
114 
115  command_buffer_->SetLabel(
116  "EntityPass Command Buffer: Depth=" + std::to_string(pass_depth) +
117  " Count=" + std::to_string(pass_count_));
118 
119  RenderPassResult result;
120  {
121  // If the pass target has a resolve texture, then we're using MSAA.
122  bool is_msaa = pass_target_.GetRenderTarget()
124  .find(0)
125  ->second.resolve_texture != nullptr;
126  if (pass_count_ > 0 && is_msaa) {
127  result.backdrop_texture =
128  pass_target_.Flip(*renderer_.GetContext()->GetResourceAllocator());
129  if (!result.backdrop_texture) {
130  VALIDATION_LOG << "Could not flip the EntityPass render target.";
131  }
132  }
133  }
134 
135  // Find the color attachment a second time, since the target may have just
136  // flipped.
137  auto color0 =
138  pass_target_.GetRenderTarget().GetColorAttachments().find(0)->second;
139  bool is_msaa = color0.resolve_texture != nullptr;
140 
141  if (pass_count_ > 0) {
142  // When MSAA is being used, we end up overriding the entire backdrop by
143  // drawing the previous pass texture, and so we don't have to clear it and
144  // can use kDontCare.
145  color0.load_action = is_msaa ? LoadAction::kDontCare : LoadAction::kLoad;
146  } else {
147  color0.load_action = LoadAction::kClear;
148  }
149 
150  color0.store_action =
152 
153  auto depth = pass_target_.GetRenderTarget().GetDepthAttachment();
154  if (!depth.has_value()) {
155  VALIDATION_LOG << "Depth attachment unexpectedly missing from the "
156  "EntityPass render target.";
157  return {};
158  }
159  depth->load_action = LoadAction::kClear;
160  depth->store_action = StoreAction::kDontCare;
161  pass_target_.target_.SetDepthAttachment(depth.value());
162 
163  auto stencil = pass_target_.GetRenderTarget().GetStencilAttachment();
164  if (!depth.has_value() || !stencil.has_value()) {
165  VALIDATION_LOG << "Stencil/Depth attachment unexpectedly missing from the "
166  "EntityPass render target.";
167  return {};
168  }
169  stencil->load_action = LoadAction::kClear;
170  stencil->store_action = StoreAction::kDontCare;
171  depth->load_action = LoadAction::kClear;
172  depth->store_action = StoreAction::kDontCare;
173  pass_target_.target_.SetDepthAttachment(depth);
174  pass_target_.target_.SetStencilAttachment(stencil.value());
175  pass_target_.target_.SetColorAttachment(color0, 0);
176 
177  pass_ = command_buffer_->CreateRenderPass(pass_target_.GetRenderTarget());
178  if (!pass_) {
179  VALIDATION_LOG << "Could not create render pass.";
180  return {};
181  }
182  // Commands are fairly large (500B) objects, so re-allocation of the command
183  // buffer while encoding can add a surprising amount of overhead. We make a
184  // conservative npot estimate to avoid this case.
185  pass_->ReserveCommands(Allocation::NextPowerOfTwoSize(entity_count_));
186  pass_->SetLabel(
187  "EntityPass Render Pass: Depth=" + std::to_string(pass_depth) +
188  " Count=" + std::to_string(pass_count_));
189 
190  result.pass = pass_;
191  result.just_created = true;
192 
193  if (!renderer_.GetContext()->GetCapabilities()->SupportsReadFromResolve() &&
194  result.backdrop_texture ==
195  result.pass->GetRenderTarget().GetRenderTargetTexture()) {
196  VALIDATION_LOG << "EntityPass backdrop restore configuration is not valid "
197  "for the current graphics backend.";
198  }
199 
200  ++pass_count_;
201  return result;
202 }

References impeller::InlinePassContext::RenderPassResult::backdrop_texture, impeller::EntityPassTarget::Flip(), impeller::RenderTarget::GetColorAttachments(), impeller::ContentContext::GetContext(), impeller::RenderTarget::GetDepthAttachment(), impeller::EntityPassTarget::GetRenderTarget(), impeller::RenderTarget::GetStencilAttachment(), IsActive(), impeller::InlinePassContext::RenderPassResult::just_created, impeller::kClear, impeller::kDontCare, impeller::kLoad, impeller::kMultisampleResolve, impeller::kStore, impeller::Allocation::NextPowerOfTwoSize(), impeller::InlinePassContext::RenderPassResult::pass, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetDepthAttachment(), impeller::RenderTarget::SetStencilAttachment(), and VALIDATION_LOG.

◆ GetTexture()

std::shared_ptr< Texture > impeller::InlinePassContext::GetTexture ( )

Definition at line 48 of file inline_pass_context.cc.

48  {
49  if (!IsValid()) {
50  return nullptr;
51  }
52  return pass_target_.GetRenderTarget().GetRenderTargetTexture();
53 }

References impeller::EntityPassTarget::GetRenderTarget(), impeller::RenderTarget::GetRenderTargetTexture(), and IsValid().

◆ IsActive()

bool impeller::InlinePassContext::IsActive ( ) const

Definition at line 44 of file inline_pass_context.cc.

44  {
45  return pass_ != nullptr;
46 }

Referenced by EndPass(), and GetRenderPass().

◆ IsValid()

bool impeller::InlinePassContext::IsValid ( ) const

Definition at line 40 of file inline_pass_context.cc.

40  {
41  return pass_target_.IsValid();
42 }

References impeller::EntityPassTarget::IsValid().

Referenced by GetTexture().


The documentation for this class was generated from the following files:
impeller::StoreAction::kMultisampleResolve
@ kMultisampleResolve
impeller::LoadAction::kLoad
@ kLoad
impeller::AddMipmapGeneration
fml::Status AddMipmapGeneration(const std::shared_ptr< CommandBuffer > &command_buffer, const std::shared_ptr< Context > &context, const std::shared_ptr< Texture > &texture)
Adds a blit command to the render pass.
Definition: texture_mipmap.cc:11
impeller::EntityPassTarget::IsValid
bool IsValid() const
Definition: entity_pass_target.cc:72
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
impeller::RenderTarget::SetColorAttachment
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
Definition: render_target.cc:169
impeller::StoreAction::kDontCare
@ kDontCare
impeller::RenderTarget::GetColorAttachments
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
Definition: render_target.cc:198
impeller::LoadAction::kClear
@ kClear
impeller::RenderTarget::GetDepthAttachment
const std::optional< DepthAttachment > & GetDepthAttachment() const
Definition: render_target.cc:203
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:144
impeller::InlinePassContext::IsActive
bool IsActive() const
Definition: inline_pass_context.cc:44
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:553
impeller::StoreAction::kStore
@ kStore
impeller::InlinePassContext::EndPass
bool EndPass()
Definition: inline_pass_context.cc:55
impeller::InlinePassContext::IsValid
bool IsValid() const
Definition: inline_pass_context.cc:40
impeller::InlinePassContext::GetPassTarget
EntityPassTarget & GetPassTarget() const
Definition: inline_pass_context.cc:89
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::RenderTarget::SetStencilAttachment
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
Definition: render_target.cc:188
impeller::LoadAction::kDontCare
@ kDontCare
impeller::RenderTarget::GetStencilAttachment
const std::optional< StencilAttachment > & GetStencilAttachment() const
Definition: render_target.cc:207
impeller::RenderTarget::SetDepthAttachment
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
Definition: render_target.cc:178
impeller::EntityPassTarget::GetRenderTarget
const RenderTarget & GetRenderTarget() const
Definition: entity_pass_target.cc:68
impeller::EntityPassTarget::Flip
std::shared_ptr< Texture > Flip(Allocator &allocator)
Flips the backdrop and returns a readable texture that can be bound/sampled to restore the previous p...
Definition: entity_pass_target.cc:20