Open Bug 1431249 Opened 8 years ago Updated 11 months ago

Create a reference frame for perspective transforms

Categories

(Core :: Web Painting, enhancement, P3)

enhancement

Tracking

()

Tracking Status
firefox59 --- affected

People

(Reporter: botond, Unassigned)

Details

When we added APZ support for perspective transforms in bug 1168263, the changes we had to make to APZ code were fairly hacky and special-case-y. Since then, we've just had to pile on with more hackery in bug 1424591 and bug 1429373. I discussed this situation with :mattwoodrow, and he suggested that we could create stacking contexts for perspective transforms. We believe this would change the shape of affected layer trees in such a way that the hacky APZ changes I mentioned would no longer be necessary.
Stacking contexts are a CSS standard concept that means that everything rendered by this element (and descendants) can be rendered atomically (to a temporary buffer), and no content from our siblings/ancestors can be sorted into the middle. The perspective property introduces a stacking context (and we do handle this correctly), but we build our display list in a weird way. The stacking context means that it's valid to create a single nsDisplayPerspective that wraps the content for the frame with perspective, and everything under it. Instead we create a nsDisplayWrapList as this container to enforce the stacking context, plus we add an nsDisplayPerspective around each child that has a transform affected by our perspective. Transformed frames are a 'reference frame' for the display list, which means that all items within the transform have coordinates relative to the transform frame, and the transform item itself applies the CSS transform, followed by a translation to adjust into the coordinate space outside the transform (the next transformed ancestor, or the root). When a transform display item detects that it has a perspective item wrapping it, we instead make this translation just convert into the coordinate space of the perspective frame, then the perspective item becomes responsible for applying whatever translation is left. This also means that we get N nsDisplayPerspective items, one for each transformed child, and we have some complexity involved to give each of these items a unique identifier. The solution proposed here is to make perspective frames a reference frame, and just create a single nsDisplayPerspective item that wraps all children. Transformed children would get the translation offset applied (as normal) to their reference frame, which would be the same as the special-case for perspective we have now. Non-transformed children will get the perspective transformation applied, but this is a no-op for non-3d transforms. It's probably possible for the perspective item to have children transform item, but where the frame for the child item belongs to a descendant other than a direct child of the perspective item. In this case the perspective shouldn't be applied, and we'd need to do something to block this. We have the Layer::CONTENT_EXTEND_3D_CONTEXT flag, which flattens transforms to 2d (and would solve this), except it operates in the wrong direction (controls combining with children, we want to control combining with parent), but something similar might work. CC'ing gerald in case this is something he'd be interested in working on.
Thanks for the details, Matt! I'm adjusting the bug title to be a bit more accurate based on your description.
Summary: Create a stacking context for perspective transforms → Create a reference frame for perspective transforms
[ Triage 2017/02/20: P3 ]
Priority: -- → P3
Assignee: nobody → gsquelart
Component: Layout → Layout: Web Painting
Sorry, can't manage, so I'm putting it back on the up-for-grabs pile.
Assignee: gsquelart → nobody
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.