88#include " impeller/geometry/path_builder.h"
99#include " impeller/renderer/command_buffer.h"
1010#include " impeller/renderer/render_pass.h"
11- #include " impeller/renderer/render_target.h"
1211
1312namespace impeller {
1413
15- CanvasPass::CanvasPass () = default ;
14+ CanvasPass::CanvasPass (std::unique_ptr<CanvasPassDelegate> delegate)
15+ : delegate_(std::move(delegate)) {
16+ if (!delegate_) {
17+ delegate_ = CanvasPassDelegate::MakeDefault ();
18+ }
19+ }
1620
1721CanvasPass::~CanvasPass () = default ;
1822
@@ -85,8 +89,12 @@ bool CanvasPass::Render(ContentRenderer& renderer,
8589 }
8690 }
8791 for (const auto & subpass : subpasses_) {
88- if (!subpass) {
89- return false ;
92+ if (delegate_->CanCollapseIntoParentPass ()) {
93+ // Directly render into the parent pass and move on.
94+ if (!subpass->Render (renderer, parent_pass)) {
95+ return false ;
96+ }
97+ continue ;
9098 }
9199
92100 const auto subpass_coverage = subpass->GetCoverageRect ();
@@ -102,6 +110,27 @@ bool CanvasPass::Render(ContentRenderer& renderer,
102110 auto subpass_target = RenderTarget::CreateOffscreen (
103111 *context, ISize::Ceil (subpass_coverage.size ));
104112
113+ auto subpass_texture = subpass_target.GetRenderTargetTexture ();
114+
115+ if (!subpass_texture) {
116+ return false ;
117+ }
118+
119+ auto offscreen_texture_contents =
120+ delegate_->CreateContentsForSubpassTarget (*subpass_texture);
121+
122+ if (!offscreen_texture_contents) {
123+ // This is an error because the subpass delegate said the pass couldn't be
124+ // collapsed into its parent. Yet, when asked how it want's to postprocess
125+ // the offscreen texture, it couldn't give us an answer.
126+ //
127+ // Theoretically, we could collapse the pass now. But that would be
128+ // wasteful as we already have the offscreen texture and we don't want to
129+ // discard it without ever using it. Just make the delegate do the right
130+ // thing.
131+ return false ;
132+ }
133+
105134 auto sub_command_buffer = context->CreateRenderCommandBuffer ();
106135
107136 sub_command_buffer->SetLabel (" Offscreen Command Buffer" );
@@ -130,12 +159,6 @@ bool CanvasPass::Render(ContentRenderer& renderer,
130159 return false ;
131160 }
132161
133- auto offscreen_texture_contents = std::make_shared<TextureContents>();
134- offscreen_texture_contents->SetTexture (
135- subpass_target.GetRenderTargetTexture ());
136- offscreen_texture_contents->SetSourceRect (
137- IRect::MakeSize (subpass_target.GetRenderTargetTexture ()->GetSize ()));
138-
139162 Entity entity;
140163 entity.SetPath (PathBuilder{}.AddRect (subpass_coverage).CreatePath ());
141164 entity.SetContents (std::move (offscreen_texture_contents));
0 commit comments