[Impeller] Fix back-to-back clip restoration (flutter/engine#38964)

This commit is contained in:
Brandon DeRosier 2023-01-17 18:55:22 -08:00 committed by GitHub
parent 08bfbfebc9
commit ae581a94ac
2 changed files with 29 additions and 3 deletions

View File

@ -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<Color, 5> colors = {Color::White(), Color::Black(),
Color::SkyBlue(), Color::Red(),

View File

@ -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;
}