Closed Bug 1697979 Opened 3 years ago Closed 2 years ago

Rebuild display lists for frame subtrees

Categories

(Core :: Web Painting, enhancement, P2)

enhancement

Tracking

()

RESOLVED FIXED
98 Branch
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

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.

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.

Severity: -- → S3
Priority: -- → P2
Summary: Ideas for better retained display lists → Rebuild display lists for frame subtrees
See Also: → 1554503, 1539597
Assignee: nobody → mikokm
Status: NEW → ASSIGNED
See Also: → 1737889
Attachment #9245810 - Attachment description: WIP: Bug 1697979 - Reuse previously built stacking context display items without merging [WIP] → Bug 1697979 - Reuse previously built stacking context display items without merging r=mstange

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
  1. When creating container items for stacking context frames, the outermost container items are marked with "top-level container" flag.
  • Next paint happens
  1. 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.

  2. 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.

  3. 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).

Attachment #9245810 - Attachment description: Bug 1697979 - Reuse previously built stacking context display items without merging r=mstange → Bug 1697979 - Part 1: Reuse previously built stacking context display items without merging r=mstange

Depends on D128413

Depends on D133200

Depends on: 1751018
Pushed by mikokm@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/1cb3b14f2f6c
Part 1: Reuse previously built stacking context display items without merging r=mstange
https://hg.mozilla.org/integration/autoland/rev/456b57492294
Part 2: Adjust test expectations r=mstange
https://hg.mozilla.org/integration/autoland/rev/4edb10a45d13
Part 3: Add tests r=mstange
Pushed by mikokm@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/ea7ce38abaab
Part 1: Reuse previously built stacking context display items without merging r=mstange
https://hg.mozilla.org/integration/autoland/rev/db3882cc536c
Part 2: Adjust test expectations r=mstange
https://hg.mozilla.org/integration/autoland/rev/e4248d811360
Part 3: Add tests r=mstange

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.

Pushed by mikokm@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/1513c7b10085
Part 1: Reuse previously built stacking context display items without merging r=mstange
https://hg.mozilla.org/integration/autoland/rev/356161819877
Part 2: Adjust test expectations r=mstange
https://hg.mozilla.org/integration/autoland/rev/bc9369b38412
Part 3: Add tests r=mstange
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 98 Branch
Regressions: 1751587
Flags: needinfo?(mikokm)
Depends on: 1751742
Regressions: 1751743

(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

Regressions: 1751892
Regressions: 1751965
No longer regressions: 1751965
Regressions: 1758860
No longer regressions: 1758860
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: