Open Bug 2065180 Opened 9 days ago Updated 9 days ago

Assertion failure: asr == nullptr painting a top-layer popover anchored inside a position: sticky subtree

Categories

(Core :: Layout: Positioned, defect)

defect

Tracking

()

People

(Reporter: dao, Unassigned)

References

Details

(Keywords: assertion, testcase)

Attachments

(1 file)

Painting a top-layer popover that is anchor-positioned to an element inside a position: sticky subtree hits

Assertion failure: asr == nullptr, at layout/generic/nsIFrame.cpp:4595

and takes the content process with it, via ViewportFrame::BuildDisplayListForContentTopLayer -> BuildDisplayListForTopLayerFrame -> nsIFrame::BuildDisplayListForChild. Debug only; release builds paint the popover correctly.

Steps to reproduce

Load the attached minimal.html in a debug build on a real widget backend. Headless never reproduces it, having no APZ:

xvfb-run -a -s "-screen 0 1600x1200x24" env -u WAYLAND_DISPLAY MOZ_ENABLE_WAYLAND=0 \
  GDK_BACKEND=x11 XPCOM_DEBUG_BREAK=abort \
  ./mach run --temp-profile /path/to/minimal.html

That is the whole test case, minus a script that calls showPopover():

<div style="position:sticky">
  <div style="anchor-name:--a">
    <div popover style="position:absolute;height:110px;inline-size:1268px;
                        position-anchor:--a;position-area:span-block-end">
      <span style="position:absolute;height:12px;inline-size:12px"></span>
    </div>
  </div>
</div>

It asserts on 3 runs out of 3.

Ingredients

Reduced from an about:newtab page by delta debugging. Each item below was verified by removing it and confirming the page still runs and still opens the popover, but no longer asserts.

  • position: sticky on an ancestor of the anchor. Static or relative is clean, and so is moving the anchor out of the sticky subtree. The sticky element does not have to be stuck, and the page does not have to be scrollable.
  • anchor-name plus position-anchor, and position-area.
  • The popover attribute. The same shape outside the top layer is clean.
  • position: absolute on the popover. Without it the popover is fixed and hits a different, intermittent assertion instead, PresContext()->Document()->GetActiveViewTransition() a few lines below.
  • A non-trivial height and inline-size on the popover.
  • An absolutely-positioned descendant inside the popover. Making that child position: relative is clean.

Guess at the cause

Offered as a hypothesis from reading the code, not something I confirmed in a debugger. The assertion sits on the branch that handles a mismatch between savedOutOfFlowData->mContainingBlockActiveScrolledRoot and DisplayPortUtils::GetASRAncestorFrame(child->GetParent()), and the asserts on that branch encode the assumption that such a mismatch can only be the view-transition native-anonymous-content case from bug 2002160. Anchor positioning looks like a second way to reach a legitimate mismatch: GetASRAncestorFrame follows the anchor chain through AnchorPositioningUtils::GetAnchorThatFrameScrollsWith, so an anchored out-of-flow takes its ASR from its anchor rather than from its parent. That would also account for the absolutely-positioned descendant being required, it being the child whose containing block is the anchored popover.

No CSS-only mitigation found

All of these still assert: anchor-name on the sticky element itself rather than on a descendant of it; contain: paint, contain: layout, will-change: transform, anchor-scope or inset-block-start: 0 on the sticky element; contain: layout, contain: paint, overflow: hidden or transform: translateZ(0) on the popover; and wrapping the popover's absolutely-positioned child in a position: relative div.

How this was hit

Putting the address bar on about:newtab (bug 2062215) anchors its results view to the search input, which sits inside newtab's sticky search wrapper. That fails browser/components/urlbar/tests/browser/browser_newtab_result_icon.js on every debug platform, so the patch cannot land with the CSS-only anchoring.

Build: local debug build of autoland f9a2ea974170 plus front-end-only patches that this file:// test case does not load.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: