Skip to content

Commit ab16b0b

Browse files
chinmaygardednfield
authored andcommitted
Setup canvas pass hierarchies.
1 parent 3f41788 commit ab16b0b

File tree

6 files changed

+131
-54
lines changed

6 files changed

+131
-54
lines changed

impeller/aiks/aiks_renderer.cc

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,10 @@ bool AiksRenderer::Render(const Picture& picture, RenderPass& parent_pass) {
3333
return false;
3434
}
3535

36-
for (const auto& entry : picture.entries) {
37-
if (!entry.pass.has_value()) {
38-
continue;
39-
;
40-
}
41-
42-
if (!entry.pass->Render(*content_renderer_, parent_pass)) {
43-
return false;
44-
}
36+
if (picture.pass) {
37+
return picture.pass->Render(*content_renderer_, parent_pass);
4538
}
39+
4640
return true;
4741
}
4842

impeller/aiks/canvas.cc

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,25 @@
1212
namespace impeller {
1313

1414
Canvas::Canvas() {
15-
Save(true);
15+
Initialize();
1616
}
1717

1818
Canvas::~Canvas() = default;
1919

20+
void Canvas::Initialize() {
21+
base_pass_ = std::make_unique<CanvasPass>();
22+
current_pass_ = base_pass_.get();
23+
xformation_stack_.emplace_back(CanvasStackEntry{});
24+
FML_DCHECK(GetSaveCount() == 1u);
25+
FML_DCHECK(base_pass_->GetDepth() == 1u);
26+
}
27+
28+
void Canvas::Reset() {
29+
base_pass_ = nullptr;
30+
current_pass_ = nullptr;
31+
xformation_stack_ = {};
32+
}
33+
2034
void Canvas::Save() {
2135
Save(false);
2236
}
@@ -26,6 +40,10 @@ bool Canvas::Restore() {
2640
if (xformation_stack_.size() == 1) {
2741
return false;
2842
}
43+
if (xformation_stack_.back().is_subpass) {
44+
current_pass_ = GetCurrentPass().GetSuperpass();
45+
FML_DCHECK(current_pass_);
46+
}
2947
xformation_stack_.pop_back();
3048
return true;
3149
}
@@ -69,11 +87,11 @@ void Canvas::DrawPath(Path path, Paint paint) {
6987
entity.SetStencilDepth(GetStencilDepth());
7088
entity.SetContents(paint.CreateContentsForEntity());
7189

72-
GetCurrentPass().PushEntity(std::move(entity));
90+
GetCurrentPass().AddEntity(std::move(entity));
7391
}
7492

7593
void Canvas::SaveLayer(const Paint& paint, std::optional<Rect> bounds) {
76-
Save();
94+
Save(true);
7795
}
7896

7997
void Canvas::ClipPath(Path path) {
@@ -85,23 +103,24 @@ void Canvas::ClipPath(Path path) {
85103
entity.SetContents(std::make_shared<ClipContents>());
86104
entity.SetStencilDepth(GetStencilDepth());
87105

88-
GetCurrentPass().PushEntity(std::move(entity));
106+
GetCurrentPass().AddEntity(std::move(entity));
89107
}
90108

91109
void Canvas::DrawShadow(Path path, Color color, Scalar elevation) {}
92110

93-
void Canvas::DrawPicture(const Picture& picture) {
94-
for (const auto& stack_entry : picture.entries) {
95-
auto new_stack_entry = stack_entry;
96-
if (auto pass = new_stack_entry.pass) {
97-
for (auto entity : pass->GetEntities()) {
98-
entity.IncrementStencilDepth(GetStencilDepth());
99-
entity.SetTransformation(GetCurrentTransformation() *
100-
entity.GetTransformation());
101-
}
102-
}
103-
xformation_stack_.emplace_back(std::move(new_stack_entry));
111+
void Canvas::DrawPicture(Picture picture) {
112+
if (!picture.pass) {
113+
return;
104114
}
115+
// Clone the base pass and account for the CTM updates.
116+
auto pass = picture.pass->Clone();
117+
pass->IterateAllEntities([&](auto& entity) -> bool {
118+
entity.IncrementStencilDepth(GetStencilDepth());
119+
entity.SetTransformation(GetCurrentTransformation() *
120+
entity.GetTransformation());
121+
return true;
122+
});
123+
return;
105124
}
106125

107126
void Canvas::DrawImage(std::shared_ptr<Image> image,
@@ -140,23 +159,23 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
140159
entity.SetPath(PathBuilder{}.AddRect(dest).CreatePath());
141160
entity.SetContents(contents);
142161
entity.SetTransformation(GetCurrentTransformation());
143-
GetCurrentPass().PushEntity(std::move(entity));
162+
163+
GetCurrentPass().AddEntity(std::move(entity));
144164
}
145165

146166
Picture Canvas::EndRecordingAsPicture() {
147167
Picture picture;
148-
picture.entries = std::move(xformation_stack_);
168+
picture.pass = std::move(base_pass_);
169+
170+
Reset();
171+
Initialize();
172+
149173
return picture;
150174
}
151175

152176
CanvasPass& Canvas::GetCurrentPass() {
153-
for (auto i = xformation_stack_.rbegin(), end = xformation_stack_.rend();
154-
i < end; i++) {
155-
if (i->pass.has_value()) {
156-
return i->pass.value();
157-
}
158-
}
159-
FML_UNREACHABLE();
177+
FML_DCHECK(current_pass_ != nullptr);
178+
return *current_pass_;
160179
}
161180

162181
void Canvas::IncrementStencilDepth() {
@@ -172,21 +191,15 @@ void Canvas::DrawRect(Rect rect, Paint paint) {
172191
}
173192

174193
void Canvas::Save(bool create_subpass) {
175-
// Check if called from the ctor.
176-
if (xformation_stack_.empty()) {
177-
FML_DCHECK(create_subpass) << "Base entries must have a pass.";
178-
CanvasStackEntry entry;
179-
entry.pass = CanvasPass{};
180-
xformation_stack_.emplace_back(std::move(entry));
181-
}
182-
183194
auto entry = CanvasStackEntry{};
184-
185195
entry.xformation = xformation_stack_.back().xformation;
186196
entry.stencil_depth = xformation_stack_.back().stencil_depth;
197+
entry.is_subpass = create_subpass;
198+
187199
if (create_subpass) {
188-
entry.pass = CanvasPass{};
200+
current_pass_ = GetCurrentPass().AddSubpass(std::make_unique<CanvasPass>());
189201
}
202+
190203
xformation_stack_.emplace_back(std::move(entry));
191204
}
192205

impeller/aiks/canvas.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,19 @@ class Canvas {
6464

6565
void DrawShadow(Path path, Color color, Scalar elevation);
6666

67-
void DrawPicture(const Picture& picture);
67+
void DrawPicture(Picture picture);
6868

6969
Picture EndRecordingAsPicture();
7070

7171
private:
72+
std::unique_ptr<CanvasPass> base_pass_;
73+
CanvasPass* current_pass_ = nullptr;
7274
std::deque<CanvasStackEntry> xformation_stack_;
7375

76+
void Initialize();
77+
78+
void Reset();
79+
7480
CanvasPass& GetCurrentPass();
7581

7682
void IncrementStencilDepth();

impeller/aiks/canvas_pass.cc

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,26 @@ CanvasPass::CanvasPass() = default;
1212

1313
CanvasPass::~CanvasPass() = default;
1414

15-
void CanvasPass::PushEntity(Entity entity) {
15+
void CanvasPass::AddEntity(Entity entity) {
1616
entities_.emplace_back(std::move(entity));
1717
}
1818

1919
const std::vector<Entity>& CanvasPass::GetEntities() const {
2020
return entities_;
2121
}
2222

23+
void CanvasPass::SetEntities(Entities entities) {
24+
entities_ = std::move(entities);
25+
}
26+
27+
size_t CanvasPass::GetDepth() const {
28+
size_t max_subpass_depth = 0u;
29+
for (const auto& subpass : subpasses_) {
30+
max_subpass_depth = std::max(max_subpass_depth, subpass->GetDepth());
31+
}
32+
return max_subpass_depth + 1u;
33+
}
34+
2335
Rect CanvasPass::GetCoverageRect() const {
2436
std::optional<Point> min, max;
2537
for (const auto& entity : entities_) {
@@ -43,13 +55,21 @@ Rect CanvasPass::GetCoverageRect() const {
4355
return {min->x, min->y, diff.x, diff.y};
4456
}
4557

58+
CanvasPass* CanvasPass::GetSuperpass() const {
59+
return superpass_;
60+
}
61+
4662
const CanvasPass::Subpasses& CanvasPass::GetSubpasses() const {
4763
return subpasses_;
4864
}
4965

50-
bool CanvasPass::AddSubpass(CanvasPass pass) {
51-
subpasses_.emplace_back(std::move(pass));
52-
return true;
66+
CanvasPass* CanvasPass::AddSubpass(std::unique_ptr<CanvasPass> pass) {
67+
if (!pass) {
68+
return nullptr;
69+
}
70+
FML_DCHECK(pass->superpass_ == nullptr);
71+
pass->superpass_ = this;
72+
return subpasses_.emplace_back(std::move(pass)).get();
5373
}
5474

5575
bool CanvasPass::Render(ContentRenderer& renderer,
@@ -59,7 +79,37 @@ bool CanvasPass::Render(ContentRenderer& renderer,
5979
return false;
6080
}
6181
}
82+
for (const auto& subpass : subpasses_) {
83+
if (!subpass->Render(renderer, parent_pass)) {
84+
return false;
85+
}
86+
}
6287
return true;
6388
}
6489

90+
void CanvasPass::IterateAllEntities(std::function<bool(Entity&)> iterator) {
91+
if (!iterator) {
92+
return;
93+
}
94+
95+
for (auto& entity : entities_) {
96+
if (!iterator(entity)) {
97+
return;
98+
}
99+
}
100+
101+
for (auto& subpass : subpasses_) {
102+
subpass->IterateAllEntities(iterator);
103+
}
104+
}
105+
106+
std::unique_ptr<CanvasPass> CanvasPass::Clone() const {
107+
auto pass = std::make_unique<CanvasPass>();
108+
pass->SetEntities(entities_);
109+
for (const auto& subpass : subpasses_) {
110+
pass->AddSubpass(subpass->Clone());
111+
}
112+
return pass;
113+
}
114+
65115
} // namespace impeller

impeller/aiks/canvas_pass.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,47 @@ class ContentRenderer;
1818

1919
class CanvasPass {
2020
public:
21-
using Subpasses = std::vector<CanvasPass>;
21+
using Entities = std::vector<Entity>;
22+
using Subpasses = std::vector<std::unique_ptr<CanvasPass>>;
2223

2324
CanvasPass();
2425

2526
~CanvasPass();
2627

27-
void PushEntity(Entity entity);
28+
size_t GetDepth() const;
29+
30+
std::unique_ptr<CanvasPass> Clone() const;
2831

2932
Rect GetCoverageRect() const;
3033

34+
void AddEntity(Entity entity);
35+
36+
void SetEntities(Entities entities);
37+
3138
const std::vector<Entity>& GetEntities() const;
3239

3340
const Subpasses& GetSubpasses() const;
3441

35-
bool AddSubpass(CanvasPass pass);
42+
CanvasPass* AddSubpass(std::unique_ptr<CanvasPass> pass);
43+
44+
CanvasPass* GetSuperpass() const;
3645

3746
bool Render(ContentRenderer& renderer, RenderPass& parent_pass) const;
3847

48+
void IterateAllEntities(std::function<bool(Entity&)> iterator);
49+
3950
private:
40-
std::vector<Entity> entities_;
51+
Entities entities_;
4152
Subpasses subpasses_;
53+
CanvasPass* superpass_ = nullptr;
54+
55+
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPass);
4256
};
4357

4458
struct CanvasStackEntry {
4559
Matrix xformation;
4660
size_t stencil_depth = 0u;
47-
std::optional<CanvasPass> pass;
61+
bool is_subpass = false;
4862
};
4963

5064
} // namespace impeller

impeller/aiks/picture.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace impeller {
1515

1616
struct Picture {
17-
std::deque<CanvasStackEntry> entries;
17+
std::unique_ptr<CanvasPass> pass;
1818
};
1919

2020
} // namespace impeller

0 commit comments

Comments
 (0)