Skip to content

Commit 18f8e72

Browse files
chinmaygardednfield
authored andcommitted
Setup a framework to collapse passes.
1 parent f9a6a2c commit 18f8e72

File tree

6 files changed

+110
-15
lines changed

6 files changed

+110
-15
lines changed

impeller/aiks/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ impeller_component("aiks") {
1212
"canvas.h",
1313
"canvas_pass.cc",
1414
"canvas_pass.h",
15+
"canvas_pass_delegate.cc",
16+
"canvas_pass_delegate.h",
1517
"image.cc",
1618
"image.h",
1719
"paint.cc",

impeller/aiks/aiks_unittests.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,16 @@ TEST_F(AiksTest, CanRenderGroupOpacity) {
110110
Canvas canvas;
111111

112112
Paint red;
113-
red.color = Color::Red(); //.WithAlpha(0.5);
113+
red.color = Color::Red();
114114
Paint green;
115-
green.color = Color::Green(); //.WithAlpha(0.5);
115+
green.color = Color::Green();
116116
Paint blue;
117-
blue.color = Color::Blue(); //.WithAlpha(0.5);
117+
blue.color = Color::Blue();
118118

119119
Paint alpha;
120120
alpha.color = Color::Red().WithAlpha(0.5);
121121

122-
// canvas.SaveLayer(alpha);
122+
canvas.SaveLayer(alpha);
123123

124124
canvas.DrawRect({000, 000, 100, 100}, red);
125125
canvas.DrawRect({020, 020, 100, 100}, green);

impeller/aiks/canvas_pass.cc

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
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

1312
namespace 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

1721
CanvasPass::~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));

impeller/aiks/canvas_pass.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
#include <vector>
1010

1111
#include "flutter/fml/macros.h"
12+
#include "impeller/aiks/canvas_pass_delegate.h"
1213
#include "impeller/entity/contents.h"
1314
#include "impeller/entity/entity.h"
15+
#include "impeller/renderer/render_target.h"
1416

1517
namespace impeller {
1618

@@ -21,7 +23,7 @@ class CanvasPass {
2123
using Entities = std::vector<Entity>;
2224
using Subpasses = std::vector<std::unique_ptr<CanvasPass>>;
2325

24-
CanvasPass();
26+
CanvasPass(std::unique_ptr<CanvasPassDelegate> delegate = nullptr);
2527

2628
~CanvasPass();
2729

@@ -57,6 +59,7 @@ class CanvasPass {
5759
CanvasPass* superpass_ = nullptr;
5860
Matrix xformation_;
5961
size_t stencil_depth_ = 0u;
62+
std::unique_ptr<CanvasPassDelegate> delegate_;
6063

6164
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPass);
6265
};

impeller/aiks/canvas_pass_delegate.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
5+
#include "impeller/aiks/canvas_pass_delegate.h"
6+
7+
namespace impeller {
8+
9+
CanvasPassDelegate::CanvasPassDelegate() = default;
10+
11+
CanvasPassDelegate::~CanvasPassDelegate() = default;
12+
13+
class DefaultCanvasPassDelegate final : public CanvasPassDelegate {
14+
public:
15+
DefaultCanvasPassDelegate() = default;
16+
17+
~DefaultCanvasPassDelegate() override = default;
18+
19+
bool CanCollapseIntoParentPass() override { return true; }
20+
21+
std::shared_ptr<Contents> CreateContentsForSubpassTarget(
22+
const Texture& target) override {
23+
// Not possible since this pass always collapses into its parent.
24+
FML_UNREACHABLE();
25+
}
26+
27+
private:
28+
FML_DISALLOW_COPY_AND_ASSIGN(DefaultCanvasPassDelegate);
29+
};
30+
31+
std::unique_ptr<CanvasPassDelegate> CanvasPassDelegate::MakeDefault() {
32+
return std::make_unique<DefaultCanvasPassDelegate>();
33+
}
34+
35+
} // namespace impeller

impeller/aiks/canvas_pass_delegate.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
5+
#pragma once
6+
7+
#include <memory>
8+
9+
#include "flutter/fml/macros.h"
10+
#include "impeller/entity/contents.h"
11+
#include "impeller/renderer/texture.h"
12+
13+
namespace impeller {
14+
15+
class CanvasPassDelegate {
16+
public:
17+
static std::unique_ptr<CanvasPassDelegate> MakeDefault();
18+
19+
CanvasPassDelegate();
20+
21+
virtual ~CanvasPassDelegate();
22+
23+
virtual bool CanCollapseIntoParentPass() = 0;
24+
25+
virtual std::shared_ptr<Contents> CreateContentsForSubpassTarget(
26+
const Texture& target) = 0;
27+
28+
private:
29+
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPassDelegate);
30+
};
31+
32+
} // namespace impeller

0 commit comments

Comments
 (0)