Skip to content

[Impeller] Reserve content depth in the shared backdrop fast path - #193176

Merged
auto-submit[bot] merged 2 commits into
flutter:masterfrom
ahmadwyne:fix-backdrop-group-depth
Sep 24, 2026
Merged

auto-submit[bot] merged 2 commits into
flutter:masterfrom
ahmadwyne:fix-backdrop-group-depth

Conversation

@ahmadwyne

@ahmadwyne ahmadwyne commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

The grouped backdrop fast path in Canvas::SaveLayer leaves the layer's contents with no depth budget, which trips the depth check in AddRenderEntityToCurrentPass on debug engines.

When several backdrop filters share a backdrop id and all of their filters are equal, the layer is processed once and the shared snapshot is reused. That path renders the backdrop entity with the layer's own depth (++current_depth_) and then calls Save(0), so the new stack entry's clip_depth ends up equal to the current depth. The first draw inside the layer then lands one past it:

[FATAL:flutter/impeller/display_list/canvas.cc(2473)] Check failed: current_depth_ <= transform_stack_.back().clip_depth. 135 <=? 134

This reserves total_content_depth for the contents instead, which is what the regular saveLayer path does. The backdrop entity keeps using the layer's own depth slot, and the matching Restore() pops a plain save without drawing anything, so no depth is counted twice.

Fixes #193124

Testing

Added BackdropGroupSharedSnapshotReservesContentDepth to impeller/display_list/canvas_unittests.cc. It is modelled on the neighbouring BackdropGroupIdUsesCoverageUnionForSnapshot, with the difference that each of the two grouped layers draws something inside, which is what exposes the missing depth budget.

Verified against an unoptimized host engine build (host_debug_unopt) on Windows:

  • Without the fix, the new test aborts on the check above (2 <=? 1) on both OpenGLES and Vulkan.
  • With the fix, it passes on OpenGLES, OpenGLESSDF and Vulkan.
  • *Backdrop* and *ClipDepth* pass with no failures. The remaining instances are skipped on this machine: Metal is unavailable on Windows, and the framebuffer-fetch tests only run on Vulkan, which I ran with SwiftShader and validation layers enabled.

Pre-launch Checklist

When several backdrop filters share a backdrop id and all of their filters
are equal, `Canvas::SaveLayer` reuses one shared snapshot: it renders the
backdrop entity using the layer's own depth and then calls `Save(0)`.

That left the layer's contents with no depth budget, since the new stack
entry's `clip_depth` was set to the current depth. The first draw inside the
layer then landed one past `clip_depth` and tripped the depth check in
`AddRenderEntityToCurrentPass` on debug engines:

    Check failed: current_depth_ <= transform_stack_.back().clip_depth.

Reserve `total_content_depth` for the contents instead, matching the regular
saveLayer path. The backdrop entity keeps using the layer's own depth slot,
and the matching `Restore()` pops a plain save without drawing, so no depth
is counted twice.

Fixes flutter#193124

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Canvas::SaveLayer method in Impeller to pass total_content_depth instead of 0 to the Save call when rendering a backdrop entity. It also adds a corresponding unit test, BackdropGroupSharedSnapshotReservesContentDepth, to verify that the backdrop group shared snapshot correctly reserves content depth. There are no review comments, and I have no feedback to provide.

@gaaclarke
gaaclarke self-requested a review September 22, 2026 20:18
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Sep 22, 2026
@gaaclarke gaaclarke added the CICD Run CI/CD label Sep 23, 2026

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, verified the test fails without the fix locally. Thanks!

@andywolff

Copy link
Copy Markdown
Contributor

the ci.yaml validation check failure likely just means you need a sync

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Sep 23, 2026
@gaaclarke gaaclarke added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels Sep 23, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 23, 2026
@auto-submit

auto-submit Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193176, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@gaaclarke gaaclarke added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 23, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 23, 2026
@auto-submit

auto-submit Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/193176, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@ahmadwyne

Copy link
Copy Markdown
Contributor Author

The Mac customer_testing failure looks unrelated to this change. flutter pub get failed while cloning one of the customer test repos:

git clone --mirror https://github.com/widgetbakery/headless_widgets.git
fatal: unable to access 'https://github.com/widgetbakery/headless_widgets.git/': SSL: certificate verification failed (result: 5)
exit code: 128

The other customer tests in the same run passed, and this one never got as far as running any test code. Could someone kick off a rerun of that task once the tree is green?

@gaaclarke

Copy link
Copy Markdown
Member

Could someone kick off a rerun of that task once the tree is green?

Already kicked, yea it's not something you should have to worry about. It's some sort of flake unfortunately.

@ahmadwyne

Copy link
Copy Markdown
Contributor Author

All the checks have passed on 5f57206. @gaaclarke could you re-apply autosubmit? Thanks for the reviews.

@andywolff andywolff added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 24, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Sep 24, 2026
Merged via the queue into flutter:master with commit 4ae563f Sep 24, 2026
41 of 42 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DCHECK failing on debug engines ( clip_depth assert )

3 participants