Closed Bug 1409582 Opened 7 years ago Closed 7 years ago

ASSERTION: Bounds computation mismatch in Headless mode on MacOS

Categories

(Core :: Web Painting, defect)

Unspecified
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: bdahl, Unassigned)

References

Details

When running a plain mochitest in headless mode on MacOS in a debug build:

MOZ_HEADLESS=1 ./mach test test_child.html --keep-open=false --setpref="dom.ipc.processCount=1"

I see the following assertion:

[Parent 610, Main Thread] ###!!! ASSERTION: Bounds computation mismatch: 'mContainerBounds.IsEqualInterior(mAccumulatedChildBounds)', file /builds/worker/workspace/build/src/layout/painting/FrameLayerBuilder.cpp, line 5295

I did a bisect and it came up with bug 1402368 (https://hg.mozilla.org/mozilla-central/log?rev=747cfc86a8cccb5a80fb224a9d15c017fd3c4937)

Also, the assertion doesn't happen with non-e10s.
I haven’t had too much luck with his bug. The element that fails the assertion is an nsTextControlFrame, which makes sense with the above change that caused the regression.

In headless mode I see:
mContainerBounds        [x = 18120, y = 2400, width = 43560, height = 1440]
mAccumulatedChildBounds [x = 18120, y = 2550, width = 43560, height = 1140]

In normal mode:
mContainerBounds        [x=18120 y=2400 width=38400 height=1440]
mAccumulatedChildBounds [x=18120 y=2400 width=38400 height=1440]

Walking through the code in ContainerState::ProcessDisplayItems[1] that builds up the mAccumulatedChildBounds, I observed that the bounds calculation on the third child takes a different path. In normal mode, bounds come from display item clip[2], since itemASR != mContainerASR. Whereas in headless, both itemASR and mContainerASR are null, so the bounds come from here[3].

From there, I tried to figure out why itemASR and mContainerASR are different in headless and normal modes. In normal mode’s ContainerState::ProcessDisplayItems the itemASR comes from item->GetActiveScrolledRoot(), whereas in headless itemASR is set to mContainerASR since mManager->IsWidgetLayerManager() returns false. This is where I noticed mManager was different. Relevant code [4]

In normal mode, mManager is a ClientLayerManager and in headless it’s a BasicLayerManager. Again, I tried to figure to why they’re were different, so I set a conditional breakpoint(mContainerBounds.x == 18120 && mContainerBounds.y == 2400) in the ContainerState constructor and from there I can see the backtraces are different:

normal:
bt 15
>>* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
>>    frame #0: 0x0000000112938293 XUL`mozilla::ContainerState::ContainerState(this=0x00007fff5e80a420, aBuilder=0x00007fff5e80ccb0, aManager=0x0000000133018720, aLayerBuilder=0x00000001976a2c80, aContainerFrame=0x0000000132812760, aContainerItem=0x0000000132716e00, aContainerBounds=0x00007fff5e80a350, aContainerLayer=0x000000019764e400, aParameters=0x00007fff5e80a360, aFlattenToSingleLayer=false, aBackgroundColor=0, aContainerASR=0x0000000000000000, aContainerScrollMetadataASR=0x0000000000000000, aContainerCompositorASR=0x0000000000000000) at FrameLayerBuilder.cpp:1081
>>    frame #1: 0x00000001128d4564 XUL`mozilla::ContainerState::ContainerState(this=0x00007fff5e80a420, aBuilder=0x00007fff5e80ccb0, aManager=0x0000000133018720, aLayerBuilder=0x00000001976a2c80, aContainerFrame=0x0000000132812760, aContainerItem=0x0000000132716e00, aContainerBounds=0x00007fff5e80a350, aContainerLayer=0x000000019764e400, aParameters=0x00007fff5e80a360, aFlattenToSingleLayer=false, aBackgroundColor=0, aContainerASR=0x0000000000000000, aContainerScrollMetadataASR=0x0000000000000000, aContainerCompositorASR=0x0000000000000000) at FrameLayerBuilder.cpp:1077
>>    frame #2: 0x00000001128d31fd XUL`mozilla::FrameLayerBuilder::BuildContainerLayerFor(this=0x00000001976a2c80, aBuilder=0x00007fff5e80ccb0, aManager=0x0000000133018720, aContainerFrame=0x0000000132812760, aContainerItem=0x0000000132716e00, aChildren=0x0000000132716e60, aParameters=0x00007fff5e80ab90, aTransform=0x0000000000000000, aFlags=0) at FrameLayerBuilder.cpp:5683
>>    frame #3: 0x000000011292a611 XUL`nsDisplayMask::BuildLayer(this=0x0000000132716e00, aBuilder=0x00007fff5e80ccb0, aManager=0x0000000133018720, aContainerParameters=0x00007fff5e80ab90) at nsDisplayList.cpp:8981
>>    frame #4: 0x00000001128cbdab XUL`mozilla::ContainerState::ProcessDisplayItems(this=0x00007fff5e80b320, aList=0x00007fff5e80c430) at FrameLayerBuilder.cpp:4281
>>    frame #5: 0x00000001128d3210 XUL`mozilla::FrameLayerBuilder::BuildContainerLayerFor(this=0x00000001976a2c80, aBuilder=0x00007fff5e80ccb0, aManager=0x0000000133018720, aContainerFrame=0x000000013015f1e0, aContainerItem=0x0000000000000000, aChildren=0x00007fff5e80c430, aParameters=0x00007fff5e80b830, aTransform=0x0000000000000000, aFlags=0) at FrameLayerBuilder.cpp:5689
>>  * frame #6: 0x000000011290ae94 XUL`nsDisplayList::PaintRoot(this=0x00007fff5e80c430, aBuilder=0x00007fff5e80ccb0, aCtx=0x0000000000000000, aFlags=13) at nsDisplayList.cpp:2271
>>    frame #7: 0x00000001124c3691 XUL`nsLayoutUtils::PaintFrame(aRenderingContext=0x0000000000000000, aFrame=0x000000013015f1e0, aDirtyRegion=0x00007fff5e80e6d8, aBackstop=4294967295, aBuilderMode=PAINTING, aFlags=388) at nsLayoutUtils.cpp:3823
>>    frame #8: 0x0000000112427582 XUL`mozilla::PresShell::Paint(this=0x000000012fb35000, aViewToPaint=0x0000000130129500, aDirtyRegion=0x00007fff5e80e6d8, aFlags=1) at PresShell.cpp:6423
>>    frame #9: 0x0000000111eb7efd XUL`nsViewManager::ProcessPendingUpdatesPaint(this=0x0000000108194a80, aWidget=0x0000000130109c00) at nsViewManager.cpp:480
>>    frame #10: 0x0000000111eb7a99 XUL`nsViewManager::ProcessPendingUpdatesForView(this=0x0000000108194a80, aView=0x0000000130129500, aFlushDirtyRegion=true) at nsViewManager.cpp:412
>>    frame #11: 0x0000000111eb8d9e XUL`nsViewManager::ProcessPendingUpdates(this=0x0000000108194a80) at nsViewManager.cpp:1102
>>    frame #12: 0x00000001123cb923 XUL`nsRefreshDriver::Tick(this=0x0000000130109800, aNowEpoch=1508879745046766, aNowTime=(mValue = 375982661935153)) at nsRefreshDriver.cpp:2091
>>    frame #13: 0x00000001123d1bcf XUL`mozilla::RefreshDriverTimer::TickDriver(driver=0x0000000130109800, jsnow=1508879745046766, now=(mValue = 375982661935153)) at nsRefreshDriver.cpp:337
>>    frame #14: 0x00000001123d19d3 XUL`mozilla::RefreshDriverTimer::TickRefreshDrivers(this=0x0000000131bf1640, aJsNow=1508879745046766, aNow=(mValue = 375982661935153), aDrivers=0x0000000131bf1670) at nsRefreshDriver.cpp:307

headless:
bt 15
>>* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
>>  * frame #0: 0x00000001181f0293 XUL`mozilla::ContainerState::ContainerState(this=0x00007fff574c8c50, aBuilder=0x00007fff574cbc50, aManager=0x000000019c1ede30, aLayerBuilder=0x000000019c356b70, aContainerFrame=0x000000013b22b760, aContainerItem=0x000000019c381560, aContainerBounds=0x00007fff574c8b80, aContainerLayer=0x0000000131b4e400, aParameters=0x00007fff574c8b90, aFlattenToSingleLayer=false, aBackgroundColor=0, aContainerASR=0x0000000000000000, aContainerScrollMetadataASR=0x0000000000000000, aContainerCompositorASR=0x0000000000000000) at FrameLayerBuilder.cpp:1081
>>    frame #1: 0x000000011818c564 XUL`mozilla::ContainerState::ContainerState(this=0x00007fff574c8c50, aBuilder=0x00007fff574cbc50, aManager=0x000000019c1ede30, aLayerBuilder=0x000000019c356b70, aContainerFrame=0x000000013b22b760, aContainerItem=0x000000019c381560, aContainerBounds=0x00007fff574c8b80, aContainerLayer=0x0000000131b4e400, aParameters=0x00007fff574c8b90, aFlattenToSingleLayer=false, aBackgroundColor=0, aContainerASR=0x0000000000000000, aContainerScrollMetadataASR=0x0000000000000000, aContainerCompositorASR=0x0000000000000000) at FrameLayerBuilder.cpp:1077
>>    frame #2: 0x000000011818b1fd XUL`mozilla::FrameLayerBuilder::BuildContainerLayerFor(this=0x000000019c356b70, aBuilder=0x00007fff574cbc50, aManager=0x000000019c1ede30, aContainerFrame=0x000000013b22b760, aContainerItem=0x000000019c381560, aChildren=0x000000019c3815c0, aParameters=0x00007fff574c93b8, aTransform=0x0000000000000000, aFlags=0) at FrameLayerBuilder.cpp:5683
>>    frame #3: 0x00000001181e2611 XUL`nsDisplayMask::BuildLayer(this=0x000000019c381560, aBuilder=0x00007fff574cbc50, aManager=0x000000019c1ede30, aContainerParameters=0x00007fff574c93b8) at nsDisplayList.cpp:8981
>>    frame #4: 0x0000000118187174 XUL`mozilla::FrameLayerBuilder::AddPaintedDisplayItem(this=0x000000019c3568d0, aLayerData=0x000000019c1e5988, aItem=0x000000019c381560, aClip=0x000000019bd8dc00, aContainerState=0x00007fff574ca2c0, aLayerState=LAYER_SVG_EFFECTS, aTopLeft=0x000000019c1e5a90) at FrameLayerBuilder.cpp:4702
>>    frame #5: 0x000000011817bec2 XUL`void mozilla::ContainerState::FinishPaintedLayerData<mozilla::PaintedLayerDataNode::PopPaintedLayerData()::$_0>(this=0x00007fff574ca2c0, aData=0x000000019c1e5988, aFindOpaqueBackgroundColor=(anonymous class) @ 0x00007fff574c9d10)::$_0) at FrameLayerBuilder.cpp:3166
>>    frame #6: 0x000000011817bb83 XUL`mozilla::PaintedLayerDataNode::PopPaintedLayerData(this=0x000000019c340b00) at FrameLayerBuilder.cpp:2871
>>    frame #7: 0x000000011817b91c XUL`mozilla::PaintedLayerDataNode::PopAllPaintedLayerData(this=0x000000019c340b00) at FrameLayerBuilder.cpp:2881
>>    frame #8: 0x000000011817b76c XUL`mozilla::PaintedLayerDataNode::Finish(this=0x000000019c340b00, aParentNeedsAccurateVisibleAboveRegion=false) at FrameLayerBuilder.cpp:2835
>>    frame #9: 0x000000011817d50a XUL`mozilla::PaintedLayerDataTree::Finish(this=0x00007fff574ca380) at FrameLayerBuilder.cpp:2895
>>    frame #10: 0x000000011818a24d XUL`mozilla::ContainerState::Finish(this=0x00007fff574ca2c0, aTextContentFlags=0x00007fff574ca190, aContainerPixelBounds=0x00007fff574ca1a0, aChildItems=0x00007fff574cb3d0, aHasComponentAlphaChildren=0x0000000000000000) at FrameLayerBuilder.cpp:5265
>>    frame #11: 0x000000011818b354 XUL`mozilla::FrameLayerBuilder::BuildContainerLayerFor(this=0x000000019c3568d0, aBuilder=0x00007fff574cbc50, aManager=0x000000013b9f8720, aContainerFrame=0x0000000138bd91e0, aContainerItem=0x0000000000000000, aChildren=0x00007fff574cb3d0, aParameters=0x00007fff574ca7d0, aTransform=0x0000000000000000, aFlags=0) at FrameLayerBuilder.cpp:5703
>>    frame #12: 0x00000001181c2e94 XUL`nsDisplayList::PaintRoot(this=0x00007fff574cb3d0, aBuilder=0x00007fff574cbc50, aCtx=0x0000000000000000, aFlags=13) at nsDisplayList.cpp:2271
>>    frame #13: 0x0000000117d7b691 XUL`nsLayoutUtils::PaintFrame(aRenderingContext=0x0000000000000000, aFrame=0x0000000138bd91e0, aDirtyRegion=0x00007fff574cd678, aBackstop=4294967295, aBuilderMode=PAINTING, aFlags=388) at nsLayoutUtils.cpp:3823
>>    frame #14: 0x0000000117cdf582 XUL`mozilla::PresShell::Paint(this=0x0000000138bd6000, aViewToPaint=0x0000000138b8dc00, aDirtyRegion=0x00007fff574cd678, aFlags=1) at PresShell.cpp:6423


I’m not familiar with frame/layer code, so I’m not sure why in normal mode the container state is created directly from the PaintRoot and causes the layer manager to be a ClientLayerManager versus in headless, the ContainerState is created from further down in the PaintRoot call when PaintedLayerDataTree::Finish is called and subsequently FrameLayerBuilder::AddPaintedDisplayItem which sets the layer manager to a BasicLayerManager.


[1] http://searchfox.org/mozilla-central/rev/1285ae3e810e2dbf2652c49ee539e3199fcfe820/layout/painting/FrameLayerBuilder.cpp#4001
[2] http://searchfox.org/mozilla-central/rev/1285ae3e810e2dbf2652c49ee539e3199fcfe820/layout/painting/FrameLayerBuilder.cpp#4111
[3] http://searchfox.org/mozilla-central/rev/1285ae3e810e2dbf2652c49ee539e3199fcfe820/layout/painting/FrameLayerBuilder.cpp#4097
[4] http://searchfox.org/mozilla-central/rev/1285ae3e810e2dbf2652c49ee539e3199fcfe820/layout/painting/FrameLayerBuilder.cpp#4052
Another thing to note, in normal mode, e10s and non-e10s have different values for the mContainerBounds of the nsTextControlFrame. 

Regular non-e10s:
(x = 18120, y = 2550, width = 38400, height = 1140)
Regular e10s:
(x = 18120, y = 2400, width = 38400, height = 1440)

The container values appear to come from different paths in GetClippedBoundsWithRespectToASR[1]. In non-e10s, it calls GetClippedBounds vs e10s calls DisplayItemClipChain::ClipForASR. 


[1]http://searchfox.org/mozilla-central/rev/dd47bee6468de7e1221b4d006342ad6b9813d0e5/layout/painting/nsDisplayList.cpp#2149
Appears to be fixed now, likely bug 1382534.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.