Skip to content

Commit 398b74f

Browse files
chinmaygardednfield
authored andcommitted
Work towards making canvas subpasses configure postprocessing effects.
1 parent 3a8fb57 commit 398b74f

File tree

9 files changed

+90
-58
lines changed

9 files changed

+90
-58
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ TEST_F(AiksTest, CanRenderGroupOpacity) {
121121

122122
canvas.SaveLayer(alpha);
123123

124-
canvas.DrawRect({100, 100, 100, 100}, red);
125-
canvas.DrawRect({120, 120, 100, 100}, green);
126-
canvas.DrawRect({140, 140, 100, 100}, blue);
124+
canvas.DrawRect({000, 000, 100, 100}, red);
125+
// canvas.DrawRect({020, 020, 100, 100}, green);
126+
// canvas.DrawRect({040, 040, 100, 100}, blue);
127127

128128
canvas.Restore();
129129

impeller/aiks/canvas.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void Canvas::Initialize() {
2222
current_pass_ = base_pass_.get();
2323
xformation_stack_.emplace_back(CanvasStackEntry{});
2424
FML_DCHECK(GetSaveCount() == 1u);
25-
FML_DCHECK(base_pass_->GetDepth() == 1u);
25+
FML_DCHECK(base_pass_->GetSubpassesDepth() == 1u);
2626
}
2727

2828
void Canvas::Reset() {
@@ -192,14 +192,15 @@ void Canvas::DrawRect(Rect rect, Paint paint) {
192192

193193
void Canvas::Save(bool create_subpass) {
194194
auto entry = CanvasStackEntry{};
195-
entry.xformation = xformation_stack_.back().xformation;
196-
entry.stencil_depth = xformation_stack_.back().stencil_depth;
197-
entry.is_subpass = create_subpass;
198-
199195
if (create_subpass) {
196+
entry.is_subpass = true;
200197
current_pass_ = GetCurrentPass().AddSubpass(std::make_unique<CanvasPass>());
198+
current_pass_->SetTransformation(xformation_stack_.back().xformation);
199+
current_pass_->SetStencilDepth(xformation_stack_.back().stencil_depth);
200+
} else {
201+
entry.xformation = xformation_stack_.back().xformation;
202+
entry.stencil_depth = xformation_stack_.back().stencil_depth;
201203
}
202-
203204
xformation_stack_.emplace_back(std::move(entry));
204205
}
205206

impeller/aiks/canvas_pass.cc

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ void CanvasPass::SetEntities(Entities entities) {
2828
entities_ = std::move(entities);
2929
}
3030

31-
size_t CanvasPass::GetDepth() const {
31+
size_t CanvasPass::GetSubpassesDepth() const {
3232
size_t max_subpass_depth = 0u;
3333
for (const auto& subpass : subpasses_) {
34-
max_subpass_depth = std::max(max_subpass_depth, subpass->GetDepth());
34+
max_subpass_depth =
35+
std::max(max_subpass_depth, subpass->GetSubpassesDepth());
3536
}
3637
return max_subpass_depth + 1u;
3738
}
@@ -84,6 +85,10 @@ bool CanvasPass::Render(ContentRenderer& renderer,
8485
}
8586
}
8687
for (const auto& subpass : subpasses_) {
88+
if (!subpass) {
89+
return false;
90+
}
91+
8792
const auto subpass_coverage = subpass->GetCoverageRect();
8893

8994
if (subpass_coverage.IsEmpty()) {
@@ -109,9 +114,7 @@ bool CanvasPass::Render(ContentRenderer& renderer,
109114
return false;
110115
}
111116

112-
if (!subpass) {
113-
return false;
114-
}
117+
sub_renderpass->SetLabel("OffscreenPass");
115118

116119
if (!subpass->Render(renderer, *sub_renderpass)) {
117120
return false;
@@ -132,6 +135,8 @@ bool CanvasPass::Render(ContentRenderer& renderer,
132135
Entity entity;
133136
entity.SetPath(PathBuilder{}.AddRect(subpass_coverage).CreatePath());
134137
entity.SetContents(std::move(offscreen_texture_contents));
138+
entity.SetStencilDepth(stencil_depth_);
139+
entity.SetTransformation(xformation_);
135140
if (!entity.Render(renderer, parent_pass)) {
136141
return false;
137142
}
@@ -165,4 +170,12 @@ std::unique_ptr<CanvasPass> CanvasPass::Clone() const {
165170
return pass;
166171
}
167172

173+
void CanvasPass::SetTransformation(Matrix xformation) {
174+
xformation_ = std::move(xformation);
175+
}
176+
177+
void CanvasPass::SetStencilDepth(size_t stencil_depth) {
178+
stencil_depth_ = stencil_depth;
179+
}
180+
168181
} // namespace impeller

impeller/aiks/canvas_pass.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class CanvasPass {
2525

2626
~CanvasPass();
2727

28-
size_t GetDepth() const;
28+
size_t GetSubpassesDepth() const;
2929

3030
std::unique_ptr<CanvasPass> Clone() const;
3131

@@ -47,10 +47,16 @@ class CanvasPass {
4747

4848
void IterateAllEntities(std::function<bool(Entity&)> iterator);
4949

50+
void SetTransformation(Matrix xformation);
51+
52+
void SetStencilDepth(size_t stencil_depth);
53+
5054
private:
5155
Entities entities_;
5256
Subpasses subpasses_;
5357
CanvasPass* superpass_ = nullptr;
58+
Matrix xformation_;
59+
size_t stencil_depth_ = 0u;
5460

5561
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPass);
5662
};

impeller/playground/playground.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static void PlaygroundKeyCallback(GLFWwindow* window,
154154
ColorAttachment color0;
155155
color0.texture =
156156
std::make_shared<TextureMTL>(color0_tex, current_drawable.texture);
157-
color0.clear_color = Color::SkyBlue();
157+
color0.clear_color = Color::DarkSlateGray();
158158
color0.load_action = LoadAction::kClear;
159159
color0.store_action = StoreAction::kStore;
160160

impeller/renderer/backend/metal/command_buffer_mtl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class CommandBufferMTL final : public CommandBuffer {
3232
// |CommandBuffer|
3333
void SubmitCommands(CompletionCallback callback) override;
3434

35+
// |CommandBuffer|
36+
void ReserveSpotInQueue() override;
37+
3538
// |CommandBuffer|
3639
std::shared_ptr<RenderPass> CreateRenderPass(
3740
RenderTarget target) const override;

impeller/renderer/backend/metal/command_buffer_mtl.mm

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,28 @@
3535
}
3636

3737
void CommandBufferMTL::SubmitCommands(CompletionCallback callback) {
38-
if (!callback) {
39-
callback = [](auto) {};
40-
}
41-
4238
if (!buffer_) {
4339
// Already committed. This is caller error.
44-
callback(Status::kError);
40+
if (callback) {
41+
callback(Status::kError);
42+
}
4543
return;
4644
}
4745

48-
[buffer_ addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
49-
callback(ToCommitResult(buffer.status));
50-
}];
46+
if (callback) {
47+
[buffer_ addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
48+
callback(ToCommitResult(buffer.status));
49+
}];
50+
}
51+
5152
[buffer_ commit];
5253
buffer_ = nil;
5354
}
5455

56+
void CommandBufferMTL::ReserveSpotInQueue() {
57+
[buffer_ enqueue];
58+
}
59+
5560
std::shared_ptr<RenderPass> CommandBufferMTL::CreateRenderPass(
5661
RenderTarget target) const {
5762
if (!buffer_) {

impeller/renderer/backend/metal/render_pass_mtl.mm

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,23 @@ static bool ConfigureStencilAttachment(
127127
if (!IsValid()) {
128128
return false;
129129
}
130-
auto pass = [buffer_ renderCommandEncoderWithDescriptor:desc_];
130+
auto render_command_encoder =
131+
[buffer_ renderCommandEncoderWithDescriptor:desc_];
131132

132-
if (!pass) {
133+
if (!render_command_encoder) {
133134
return false;
134135
}
135136

136137
if (!label_.empty()) {
137-
[pass setLabel:@(label_.c_str())];
138+
[render_command_encoder setLabel:@(label_.c_str())];
138139
}
139140

140141
// Success or failure, the pass must end. The buffer can only process one pass
141142
// at a time.
142-
fml::ScopedCleanupClosure auto_end([pass]() { [pass endEncoding]; });
143+
fml::ScopedCleanupClosure auto_end(
144+
[render_command_encoder]() { [render_command_encoder endEncoding]; });
143145

144-
return EncodeCommands(transients_allocator, pass);
146+
return EncodeCommands(transients_allocator, render_command_encoder);
145147
}
146148

147149
//-----------------------------------------------------------------------------
@@ -154,7 +156,7 @@ static bool ConfigureStencilAttachment(
154156
/// absent.
155157
///
156158
struct PassBindingsCache {
157-
PassBindingsCache(id<MTLRenderCommandEncoder> pass) : pass_(pass) {}
159+
PassBindingsCache(id<MTLRenderCommandEncoder> encoder) : encoder_(encoder) {}
158160

159161
PassBindingsCache(const PassBindingsCache&) = delete;
160162

@@ -165,15 +167,15 @@ void SetRenderPipelineState(id<MTLRenderPipelineState> pipeline) {
165167
return;
166168
}
167169
pipeline_ = pipeline;
168-
[pass_ setRenderPipelineState:pipeline_];
170+
[encoder_ setRenderPipelineState:pipeline_];
169171
}
170172

171173
void SetDepthStencilState(id<MTLDepthStencilState> depth_stencil) {
172174
if (depth_stencil_ == depth_stencil) {
173175
return;
174176
}
175177
depth_stencil_ = depth_stencil;
176-
[pass_ setDepthStencilState:depth_stencil_];
178+
[encoder_ setDepthStencilState:depth_stencil_];
177179
}
178180

179181
bool SetBuffer(ShaderStage stage,
@@ -194,10 +196,10 @@ bool SetBuffer(ShaderStage stage,
194196

195197
switch (stage) {
196198
case ShaderStage::kVertex:
197-
[pass_ setVertexBufferOffset:offset atIndex:index];
199+
[encoder_ setVertexBufferOffset:offset atIndex:index];
198200
return true;
199201
case ShaderStage::kFragment:
200-
[pass_ setFragmentBufferOffset:offset atIndex:index];
202+
[encoder_ setFragmentBufferOffset:offset atIndex:index];
201203
return true;
202204
default:
203205
FML_DCHECK(false)
@@ -209,10 +211,10 @@ bool SetBuffer(ShaderStage stage,
209211
buffers_map[index] = {buffer, offset};
210212
switch (stage) {
211213
case ShaderStage::kVertex:
212-
[pass_ setVertexBuffer:buffer offset:offset atIndex:index];
214+
[encoder_ setVertexBuffer:buffer offset:offset atIndex:index];
213215
return true;
214216
case ShaderStage::kFragment:
215-
[pass_ setFragmentBuffer:buffer offset:offset atIndex:index];
217+
[encoder_ setFragmentBuffer:buffer offset:offset atIndex:index];
216218
return true;
217219
default:
218220
FML_DCHECK(false) << "Cannot bind buffer to unknown shader stage.";
@@ -231,10 +233,10 @@ bool SetTexture(ShaderStage stage, uint64_t index, id<MTLTexture> texture) {
231233
texture_map[index] = texture;
232234
switch (stage) {
233235
case ShaderStage::kVertex:
234-
[pass_ setVertexTexture:texture atIndex:index];
236+
[encoder_ setVertexTexture:texture atIndex:index];
235237
return true;
236238
case ShaderStage::kFragment:
237-
[pass_ setFragmentTexture:texture atIndex:index];
239+
[encoder_ setFragmentTexture:texture atIndex:index];
238240
return true;
239241
default:
240242
FML_DCHECK(false) << "Cannot bind buffer to unknown shader stage.";
@@ -255,10 +257,10 @@ bool SetSampler(ShaderStage stage,
255257
sampler_map[index] = sampler;
256258
switch (stage) {
257259
case ShaderStage::kVertex:
258-
[pass_ setVertexSamplerState:sampler atIndex:index];
260+
[encoder_ setVertexSamplerState:sampler atIndex:index];
259261
return true;
260262
case ShaderStage::kFragment:
261-
[pass_ setFragmentSamplerState:sampler atIndex:index];
263+
[encoder_ setFragmentSamplerState:sampler atIndex:index];
262264
return true;
263265
default:
264266
FML_DCHECK(false) << "Cannot bind buffer to unknown shader stage.";
@@ -276,7 +278,7 @@ bool SetSampler(ShaderStage stage,
276278
using TextureMap = std::map<uint64_t, id<MTLTexture>>;
277279
using SamplerMap = std::map<uint64_t, id<MTLSamplerState>>;
278280

279-
const id<MTLRenderCommandEncoder> pass_;
281+
const id<MTLRenderCommandEncoder> encoder_;
280282
id<MTLRenderPipelineState> pipeline_ = nullptr;
281283
id<MTLDepthStencilState> depth_stencil_ = nullptr;
282284
std::map<ShaderStage, BufferMap> buffers_;
@@ -332,8 +334,8 @@ static bool Bind(PassBindingsCache& pass,
332334
}
333335

334336
bool RenderPassMTL::EncodeCommands(Allocator& allocator,
335-
id<MTLRenderCommandEncoder> pass) const {
336-
PassBindingsCache pass_bindings(pass);
337+
id<MTLRenderCommandEncoder> encoder) const {
338+
PassBindingsCache pass_bindings(encoder);
337339
auto bind_stage_resources = [&allocator, &pass_bindings](
338340
const Bindings& bindings,
339341
ShaderStage stage) -> bool {
@@ -355,7 +357,7 @@ static bool Bind(PassBindingsCache& pass,
355357
return true;
356358
};
357359

358-
fml::closure pop_debug_marker = [pass]() { [pass popDebugGroup]; };
360+
fml::closure pop_debug_marker = [encoder]() { [encoder popDebugGroup]; };
359361
for (const auto& command : commands_) {
360362
if (command.index_count == 0u) {
361363
FML_DLOG(ERROR) << "Zero index count in render pass command.";
@@ -364,19 +366,19 @@ static bool Bind(PassBindingsCache& pass,
364366

365367
fml::ScopedCleanupClosure auto_pop_debug_marker(pop_debug_marker);
366368
if (!command.label.empty()) {
367-
[pass pushDebugGroup:@(command.label.c_str())];
369+
[encoder pushDebugGroup:@(command.label.c_str())];
368370
} else {
369371
auto_pop_debug_marker.Release();
370372
}
371373
pass_bindings.SetRenderPipelineState(
372374
PipelineMTL::Cast(*command.pipeline).GetMTLRenderPipelineState());
373375
pass_bindings.SetDepthStencilState(
374376
PipelineMTL::Cast(*command.pipeline).GetMTLDepthStencilState());
375-
[pass setFrontFacingWinding:command.winding == WindingOrder::kClockwise
376-
? MTLWindingClockwise
377-
: MTLWindingCounterClockwise];
378-
[pass setCullMode:MTLCullModeNone];
379-
[pass setStencilReferenceValue:command.stencil_reference];
377+
[encoder setFrontFacingWinding:command.winding == WindingOrder::kClockwise
378+
? MTLWindingClockwise
379+
: MTLWindingCounterClockwise];
380+
[encoder setCullMode:MTLCullModeNone];
381+
[encoder setStencilReferenceValue:command.stencil_reference];
380382
if (!bind_stage_resources(command.vertex_bindings, ShaderStage::kVertex)) {
381383
return false;
382384
}
@@ -400,14 +402,14 @@ static bool Bind(PassBindingsCache& pass,
400402
FML_DCHECK(command.index_count * sizeof(uint32_t) ==
401403
command.index_buffer.range.length);
402404
// Returns void. All error checking must be done by this point.
403-
[pass drawIndexedPrimitives:ToMTLPrimitiveType(command.primitive_type)
404-
indexCount:command.index_count
405-
indexType:MTLIndexTypeUInt32
406-
indexBuffer:mtl_index_buffer
407-
indexBufferOffset:command.index_buffer.range.offset
408-
instanceCount:1u
409-
baseVertex:0u
410-
baseInstance:0u];
405+
[encoder drawIndexedPrimitives:ToMTLPrimitiveType(command.primitive_type)
406+
indexCount:command.index_count
407+
indexType:MTLIndexTypeUInt32
408+
indexBuffer:mtl_index_buffer
409+
indexBufferOffset:command.index_buffer.range.offset
410+
instanceCount:1u
411+
baseVertex:0u
412+
baseInstance:0u];
411413
}
412414
return true;
413415
}

impeller/renderer/command_buffer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class CommandBuffer {
5353

5454
void SubmitCommands();
5555

56+
virtual void ReserveSpotInQueue() = 0;
57+
5658
//----------------------------------------------------------------------------
5759
/// @brief Create a render pass to record render commands into.
5860
///

0 commit comments

Comments
 (0)