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 
9 #include "flutter/fml/status.h"
11 #include "impeller/core/formats.h"
17 
18 namespace impeller {
19 
21  EntityPassTarget& pass_target)
22  : renderer_(renderer), pass_target_(pass_target) {}
23 
25  EndPass();
26 }
27 
29  return pass_target_.IsValid();
30 }
31 
33  return pass_ != nullptr;
34 }
35 
36 std::shared_ptr<Texture> InlinePassContext::GetTexture() {
37  if (!IsValid()) {
38  return nullptr;
39  }
40  return pass_target_.GetRenderTarget().GetRenderTargetTexture();
41 }
42 
43 bool InlinePassContext::EndPass(bool is_onscreen) {
44  if (!IsActive()) {
45  return true;
46  }
47  FML_DCHECK(command_buffer_);
48 
49  if (!pass_->EncodeCommands()) {
50  VALIDATION_LOG << "Failed to encode and submit command buffer while ending "
51  "render pass.";
52  return false;
53  }
54 
55  const std::shared_ptr<Texture>& target_texture =
57  if (target_texture->GetMipCount() > 1) {
58  fml::Status mip_status = AddMipmapGeneration(
59  command_buffer_, renderer_.GetContext(), target_texture);
60  if (!mip_status.ok()) {
61  return false;
62  }
63  }
64 
65  pass_ = nullptr;
66  if (is_onscreen) {
67  return renderer_.GetContext()->SubmitOnscreen(std::move(command_buffer_));
68  } else {
69  return renderer_.GetContext()->EnqueueCommandBuffer(
70  std::move(command_buffer_));
71  }
72 }
73 
75  return pass_target_;
76 }
77 
78 const std::shared_ptr<RenderPass>& InlinePassContext::GetRenderPass() {
79  if (IsActive()) {
80  return pass_;
81  }
82 
83  /// Create a new render pass if one isn't active. This path will run the first
84  /// time this method is called, but it'll also run if the pass has been
85  /// previously ended via `EndPass`.
86 
87  command_buffer_ = renderer_.GetContext()->CreateCommandBuffer();
88  if (!command_buffer_) {
89  VALIDATION_LOG << "Could not create command buffer.";
90  return pass_;
91  }
92 
93  command_buffer_->SetLabel("EntityPass Command Buffer");
94 
95  {
96  // If the pass target has a resolve texture, then we're using MSAA.
97  bool is_msaa =
99  nullptr;
100  if (pass_count_ > 0 && is_msaa) {
101  pass_target_.Flip(renderer_);
102  }
103  }
104 
105  // Find the color attachment a second time, since the target may have just
106  // flipped.
107  ColorAttachment color0 = pass_target_.GetRenderTarget().GetColorAttachment(0);
108  bool is_msaa = color0.resolve_texture != nullptr;
109 
110  if (pass_count_ > 0) {
111  color0.load_action = is_msaa ? LoadAction::kClear : LoadAction::kLoad;
112  } else {
114  }
115 
116  color0.store_action =
118 
119  auto depth = pass_target_.GetRenderTarget().GetDepthAttachment();
120  if (!depth.has_value()) {
121  VALIDATION_LOG << "Depth attachment unexpectedly missing from the "
122  "EntityPass render target.";
123  return pass_;
124  }
125  depth->load_action = LoadAction::kClear;
126  depth->store_action = StoreAction::kDontCare;
127  pass_target_.target_.SetDepthAttachment(depth.value());
128 
129  auto stencil = pass_target_.GetRenderTarget().GetStencilAttachment();
130  if (!depth.has_value() || !stencil.has_value()) {
131  VALIDATION_LOG << "Stencil/Depth attachment unexpectedly missing from the "
132  "EntityPass render target.";
133  return pass_;
134  }
135  stencil->load_action = LoadAction::kClear;
136  stencil->store_action = StoreAction::kDontCare;
137  depth->load_action = LoadAction::kClear;
138  depth->store_action = StoreAction::kDontCare;
139  pass_target_.target_.SetDepthAttachment(depth);
140  pass_target_.target_.SetStencilAttachment(stencil.value());
141  pass_target_.target_.SetColorAttachment(color0, 0);
142 
143  pass_ = command_buffer_->CreateRenderPass(pass_target_.GetRenderTarget());
144  if (!pass_) {
145  VALIDATION_LOG << "Could not create render pass.";
146  return pass_;
147  }
148  pass_->SetLabel("EntityPass Render Pass");
149 
150  ++pass_count_;
151  return pass_;
152 }
153 
155  return pass_count_;
156 }
157 
158 } // namespace impeller
std::shared_ptr< Context > GetContext() const
std::shared_ptr< Texture > Flip(const ContentContext &renderer)
Flips the backdrop and returns a readable texture that can be bound/sampled to restore the previous p...
bool EndPass(bool is_onscreen=false)
EntityPassTarget & GetPassTarget() const
std::shared_ptr< Texture > GetTexture()
InlinePassContext(const ContentContext &renderer, EntityPassTarget &pass_target)
const std::shared_ptr< RenderPass > & GetRenderPass()
ColorAttachment GetColorAttachment(size_t index) const
Get the color attachment at [index].
std::shared_ptr< Texture > GetRenderTargetTexture() const
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
const std::optional< DepthAttachment > & GetDepthAttachment() const
const std::optional< StencilAttachment > & GetStencilAttachment() const
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_util.cc:37
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:658
LoadAction load_action
Definition: formats.h:659
StoreAction store_action
Definition: formats.h:660
#define VALIDATION_LOG
Definition: validation.h:91