Currently the overlap testing code computes all layer bounds in absolute coords, and adds them to regions in the overlap map's region stack. This doesn't make too much sense when elements are 3d-transformed (e.e. by flips), and can be very expensive. I think it would be better to treat certain layers as "overlap-test containers", and when traversing descendants, to compute regions relative to those containers. E.g. 3d-transformed element would be containers. When you pop that layer off the stack, you could map its region bounds into the space of the parent container.
This code in RenderLayer::calculateClipRects() seems just wrong: // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where // clipRects are needed in view space. LayoutPoint offset; offset = roundedIntPoint(renderer()->localToContainerPoint(FloatPoint(), rootLayer->renderer())); RenderView* view = renderer()->view(); ASSERT(view); if (view && clipRects.fixed() && rootLayer->renderer() == view) { offset -= view->frameView()->scrollOffsetForFixedPosition(); } You can't just offset when mapping rects through transforms. It really doesn't make any sense to ask for global clip rects when there are transforms. That's why transforms are normally act as clipping roots. This is causing some issues in content we have that does rotateY(180deg); the overlap testing is just broken.
Created attachment 150981 [details] Testcase
This is a bit harder than I thought. I think we should treat layers with transforms as overlap region roots, but we may not be pushing a transformed layer onto the OverlapMap at first; we won't until we discover that it has composited descendants.
Another wrinkle; accumulating into the m_overlapStack[m_overlapStack.size() - 2] region is problematic because that may cross a transform boundary.
For some reason I'm finding it really hard to fix this. The OverlapMap messes with my brain. As well as mapping regions in the overlap map up through transforms, we need to also clip them. I think this is very similar to what RenderObject::computeRectForRepaint() does, but that is designed to be called during layout.
We should also consider elements with animating transofrms as "islands" of overlap testing. Bug 91787.
I ran onto similar issue when rotated element overlaps another element, which is on top of it. In Chrome the top element seems to be correctly placed (no overlap is visible), but once you try to hover it - after a certain point the hover is not working anymore. In Safari and in the latest nighty build of standalone Webkit (r140252 at the time of writing) - you actually can see that the bottom square overlaps the top at some point. Demo - http://codepen.io/angryObject/full/rcdHm.
(In reply to comment #7) > I ran onto similar issue when rotated element overlaps another element, which is on top of it. > > In Chrome the top element seems to be correctly placed (no overlap is visible), but once you try to hover it - after a certain point the hover is not working anymore. > > In Safari and in the latest nighty build of standalone Webkit (r140252 at the time of writing) - you actually can see that the bottom square overlaps the top at some point. > > Demo - http://codepen.io/angryObject/full/rcdHm. Unless I misunderstood your comments - what you're seeing on that link is a different meaning of "overlap" related to hit-testing / layer sorting / preserve-3d. Chrome and Safari may not have matching semantics (yet) about preserve-3d (or lack thereof in your example), due to different layer sorting implementation quirks. The overlap Simon is referring to is an implementation detail when choosing what parts of the DOM can be grouped together into an accelerated composited layer; sometimes layers need to be forced to become compositing because they overlap other things that are compositing, so that we can keep the desired paint-order as per CSS 2.1 spec.
From the attached, I do see "red" in all browsers (Safari 16, Firefox Nightly 107 and Chrome Canary 108) but the red area in Safari 16 is more than all other browsers (half while 1/4 in others).