Bug 81989

Summary: Need to do layouts when transforms change on composited layers
Product: WebKit Reporter: Simon Fraser (smfr) <simon.fraser>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Normal CC: ahmad.saleem792, dino, jchaffraix, pacodj, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: BrowserCompat, InRadar
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Testcase
none
Chrome, Safari & Firefox - Video Reference none

Simon Fraser (smfr)
Reported 2012-03-22 16:22:59 PDT
We're currently failing to do layouts when the transform on a composited layer changes. This means that we fail to recompute overflow.
Attachments
Testcase (5.74 KB, text/html)
2012-03-22 16:25 PDT, Simon Fraser (smfr)
no flags
Chrome, Safari & Firefox - Video Reference (10.87 MB, video/quicktime)
2024-04-12 03:45 PDT, Ahmad Saleem
no flags
Simon Fraser (smfr)
Comment 1 2012-03-22 16:25:28 PDT
Created attachment 133381 [details] Testcase
Radar WebKit Bug Importer
Comment 2 2012-03-22 16:26:45 PDT
Ahmad Saleem
Comment 3 2024-04-12 03:45:13 PDT
Created attachment 470888 [details] Chrome, Safari & Firefox - Video Reference I am able to reproduce this bug in Safari Technology Preview 192 and the comparison between all browser can be seen with Chrome Canary 125 and Firefox Nightly 126.
pacodj
Comment 4 2026-10-01 00:45:34 PDT
Still reproduces in Safari 26.6.2 (macOS 26.6.2), iOS 26.4 Simulator Safari and Playwright WebKit 26.4. Chrome 154 and Firefox 150 are correct. Reduced case (attached, also at https://pduhard.github.io/webkit-composited-transform-overflow/): a 300x200 `overflow: hidden` box holds a full-size card with `transform: translateX(300px)`. The card is composited (a `transform: translateZ(0)` child, or `will-change: transform`). Script sets the card to `translateX(0px)`. Chrome and Firefox report scrollWidth 300, and `scrollLeft = 150` gives 0. WebKit keeps scrollWidth 600, and `scrollLeft = 150` scrolls into empty space, until something else lays out the box. The other direction is stale too. Draft fix: https://github.com/WebKit/WebKit/pull/75516. It keeps RecompositeLayer for the composited renderer and marks its containing block for simplified normal flow layout, which recomputes overflow up the containing block chain without laying out or repainting the renderer. Chromium does the equivalent on transform changes (ContainingBlock()->SetNeedsOverflowRecalc()). Related tests pass on a macOS release build and a debug build (compositing, fast/overflow, fast/scrolling, fast/repaint, transforms, animations, and the css-overflow, css-transforms and cssom-view WPTs). It also makes css-transforms/change-scale-wide-range.html match its reference. The open question is cost. When script moves every child of a container on every frame, the container now recomputes its overflow over all its children each frame: about 100 ns per child on an M5, almost all of it mapping each child's rect through its transform. MotionMark's developer test HTMLSuite/CompositedTransforms drops 5.4% (6 interleaved runs in WebKitTestRunner's off-screen view, no display available). MotionMark's main score and Speedometer 3.1 are unchanged. Two attempts did not help: skipping the recompute while the box stays inside its containing block's padding box (some moving child always touches an edge), and building the matrix in getTransformFromContainer more cheaply (the time moves to mapRect). The remaining option I see is to recompute this overflow lazily, when scroll geometry is read, which WebKit has no mechanism for today. Is the eager cost acceptable here, or would you prefer the lazy route or something else?
Note You need to log in before you can comment on or make changes to this bug.