Skip to content

Commit 3a8fb57

Browse files
chinmaygardednfield
authored andcommitted
Canvas subpasses rendering into their own command buffers.
1 parent ab16b0b commit 3a8fb57

File tree

7 files changed

+86
-4
lines changed

7 files changed

+86
-4
lines changed

impeller/aiks/canvas_pass.cc

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
#include "impeller/aiks/canvas_pass.h"
66

77
#include "impeller/entity/content_renderer.h"
8+
#include "impeller/geometry/path_builder.h"
9+
#include "impeller/renderer/command_buffer.h"
10+
#include "impeller/renderer/render_pass.h"
11+
#include "impeller/renderer/render_target.h"
812

913
namespace impeller {
1014

@@ -80,10 +84,59 @@ bool CanvasPass::Render(ContentRenderer& renderer,
8084
}
8185
}
8286
for (const auto& subpass : subpasses_) {
83-
if (!subpass->Render(renderer, parent_pass)) {
87+
const auto subpass_coverage = subpass->GetCoverageRect();
88+
89+
if (subpass_coverage.IsEmpty()) {
90+
// It is not an error to have an empty subpass. But subpasses that can't
91+
// create their intermediates must trip errors.
92+
continue;
93+
}
94+
95+
auto context = renderer.GetContext();
96+
97+
auto subpass_target = RenderTarget::CreateOffscreen(
98+
*context, ISize::Ceil(subpass_coverage.size));
99+
100+
auto sub_command_buffer = context->CreateRenderCommandBuffer();
101+
102+
if (!sub_command_buffer) {
103+
return false;
104+
}
105+
106+
auto sub_renderpass = sub_command_buffer->CreateRenderPass(subpass_target);
107+
108+
if (!sub_renderpass) {
109+
return false;
110+
}
111+
112+
if (!subpass) {
113+
return false;
114+
}
115+
116+
if (!subpass->Render(renderer, *sub_renderpass)) {
117+
return false;
118+
}
119+
120+
if (!sub_renderpass->EncodeCommands(*context->GetTransientsAllocator())) {
121+
return false;
122+
}
123+
124+
sub_command_buffer->SubmitCommands();
125+
126+
auto offscreen_texture_contents = std::make_shared<TextureContents>();
127+
offscreen_texture_contents->SetTexture(
128+
subpass_target.GetRenderTargetTexture());
129+
offscreen_texture_contents->SetSourceRect(
130+
IRect::MakeSize(subpass_target.GetRenderTargetTexture()->GetSize()));
131+
132+
Entity entity;
133+
entity.SetPath(PathBuilder{}.AddRect(subpass_coverage).CreatePath());
134+
entity.SetContents(std::move(offscreen_texture_contents));
135+
if (!entity.Render(renderer, parent_pass)) {
84136
return false;
85137
}
86138
}
139+
87140
return true;
88141
}
89142

impeller/geometry/size.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ struct TSize {
7575

7676
constexpr bool IsEmpty() const { return !IsPositive(); }
7777

78+
template <class U>
79+
static constexpr TSize Ceil(const TSize<U>& other) {
80+
return TSize{static_cast<Type>(std::ceil(other.width)),
81+
static_cast<Type>(std::ceil(other.height))};
82+
}
83+
7884
constexpr size_t MipCount() const {
7985
if (!IsPositive()) {
8086
return 1u;

impeller/renderer/backend/metal/render_pass_mtl.mm

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ static bool ConfigureStencilAttachment(
6969
for (const auto& color : colors) {
7070
if (!ConfigureColorAttachment(color.second,
7171
result.colorAttachments[color.first])) {
72-
FML_LOG(ERROR) << "Could not configure color attachment at index "
73-
<< color.first;
72+
FML_DLOG(ERROR) << "Could not configure color attachment at index "
73+
<< color.first;
7474
return nil;
7575
}
7676
}
@@ -79,13 +79,15 @@ static bool ConfigureStencilAttachment(
7979

8080
if (depth.has_value() &&
8181
!ConfigureDepthAttachment(depth.value(), result.depthAttachment)) {
82+
FML_DLOG(ERROR) << "Could not configure depth attachment.";
8283
return nil;
8384
}
8485

8586
const auto& stencil = desc.GetStencilAttachment();
8687

8788
if (stencil.has_value() &&
8889
!ConfigureStencilAttachment(stencil.value(), result.stencilAttachment)) {
90+
FML_DLOG(ERROR) << "Could not configure stencil attachment.";
8991
return nil;
9092
}
9193

impeller/renderer/command_buffer.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ CommandBuffer::CommandBuffer() = default;
1010

1111
CommandBuffer::~CommandBuffer() = default;
1212

13+
void CommandBuffer::SubmitCommands() {
14+
SubmitCommands(nullptr);
15+
}
16+
1317
} // namespace impeller

impeller/renderer/command_buffer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class CommandBuffer {
5151
///
5252
virtual void SubmitCommands(CompletionCallback callback) = 0;
5353

54+
void SubmitCommands();
55+
5456
//----------------------------------------------------------------------------
5557
/// @brief Create a render pass to record render commands into.
5658
///

impeller/renderer/render_target.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ ISize RenderTarget::GetRenderTargetSize() const {
3636
return size.has_value() ? size.value() : ISize{};
3737
}
3838

39+
std::shared_ptr<Texture> RenderTarget::GetRenderTargetTexture() const {
40+
auto found = colors_.find(0u);
41+
if (found == colors_.end()) {
42+
return nullptr;
43+
}
44+
return found->second.texture;
45+
}
46+
3947
RenderTarget& RenderTarget::SetColorAttachment(ColorAttachment attachment,
4048
size_t index) {
4149
if (attachment) {
@@ -75,10 +83,15 @@ const std::optional<StencilAttachment>& RenderTarget::GetStencilAttachment()
7583
RenderTarget RenderTarget::CreateOffscreen(const Context& context,
7684
ISize size,
7785
std::string label) {
86+
if (size.IsEmpty()) {
87+
return {};
88+
}
89+
7890
TextureDescriptor color_tex0;
7991
color_tex0.format = PixelFormat::kB8G8R8A8UNormInt;
8092
color_tex0.size = size;
81-
color_tex0.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
93+
color_tex0.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget) |
94+
static_cast<uint64_t>(TextureUsage::kShaderRead);
8295

8396
TextureDescriptor stencil_tex0;
8497
stencil_tex0.format = PixelFormat::kD32FloatS8UNormInt;

impeller/renderer/render_target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class RenderTarget {
2929

3030
ISize GetRenderTargetSize() const;
3131

32+
std::shared_ptr<Texture> GetRenderTargetTexture() const;
33+
3234
std::optional<ISize> GetColorAttachmentSize(size_t index) const;
3335

3436
RenderTarget& SetColorAttachment(ColorAttachment attachment, size_t index);

0 commit comments

Comments
 (0)