diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index c4913e500a1f9..2485772e30f58 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -270,6 +270,29 @@ TEST_P(AiksTest, CanRenderDifferenceClips) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +TEST_P(AiksTest, CanRenderWithContiguousClipRestores) { + Canvas canvas; + + // Cover the whole canvas with red. + canvas.DrawPaint({.color = Color::Red()}); + + canvas.Save(); + + // Append two clips. First with empty coverage. + canvas.ClipPath( + PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath()); + canvas.ClipPath( + PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath()); + + // Restore to no clips. + canvas.Restore(); + + // Replace the whole canvas with green. + canvas.DrawPaint({.color = Color::Green()}); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, ClipsUseCurrentTransform) { std::array colors = {Color::White(), Color::Black(), Color::SkyBlue(), Color::Red(), diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index b83c8480837ac..581974069e177 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -456,11 +456,14 @@ bool EntityPass::OnRender( return true; } - FML_DCHECK(stencil_stack.size() > 1); + auto restoration_depth = + element_entity.GetStencilDepth() - stencil_depth_floor; + FML_DCHECK(restoration_depth < stencil_stack.size()); - stencil_stack.pop_back(); + auto restored_coverage = stencil_stack.back().coverage; + stencil_stack.resize(restoration_depth + 1); - if (!stencil_stack.back().coverage.has_value()) { + if (!restored_coverage.has_value()) { // Running this restore op won't make anything renderable, so skip it. return true; }