8
8
#include " impeller/geometry/path_builder.h"
9
9
#include " impeller/renderer/command_buffer.h"
10
10
#include " impeller/renderer/render_pass.h"
11
- #include " impeller/renderer/render_target.h"
12
11
13
12
namespace impeller {
14
13
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
+ }
16
20
17
21
CanvasPass::~CanvasPass () = default ;
18
22
@@ -85,8 +89,12 @@ bool CanvasPass::Render(ContentRenderer& renderer,
85
89
}
86
90
}
87
91
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 ;
90
98
}
91
99
92
100
const auto subpass_coverage = subpass->GetCoverageRect ();
@@ -102,6 +110,27 @@ bool CanvasPass::Render(ContentRenderer& renderer,
102
110
auto subpass_target = RenderTarget::CreateOffscreen (
103
111
*context, ISize::Ceil (subpass_coverage.size ));
104
112
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
+
105
134
auto sub_command_buffer = context->CreateRenderCommandBuffer ();
106
135
107
136
sub_command_buffer->SetLabel (" Offscreen Command Buffer" );
@@ -130,12 +159,6 @@ bool CanvasPass::Render(ContentRenderer& renderer,
130
159
return false ;
131
160
}
132
161
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
-
139
162
Entity entity;
140
163
entity.SetPath (PathBuilder{}.AddRect (subpass_coverage).CreatePath ());
141
164
entity.SetContents (std::move (offscreen_texture_contents));
0 commit comments