@@ -117,6 +117,7 @@ Canvas::~Canvas() = default;
117117void Canvas::Initialize (std::optional<Rect> cull_rect) {
118118 initial_cull_rect_ = cull_rect;
119119 base_pass_ = std::make_unique<EntityPass>();
120+ base_pass_->SetNewClipDepth (++current_depth_);
120121 current_pass_ = base_pass_.get ();
121122 transform_stack_.emplace_back (CanvasStackEntry{.cull_rect = cull_rect});
122123 FML_DCHECK (GetSaveCount () == 1u );
@@ -126,6 +127,7 @@ void Canvas::Initialize(std::optional<Rect> cull_rect) {
126127void Canvas::Reset () {
127128 base_pass_ = nullptr ;
128129 current_pass_ = nullptr ;
130+ current_depth_ = 0u ;
129131 transform_stack_ = {};
130132}
131133
@@ -174,6 +176,7 @@ void Canvas::Save(bool create_subpass,
174176 if (create_subpass) {
175177 entry.rendering_mode = Entity::RenderingMode::kSubpass ;
176178 auto subpass = std::make_unique<EntityPass>();
179+ subpass->SetNewClipDepth (++current_depth_);
177180 subpass->SetEnableOffscreenCheckerboard (
178181 debug_options.offscreen_texture_checkerboard );
179182 if (backdrop_filter) {
@@ -206,16 +209,16 @@ bool Canvas::Restore() {
206209 if (transform_stack_.size () == 1 ) {
207210 return false ;
208211 }
212+ size_t num_clips = transform_stack_.back ().num_clips ;
209213 if (transform_stack_.back ().rendering_mode ==
210214 Entity::RenderingMode::kSubpass ) {
215+ current_pass_->PopClips (num_clips, current_depth_);
211216 current_pass_ = GetCurrentPass ().GetSuperpass ();
212217 FML_DCHECK (current_pass_);
213218 }
214219
215- bool contains_clips = transform_stack_.back ().contains_clips ;
216220 transform_stack_.pop_back ();
217-
218- if (contains_clips) {
221+ if (num_clips > 0 ) {
219222 RestoreClip ();
220223 }
221224
@@ -290,7 +293,7 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) {
290293 entity.SetBlendMode (paint.blend_mode );
291294 entity.SetContents (CreatePathContentsWithFilters (paint, path));
292295
293- GetCurrentPass (). AddEntity (std::move (entity));
296+ AddEntityToCurrentPass (std::move (entity));
294297}
295298
296299void Canvas::DrawPaint (const Paint& paint) {
@@ -300,7 +303,7 @@ void Canvas::DrawPaint(const Paint& paint) {
300303 entity.SetBlendMode (paint.blend_mode );
301304 entity.SetContents (CreateCoverContentsWithFilters (paint));
302305
303- GetCurrentPass (). AddEntity (std::move (entity));
306+ AddEntityToCurrentPass (std::move (entity));
304307}
305308
306309bool Canvas::AttemptDrawBlurredRRect (const Rect& rect,
@@ -338,7 +341,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
338341 entity.SetBlendMode (new_paint.blend_mode );
339342 entity.SetContents (new_paint.WithFilters (std::move (contents)));
340343
341- GetCurrentPass (). AddEntity (std::move (entity));
344+ AddEntityToCurrentPass (std::move (entity));
342345
343346 return true ;
344347}
@@ -351,7 +354,7 @@ void Canvas::DrawLine(const Point& p0, const Point& p1, const Paint& paint) {
351354 entity.SetContents (CreateContentsForGeometryWithFilters (
352355 paint, Geometry::MakeLine (p0, p1, paint.stroke_width , paint.stroke_cap )));
353356
354- GetCurrentPass (). AddEntity (std::move (entity));
357+ AddEntityToCurrentPass (std::move (entity));
355358}
356359
357360void Canvas::DrawRect (const Rect& rect, const Paint& paint) {
@@ -371,7 +374,7 @@ void Canvas::DrawRect(const Rect& rect, const Paint& paint) {
371374 entity.SetContents (
372375 CreateContentsForGeometryWithFilters (paint, Geometry::MakeRect (rect)));
373376
374- GetCurrentPass (). AddEntity (std::move (entity));
377+ AddEntityToCurrentPass (std::move (entity));
375378}
376379
377380void Canvas::DrawOval (const Rect& rect, const Paint& paint) {
@@ -398,7 +401,7 @@ void Canvas::DrawOval(const Rect& rect, const Paint& paint) {
398401 entity.SetContents (
399402 CreateContentsForGeometryWithFilters (paint, Geometry::MakeOval (rect)));
400403
401- GetCurrentPass (). AddEntity (std::move (entity));
404+ AddEntityToCurrentPass (std::move (entity));
402405}
403406
404407void Canvas::DrawRRect (const Rect& rect,
@@ -416,7 +419,7 @@ void Canvas::DrawRRect(const Rect& rect,
416419 entity.SetContents (CreateContentsForGeometryWithFilters (
417420 paint, Geometry::MakeRoundRect (rect, corner_radii)));
418421
419- GetCurrentPass (). AddEntity (std::move (entity));
422+ AddEntityToCurrentPass (std::move (entity));
420423 return ;
421424 }
422425
@@ -449,7 +452,7 @@ void Canvas::DrawCircle(const Point& center,
449452 entity.SetContents (
450453 CreateContentsForGeometryWithFilters (paint, std::move (geometry)));
451454
452- GetCurrentPass (). AddEntity (std::move (entity));
455+ AddEntityToCurrentPass (std::move (entity));
453456}
454457
455458void Canvas::ClipPath (const Path& path, Entity::ClipOperation clip_op) {
@@ -554,10 +557,10 @@ void Canvas::ClipGeometry(const std::shared_ptr<Geometry>& geometry,
554557 entity.SetContents (std::move (contents));
555558 entity.SetClipDepth (GetClipDepth ());
556559
557- GetCurrentPass ().AddEntity (std::move (entity));
560+ GetCurrentPass ().PushClip (std::move (entity));
558561
559562 ++transform_stack_.back ().clip_depth ;
560- transform_stack_.back ().contains_clips = true ;
563+ ++ transform_stack_.back ().num_clips ;
561564}
562565
563566void Canvas::IntersectCulling (Rect clip_rect) {
@@ -593,7 +596,8 @@ void Canvas::RestoreClip() {
593596 entity.SetContents (std::make_shared<ClipRestoreContents>());
594597 entity.SetClipDepth (GetClipDepth ());
595598
596- GetCurrentPass ().AddEntity (std::move (entity));
599+ // TODO(bdero): To be removed when swapping the clip strategy.
600+ AddEntityToCurrentPass (std::move (entity));
597601}
598602
599603void Canvas::DrawPoints (std::vector<Point> points,
@@ -613,7 +617,7 @@ void Canvas::DrawPoints(std::vector<Point> points,
613617 Geometry::MakePointField (std::move (points), radius,
614618 /* round=*/ point_style == PointStyle::kRound )));
615619
616- GetCurrentPass (). AddEntity (std::move (entity));
620+ AddEntityToCurrentPass (std::move (entity));
617621}
618622
619623void Canvas::DrawPicture (const Picture& picture) {
@@ -690,10 +694,16 @@ void Canvas::DrawImageRect(const std::shared_ptr<Image>& image,
690694 entity.SetContents (paint.WithFilters (contents));
691695 entity.SetTransform (GetCurrentTransform ());
692696
693- GetCurrentPass (). AddEntity (std::move (entity));
697+ AddEntityToCurrentPass (std::move (entity));
694698}
695699
696700Picture Canvas::EndRecordingAsPicture () {
701+ // Assign clip depths to any outstanding clip entities.
702+ while (current_pass_ != nullptr ) {
703+ current_pass_->PopAllClips (current_depth_);
704+ current_pass_ = current_pass_->GetSuperpass ();
705+ }
706+
697707 Picture picture;
698708 picture.pass = std::move (base_pass_);
699709
@@ -712,6 +722,11 @@ size_t Canvas::GetClipDepth() const {
712722 return transform_stack_.back ().clip_depth ;
713723}
714724
725+ void Canvas::AddEntityToCurrentPass (Entity entity) {
726+ entity.SetNewClipDepth (++current_depth_);
727+ GetCurrentPass ().AddEntity (std::move (entity));
728+ }
729+
715730void Canvas::SaveLayer (const Paint& paint,
716731 std::optional<Rect> bounds,
717732 const std::shared_ptr<ImageFilter>& backdrop_filter) {
@@ -768,7 +783,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
768783 entity.SetContents (
769784 paint.WithFilters (paint.WithMaskBlur (std::move (text_contents), true )));
770785
771- GetCurrentPass (). AddEntity (std::move (entity));
786+ AddEntityToCurrentPass (std::move (entity));
772787}
773788
774789static bool UseColorSourceContents (
@@ -807,7 +822,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
807822 // are vertex coordinates then only if the contents are an image.
808823 if (UseColorSourceContents (vertices, paint)) {
809824 entity.SetContents (CreateContentsForGeometryWithFilters (paint, vertices));
810- GetCurrentPass (). AddEntity (std::move (entity));
825+ AddEntityToCurrentPass (std::move (entity));
811826 return ;
812827 }
813828
@@ -845,7 +860,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
845860 contents->SetSourceContents (std::move (src_contents));
846861 entity.SetContents (paint.WithFilters (std::move (contents)));
847862
848- GetCurrentPass (). AddEntity (std::move (entity));
863+ AddEntityToCurrentPass (std::move (entity));
849864}
850865
851866void Canvas::DrawAtlas (const std::shared_ptr<Image>& atlas,
@@ -876,7 +891,7 @@ void Canvas::DrawAtlas(const std::shared_ptr<Image>& atlas,
876891 entity.SetBlendMode (paint.blend_mode );
877892 entity.SetContents (paint.WithFilters (contents));
878893
879- GetCurrentPass (). AddEntity (std::move (entity));
894+ AddEntityToCurrentPass (std::move (entity));
880895}
881896
882897} // namespace impeller
0 commit comments