12
12
namespace impeller {
13
13
14
14
Canvas::Canvas () {
15
- Save ( true );
15
+ Initialize ( );
16
16
}
17
17
18
18
Canvas::~Canvas () = default ;
19
19
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
+
20
34
void Canvas::Save () {
21
35
Save (false );
22
36
}
@@ -26,6 +40,10 @@ bool Canvas::Restore() {
26
40
if (xformation_stack_.size () == 1 ) {
27
41
return false ;
28
42
}
43
+ if (xformation_stack_.back ().is_subpass ) {
44
+ current_pass_ = GetCurrentPass ().GetSuperpass ();
45
+ FML_DCHECK (current_pass_);
46
+ }
29
47
xformation_stack_.pop_back ();
30
48
return true ;
31
49
}
@@ -69,11 +87,11 @@ void Canvas::DrawPath(Path path, Paint paint) {
69
87
entity.SetStencilDepth (GetStencilDepth ());
70
88
entity.SetContents (paint.CreateContentsForEntity ());
71
89
72
- GetCurrentPass ().PushEntity (std::move (entity));
90
+ GetCurrentPass ().AddEntity (std::move (entity));
73
91
}
74
92
75
93
void Canvas::SaveLayer (const Paint& paint, std::optional<Rect> bounds) {
76
- Save ();
94
+ Save (true );
77
95
}
78
96
79
97
void Canvas::ClipPath (Path path) {
@@ -85,23 +103,24 @@ void Canvas::ClipPath(Path path) {
85
103
entity.SetContents (std::make_shared<ClipContents>());
86
104
entity.SetStencilDepth (GetStencilDepth ());
87
105
88
- GetCurrentPass ().PushEntity (std::move (entity));
106
+ GetCurrentPass ().AddEntity (std::move (entity));
89
107
}
90
108
91
109
void Canvas::DrawShadow (Path path, Color color, Scalar elevation) {}
92
110
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 ;
104
114
}
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 ;
105
124
}
106
125
107
126
void Canvas::DrawImage (std::shared_ptr<Image> image,
@@ -140,23 +159,23 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
140
159
entity.SetPath (PathBuilder{}.AddRect (dest).CreatePath ());
141
160
entity.SetContents (contents);
142
161
entity.SetTransformation (GetCurrentTransformation ());
143
- GetCurrentPass ().PushEntity (std::move (entity));
162
+
163
+ GetCurrentPass ().AddEntity (std::move (entity));
144
164
}
145
165
146
166
Picture Canvas::EndRecordingAsPicture () {
147
167
Picture picture;
148
- picture.entries = std::move (xformation_stack_);
168
+ picture.pass = std::move (base_pass_);
169
+
170
+ Reset ();
171
+ Initialize ();
172
+
149
173
return picture;
150
174
}
151
175
152
176
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_;
160
179
}
161
180
162
181
void Canvas::IncrementStencilDepth () {
@@ -172,21 +191,15 @@ void Canvas::DrawRect(Rect rect, Paint paint) {
172
191
}
173
192
174
193
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
-
183
194
auto entry = CanvasStackEntry{};
184
-
185
195
entry.xformation = xformation_stack_.back ().xformation ;
186
196
entry.stencil_depth = xformation_stack_.back ().stencil_depth ;
197
+ entry.is_subpass = create_subpass;
198
+
187
199
if (create_subpass) {
188
- entry. pass = CanvasPass{} ;
200
+ current_pass_ = GetCurrentPass (). AddSubpass (std::make_unique< CanvasPass>()) ;
189
201
}
202
+
190
203
xformation_stack_.emplace_back (std::move (entry));
191
204
}
192
205
0 commit comments