12
12
namespace impeller {
13
13
14
14
Canvas::Canvas () {
15
- xformation_stack_.push ({});
16
- passes_.emplace_back (CanvasPass{});
15
+ Save (true );
17
16
}
18
17
19
18
Canvas::~Canvas () = default ;
20
19
21
20
void Canvas::Save () {
22
- FML_DCHECK (xformation_stack_.size () > 0 );
23
- xformation_stack_.push (xformation_stack_.top ());
21
+ Save (false );
24
22
}
25
23
26
24
bool Canvas::Restore () {
27
25
FML_DCHECK (xformation_stack_.size () > 0 );
28
26
if (xformation_stack_.size () == 1 ) {
29
27
return false ;
30
28
}
31
- xformation_stack_.pop ();
29
+ xformation_stack_.pop_back ();
32
30
return true ;
33
31
}
34
32
35
33
void Canvas::Concat (const Matrix& xformation) {
36
- const auto current_xformation = xformation_stack_.top ().xformation ;
37
- xformation_stack_.top ().xformation = xformation * current_xformation;
34
+ xformation_stack_.back ().xformation = xformation * GetCurrentTransformation ();
38
35
}
39
36
40
37
const Matrix& Canvas::GetCurrentTransformation () const {
41
- return xformation_stack_.top ().xformation ;
38
+ return xformation_stack_.back ().xformation ;
42
39
}
43
40
44
41
void Canvas::Translate (const Vector3& offset) {
@@ -71,6 +68,7 @@ void Canvas::DrawPath(Path path, Paint paint) {
71
68
entity.SetPath (std::move (path));
72
69
entity.SetStencilDepth (GetStencilDepth ());
73
70
entity.SetContents (paint.CreateContentsForEntity ());
71
+
74
72
GetCurrentPass ().PushEntity (std::move (entity));
75
73
}
76
74
@@ -86,21 +84,23 @@ void Canvas::ClipPath(Path path) {
86
84
entity.SetPath (std::move (path));
87
85
entity.SetContents (std::make_shared<ClipContents>());
88
86
entity.SetStencilDepth (GetStencilDepth ());
87
+
89
88
GetCurrentPass ().PushEntity (std::move (entity));
90
89
}
91
90
92
91
void Canvas::DrawShadow (Path path, Color color, Scalar elevation) {}
93
92
94
93
void Canvas::DrawPicture (const Picture& picture) {
95
- for (const auto & pass : picture.passes ) {
96
- CanvasPass new_pass;
97
- for (const auto & entity : pass.GetPassEntities ()) {
98
- auto new_entity = entity;
99
- new_entity.SetTransformation (GetCurrentTransformation () *
100
- entity.GetTransformation ());
101
- new_pass.PushEntity (std::move (new_entity));
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->GetPassEntities ()) {
98
+ entity.IncrementStencilDepth (GetStencilDepth ());
99
+ entity.SetTransformation (GetCurrentTransformation () *
100
+ entity.GetTransformation ());
101
+ }
102
102
}
103
- passes_ .emplace_back (std::move (new_pass ));
103
+ xformation_stack_ .emplace_back (std::move (new_stack_entry ));
104
104
}
105
105
}
106
106
@@ -145,21 +145,49 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
145
145
146
146
Picture Canvas::EndRecordingAsPicture () {
147
147
Picture picture;
148
- picture.passes = std::move (passes_ );
148
+ picture.entries = std::move (xformation_stack_ );
149
149
return picture;
150
150
}
151
151
152
152
CanvasPass& Canvas::GetCurrentPass () {
153
- FML_DCHECK (!passes_.empty ());
154
- return passes_.back ();
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 ();
155
160
}
156
161
157
162
void Canvas::IncrementStencilDepth () {
158
- ++xformation_stack_.top ().stencil_depth ;
163
+ ++xformation_stack_.back ().stencil_depth ;
159
164
}
160
165
161
166
size_t Canvas::GetStencilDepth () const {
162
- return xformation_stack_.top ().stencil_depth ;
167
+ return xformation_stack_.back ().stencil_depth ;
168
+ }
169
+
170
+ void Canvas::DrawRect (Rect rect, Paint paint) {
171
+ DrawPath (PathBuilder{}.AddRect (rect).CreatePath (), std::move (paint));
172
+ }
173
+
174
+ 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
+ auto entry = CanvasStackEntry{};
184
+
185
+ entry.xformation = xformation_stack_.back ().xformation ;
186
+ entry.stencil_depth = xformation_stack_.back ().stencil_depth ;
187
+ if (create_subpass) {
188
+ entry.pass = CanvasPass{};
189
+ }
190
+ xformation_stack_.emplace_back (std::move (entry));
163
191
}
164
192
165
193
} // namespace impeller
0 commit comments