With a non-stacking-context overflow scroll, we want to avoid re-computing compositing while scrolling (so not clip overflow bounds to the scroller's bounds), but we have to avoid triggering compositing of elements that are outside the scroller, but siblings in z-order.
overlapMap.push/popCompositingContainer() only knows how to handle overlap for things that are compositing container (generally, stacking context). It can't handle z-order siblings that have different clips in their containing block ancestor chain.
I think the logic could work something like this (where "inside" and "outside" refer to containing block order): * inside a composited overflow:scroll, we only need to consider overlap with other layers inside that same overflow scroll. i.e. the overflow scroll provides an overlap scope. * layers outside a composited overflow scroll don't need to overlap with layers inside that composited overflow scroll, since the composited scroller itself will provide the rect to overlap. So I think we need a per-stacking context tree where the non-child nodes are all overflow nodes (in containing block order), the leave nodes are layers, and at each level the nodes are sorted in z-order. Checking for overflow involves finding a layer in this tree and just checking for overflow against earlier siblings sharing the same parent.