Flutter Impeller
inline_pass_context.cc
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 
6 
7 #include <utility>
8 
10 #include "impeller/core/formats.h"
14 
15 namespace impeller {
16 
18  std::shared_ptr<Context> context,
19  EntityPassTarget& pass_target,
20  uint32_t pass_texture_reads,
21  uint32_t entity_count,
22  std::optional<RenderPassResult> collapsed_parent_pass)
23  : context_(std::move(context)),
24  pass_target_(pass_target),
25  entity_count_(entity_count),
26  total_pass_reads_(pass_texture_reads),
27  is_collapsed_(collapsed_parent_pass.has_value()) {
28  if (collapsed_parent_pass.has_value()) {
29  pass_ = collapsed_parent_pass.value().pass;
30  }
31 }
32 
34  if (!is_collapsed_) {
35  EndPass();
36  }
37 }
38 
40  return pass_target_.IsValid();
41 }
42 
44  return pass_ != nullptr;
45 }
46 
47 std::shared_ptr<Texture> InlinePassContext::GetTexture() {
48  if (!IsValid()) {
49  return nullptr;
50  }
51  return pass_target_.GetRenderTarget().GetRenderTargetTexture();
52 }
53 
55  if (!IsActive()) {
56  return true;
57  }
58 
59  if (command_buffer_) {
60  if (!command_buffer_->EncodeAndSubmit(pass_)) {
62  << "Failed to encode and submit command buffer while ending "
63  "render pass.";
64  return false;
65  }
66  }
67 
68  pass_ = nullptr;
69  command_buffer_ = nullptr;
70 
71  return true;
72 }
73 
75  return pass_target_;
76 }
77 
79  uint32_t pass_depth) {
80  if (IsActive()) {
81  return {.pass = pass_};
82  }
83 
84  /// Create a new render pass if one isn't active. This path will run the first
85  /// time this method is called, but it'll also run if the pass has been
86  /// previously ended via `EndPass`.
87 
88  command_buffer_ = context_->CreateCommandBuffer();
89  if (!command_buffer_) {
90  VALIDATION_LOG << "Could not create command buffer.";
91  return {};
92  }
93 
94  if (pass_target_.GetRenderTarget().GetColorAttachments().empty()) {
95  VALIDATION_LOG << "Color attachment unexpectedly missing from the "
96  "EntityPass render target.";
97  return {};
98  }
99 
100  command_buffer_->SetLabel(
101  "EntityPass Command Buffer: Depth=" + std::to_string(pass_depth) +
102  " Count=" + std::to_string(pass_count_));
103 
104  RenderPassResult result;
105  {
106  // If the pass target has a resolve texture, then we're using MSAA.
107  bool is_msaa = pass_target_.GetRenderTarget()
109  .find(0)
110  ->second.resolve_texture != nullptr;
111  if (pass_count_ > 0 && is_msaa) {
112  result.backdrop_texture =
113  pass_target_.Flip(*context_->GetResourceAllocator());
114  if (!result.backdrop_texture) {
115  VALIDATION_LOG << "Could not flip the EntityPass render target.";
116  }
117  }
118  }
119 
120  // Find the color attachment a second time, since the target may have just
121  // flipped.
122  auto color0 =
123  pass_target_.GetRenderTarget().GetColorAttachments().find(0)->second;
124  bool is_msaa = color0.resolve_texture != nullptr;
125 
126  if (pass_count_ > 0) {
127  // When MSAA is being used, we end up overriding the entire backdrop by
128  // drawing the previous pass texture, and so we don't have to clear it and
129  // can use kDontCare.
130  color0.load_action = is_msaa ? LoadAction::kDontCare : LoadAction::kLoad;
131  } else {
132  color0.load_action = LoadAction::kClear;
133  }
134 
135  color0.store_action =
137 
138  auto stencil = pass_target_.GetRenderTarget().GetStencilAttachment();
139  if (!stencil.has_value()) {
140  VALIDATION_LOG << "Stencil attachment unexpectedly missing from the "
141  "EntityPass render target.";
142  return {};
143  }
144 
145  // Only clear the stencil if this is the very first pass of the
146  // layer.
147  stencil->load_action =
148  pass_count_ > 0 ? LoadAction::kLoad : LoadAction::kClear;
149  // If we're on the last pass of the layer, there's no need to store the
150  // stencil because nothing needs to read it.
151  stencil->store_action = pass_count_ == total_pass_reads_
154  pass_target_.target_.SetStencilAttachment(stencil.value());
155 
156  pass_target_.target_.SetColorAttachment(color0, 0);
157 
158  pass_ = command_buffer_->CreateRenderPass(pass_target_.GetRenderTarget());
159  if (!pass_) {
160  VALIDATION_LOG << "Could not create render pass.";
161  return {};
162  }
163  // Commands are fairly large (500B) objects, so re-allocation of the command
164  // buffer while encoding can add a surprising amount of overhead. We make a
165  // conservative npot estimate to avoid this case.
166  pass_->ReserveCommands(Allocation::NextPowerOfTwoSize(entity_count_));
167  pass_->SetLabel(
168  "EntityPass Render Pass: Depth=" + std::to_string(pass_depth) +
169  " Count=" + std::to_string(pass_count_));
170 
171  result.pass = pass_;
172 
173  if (!context_->GetCapabilities()->SupportsReadFromResolve() &&
174  result.backdrop_texture ==
175  result.pass->GetRenderTarget().GetRenderTargetTexture()) {
176  VALIDATION_LOG << "EntityPass backdrop restore configuration is not valid "
177  "for the current graphics backend.";
178  }
179 
180  ++pass_count_;
181  return result;
182 }
183 
185  return pass_count_;
186 }
187 
188 } // namespace impeller
impeller::StoreAction::kMultisampleResolve
@ kMultisampleResolve
impeller::LoadAction::kLoad
@ kLoad
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:180
texture_descriptor.h
formats.h
impeller::StoreAction::kDontCare
@ kDontCare
impeller::EntityPassTarget
Definition: entity_pass_target.h:15
impeller::RenderTarget::GetColorAttachments
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
Definition: render_target.cc:209
impeller::InlinePassContext::RenderPassResult
Definition: inline_pass_context.h:19
validation.h
impeller::InlinePassContext::RenderPassResult::backdrop_texture
std::shared_ptr< Texture > backdrop_texture
Definition: inline_pass_context.h:21
impeller::InlinePassContext::GetPassCount
uint32_t GetPassCount() const
Definition: inline_pass_context.cc:184
impeller::LoadAction::kClear
@ kClear
impeller::RenderTarget::GetRenderTargetTexture
std::shared_ptr< Texture > GetRenderTargetTexture() const
Definition: render_target.cc:155
impeller::InlinePassContext::IsActive
bool IsActive() const
Definition: inline_pass_context.cc:43
impeller::InlinePassContext::GetRenderPass
RenderPassResult GetRenderPass(uint32_t pass_depth)
Definition: inline_pass_context.cc:78
impeller::InlinePassContext::GetTexture
std::shared_ptr< Texture > GetTexture()
Definition: inline_pass_context.cc:47
impeller::StoreAction::kStore
@ kStore
impeller::InlinePassContext::EndPass
bool EndPass()
Definition: inline_pass_context.cc:54
entity_pass_target.h
impeller::InlinePassContext::IsValid
bool IsValid() const
Definition: inline_pass_context.cc:39
impeller::InlinePassContext::InlinePassContext
InlinePassContext(std::shared_ptr< Context > context, EntityPassTarget &pass_target, uint32_t pass_texture_reads, uint32_t entity_count, std::optional< RenderPassResult > collapsed_parent_pass=std::nullopt)
Definition: inline_pass_context.cc:17
impeller::InlinePassContext::GetPassTarget
EntityPassTarget & GetPassTarget() const
Definition: inline_pass_context.cc:74
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
command_buffer.h
impeller::RenderTarget::SetStencilAttachment
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
Definition: render_target.cc:199
std
Definition: comparable.h:95
impeller::LoadAction::kDontCare
@ kDontCare
impeller::InlinePassContext::~InlinePassContext
~InlinePassContext()
Definition: inline_pass_context.cc:33
impeller::RenderTarget::GetStencilAttachment
const std::optional< StencilAttachment > & GetStencilAttachment() const
Definition: render_target.cc:218
impeller::InlinePassContext::RenderPassResult::pass
std::shared_ptr< RenderPass > pass
Definition: inline_pass_context.h:20
impeller
Definition: aiks_context.cc:10
impeller::EntityPassTarget::GetRenderTarget
const RenderTarget & GetRenderTarget() const
Definition: entity_pass_target.cc:68
inline_pass_context.h
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