1212namespace impeller {
1313
1414Canvas::Canvas () {
15- xformation_stack_.push ({});
16- passes_.emplace_back (CanvasPass{});
15+ Save (true );
1716}
1817
1918Canvas::~Canvas () = default ;
2019
2120void Canvas::Save () {
22- FML_DCHECK (xformation_stack_.size () > 0 );
23- xformation_stack_.push (xformation_stack_.top ());
21+ Save (false );
2422}
2523
2624bool Canvas::Restore () {
2725 FML_DCHECK (xformation_stack_.size () > 0 );
2826 if (xformation_stack_.size () == 1 ) {
2927 return false ;
3028 }
31- xformation_stack_.pop ();
29+ xformation_stack_.pop_back ();
3230 return true ;
3331}
3432
3533void 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 ();
3835}
3936
4037const Matrix& Canvas::GetCurrentTransformation () const {
41- return xformation_stack_.top ().xformation ;
38+ return xformation_stack_.back ().xformation ;
4239}
4340
4441void Canvas::Translate (const Vector3& offset) {
@@ -71,6 +68,7 @@ void Canvas::DrawPath(Path path, Paint paint) {
7168 entity.SetPath (std::move (path));
7269 entity.SetStencilDepth (GetStencilDepth ());
7370 entity.SetContents (paint.CreateContentsForEntity ());
71+
7472 GetCurrentPass ().PushEntity (std::move (entity));
7573}
7674
@@ -86,21 +84,23 @@ void Canvas::ClipPath(Path path) {
8684 entity.SetPath (std::move (path));
8785 entity.SetContents (std::make_shared<ClipContents>());
8886 entity.SetStencilDepth (GetStencilDepth ());
87+
8988 GetCurrentPass ().PushEntity (std::move (entity));
9089}
9190
9291void Canvas::DrawShadow (Path path, Color color, Scalar elevation) {}
9392
9493void 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+ }
102102 }
103- passes_ .emplace_back (std::move (new_pass ));
103+ xformation_stack_ .emplace_back (std::move (new_stack_entry ));
104104 }
105105}
106106
@@ -145,21 +145,49 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
145145
146146Picture Canvas::EndRecordingAsPicture () {
147147 Picture picture;
148- picture.passes = std::move (passes_ );
148+ picture.entries = std::move (xformation_stack_ );
149149 return picture;
150150}
151151
152152CanvasPass& 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 ();
155160}
156161
157162void Canvas::IncrementStencilDepth () {
158- ++xformation_stack_.top ().stencil_depth ;
163+ ++xformation_stack_.back ().stencil_depth ;
159164}
160165
161166size_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));
163191}
164192
165193} // namespace impeller
0 commit comments