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 pass_texture_reads, 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  pass_texture_reads,
uint32_t  entity_count,
std::optional< RenderPassResult collapsed_parent_pass = std::nullopt 
)

Definition at line 20 of file inline_pass_context.cc.

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

◆ ~InlinePassContext()

impeller::InlinePassContext::~InlinePassContext ( )

Definition at line 35 of file inline_pass_context.cc.

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

References EndPass().

Member Function Documentation

◆ EndPass()

bool impeller::InlinePassContext::EndPass ( )

Definition at line 56 of file inline_pass_context.cc.

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

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 208 of file inline_pass_context.cc.

208  {
209  return pass_count_;
210 }

◆ GetPassTarget()

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

Definition at line 90 of file inline_pass_context.cc.

90  {
91  return pass_target_;
92 }

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 94 of file inline_pass_context.cc.

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

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::ContentContext::kEnableStencilThenCover, 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 49 of file inline_pass_context.cc.

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

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

◆ IsActive()

bool impeller::InlinePassContext::IsActive ( ) const

Definition at line 45 of file inline_pass_context.cc.

45  {
46  return pass_ != nullptr;
47 }

Referenced by EndPass(), and GetRenderPass().

◆ IsValid()

bool impeller::InlinePassContext::IsValid ( ) const

Definition at line 41 of file inline_pass_context.cc.

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

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::ContentContext::kEnableStencilThenCover
static constexpr bool kEnableStencilThenCover
Definition: content_context.h:411
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:45
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:564
impeller::StoreAction::kStore
@ kStore
impeller::InlinePassContext::EndPass
bool EndPass()
Definition: inline_pass_context.cc:56
impeller::InlinePassContext::IsValid
bool IsValid() const
Definition: inline_pass_context.cc:41
impeller::InlinePassContext::GetPassTarget
EntityPassTarget & GetPassTarget() const
Definition: inline_pass_context.cc:90
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