Rebuild display lists for frame subtrees
Categories
(Core :: Web Painting, enhancement, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox98 | --- | fixed |
People
(Reporter: mstange, Assigned: mikokm)
References
Details
(Keywords: perf-alert)
Attachments
(3 files)
At the moment we rebuild parts of the display list based on a rebuild rectangle.
It would be better if we could rebuild a frame subtree, regardless of item coordinates.
The challenge with this is computing the correct order of the flattened display list of the containing stacking context; the display items from the rebuilt frame subtree may need to be inserted in various different spots in the outer list:
- Frame A [stacking context]
- Frame B: background item 1, positioned item 2 [z-index: 2]
- Frame C: float item 3
- Frame D: [stacking context] with wrapper item 4 and more items inside it
- ...
- Frame E: background item 5
- Frame F
- Frame G: positioned item 6 [z-index: 1], background item 7
- Frame F
- Frame B: background item 1, positioned item 2 [z-index: 2]
The flattened list for frame A should be in the order 1, 5, 7, 3, 4, 6, 2. (I think. Please correct me if I got this example wrong.) Rebuilding display items for the frame subtree rooted at frame E needs to result in that order, too.
If every frame tracked the display items that it built for itself, and every stacking context frame retained a flattened display list for itself + contents, then we could have a fast rebuild traversal where untouched frames just take their already-built items and add them to the stacking context's display list set.
So, in the above example, if frame E is touched, the next paint would find frame A (the nearest ancestor stacking context of frame E), create an empty display list set for frame A, and then traverse A's contents. The frames under B would simply add their existing items to the display list set. The nested stacking context at frame D does not need to recurse into its contents and can just use its existing wrapper item. And the frames under E would make fresh items for themselves, and also add them to the display list set. At the end, the display list set is flattened into a list on frame A.
The disadvantage over today's approach would be that you can't easily skip untouched subtrees during the fast traversal. With the rebuild rect, you can skip subtrees if the intersection with the frame's overflow rect is empty, because a frame's overflow rect includes all subtree contents. With this proposal, fast rebuild-skipping is only possible for frames that are stacking contexts.
Comment 1•4 years ago
|
||
I definitely like this idea, seems like it'd be a fair bit simpler than the current RDL merging.
One of the design goals of RDL was to avoid touching all the other frames (and associated style contexts, elements) that hadn't been invalidated.
It depends a lot on the specific web page, but it's not uncommon to have large frames tree without many stacking contexts breaking it up (though we could try encourage usage of contain
to help with this). The existing displaylist-mutate talos tests would almost certainly regress, but that's not necessarily meaningful.
A large portion of display list building time appears to be reading memory into cache, so the traversal just to add existing items might still be fairly slow. If we can do so without touching style contexts or the element at all, then that might be a significant win. If the cached items were tagged with which sublist they should be added to, maybe we can do that. We'd probably want some frame state bits set to identify which frames have descendants with items, so that we can traverse frames efficiently without doing visible region calculations.
We'd need to handle pseudo-stacking contexts too, maybe by adding the single item like we do for stacking context, and setting a builder flag to note that all items from frames that we recurse into should be ignored, unless in the positioned descendants list.
Assignee | ||
Updated•3 years ago
|
Assignee | ||
Updated•3 years ago
|
Assignee | ||
Updated•3 years ago
|
Assignee | ||
Comment 2•3 years ago
|
||
Updated•3 years ago
|
Assignee | ||
Comment 3•3 years ago
|
||
This patch implements the functionality needed to reuse previously built stacking context display items without display list merging.
It works as follows:
- Full paint happens
- When creating container items for stacking context frames, the outermost container items are marked with "top-level container" flag.
- Next paint happens
-
Modified frames are fetched from the root frame and the frame tree flags are updated so that every frame with children knows if their children have changed.
-
During display list preprocessing, the top-level container items are collected from the previous display list, if none of the ancestor or descendant frames have been modified. The items are marked with "reuseable container" flag. The display items inside the container are kept linked. The content outside of reuseable container items is destroyed.
-
During partial display list build, the previously built display items of the frame are checked, and reuseable container items are reused (if doing a partial display list build for painting and not inside a modified frame subtree).
Updated•3 years ago
|
Assignee | ||
Comment 4•3 years ago
|
||
Depends on D128413
Assignee | ||
Comment 5•3 years ago
|
||
Depends on D133200
Comment 7•3 years ago
|
||
Log: https://treeherder.mozilla.org/logviewer?job_id=364860480&repo=autoland&lineNumber=15675
https://treeherder.mozilla.org/logviewer?job_id=364861902&repo=autoland&lineNumber=24314
Backout: https://hg.mozilla.org/integration/autoland/rev/10f05d6ace0827313032d8886aeb6b3868320d15
Comment 9•3 years ago
|
||
Backed out 3 changesets (Bug 1697979) for causing reftest failures in retained-dl-displayport-1.html
Backout link: https://hg.mozilla.org/integration/autoland/rev/ade743ee3253ad02dfb0d017b19b7bdcc8457b1d
Push with failures, failure log.
Comment 10•3 years ago
|
||
Comment 11•3 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/1513c7b10085
https://hg.mozilla.org/mozilla-central/rev/356161819877
https://hg.mozilla.org/mozilla-central/rev/bc9369b38412
Assignee | ||
Updated•3 years ago
|
Comment 12•3 years ago
|
||
(In reply to Alexandru Michis [:malexandru] from comment #9)
Backed out 3 changesets (Bug 1697979) for causing reftest failures in retained-dl-displayport-1.html
Backout link: https://hg.mozilla.org/integration/autoland/rev/ade743ee3253ad02dfb0d017b19b7bdcc8457b1d
Push with failures, failure log.
== Change summary for alert #33053 (as of Tue, 25 Jan 2022 07:37:38 GMT) ==
Regressions:
Ratio | Test | Platform | Options | Absolute values (old vs new) |
---|---|---|---|---|
21% | tabpaint | windows10-64-shippable-qr | e10s fission stylo webrender | 46.52 -> 56.43 |
16% | tabpaint | windows10-64-shippable-qr | e10s fission stylo webrender | 48.24 -> 55.84 |
For up to date results, see: https://treeherder.mozilla.org/perfherder/alerts?id=33053
Comment hidden (obsolete) |
Updated•3 years ago
|
Description
•