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  // When MSAA is being used, we end up overriding the entire backdrop by
112  // drawing the previous pass texture, and so we don't have to clear it and
113  // can use kDontCare.
115  } else {
117  }
118 
119  color0.store_action =
121 
122  auto depth = pass_target_.GetRenderTarget().GetDepthAttachment();
123  if (!depth.has_value()) {
124  VALIDATION_LOG << "Depth attachment unexpectedly missing from the "
125  "EntityPass render target.";
126  return pass_;
127  }
128  depth->load_action = LoadAction::kClear;
129  depth->store_action = StoreAction::kDontCare;
130  pass_target_.target_.SetDepthAttachment(depth.value());
131 
132  auto stencil = pass_target_.GetRenderTarget().GetStencilAttachment();
133  if (!depth.has_value() || !stencil.has_value()) {
134  VALIDATION_LOG << "Stencil/Depth attachment unexpectedly missing from the "
135  "EntityPass render target.";
136  return pass_;
137  }
138  stencil->load_action = LoadAction::kClear;
139  stencil->store_action = StoreAction::kDontCare;
140  depth->load_action = LoadAction::kClear;
141  depth->store_action = StoreAction::kDontCare;
142  pass_target_.target_.SetDepthAttachment(depth);
143  pass_target_.target_.SetStencilAttachment(stencil.value());
144  pass_target_.target_.SetColorAttachment(color0, 0);
145 
146  pass_ = command_buffer_->CreateRenderPass(pass_target_.GetRenderTarget());
147  if (!pass_) {
148  VALIDATION_LOG << "Could not create render pass.";
149  return pass_;
150  }
151  pass_->SetLabel("EntityPass Render Pass");
152 
153  ++pass_count_;
154  return pass_;
155 }
156 
158  return pass_count_;
159 }
160 
161 } // 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