Hello Servo people! I've been working on a proof of concept for a new
display list design. Instead of representing the display list as a tree
of stacking concepts, all display list items are stored in a flat list.
The idea behind this experiment is that one day the flow tree will
produce a flat list of vertex buffer data to be consumed by WebRender
and not a display list. My work is an intermediary step, where we can
preserve the existing compositor + skia path while also making the diff
to merge WebRender smaller.

I've been hacking on this for a while, but I've just now gotten my work
to a point where it generally doesn't crash and passes the basic suite
of stacking tests. The idea with this email is to get some feedback on
the design before polishing this up, running some performance checks,
and posting pull requests.

Overview of the changes:

The display list structure looks like this:

pub struct DisplayList {
  pub list: Vec<DisplayListEntry>,
  pub stacking_contexts: Vec<Arc<StackingContext>>,
  pub sort_code_map: HashMap<StackingContextId, SortCode>,
}

pub struct DisplayListEntry {
    pub stacking_context_id: StackingContextId,
    pub section: DisplayListSection,
    pub item: DisplayItem,
}

Additionally, all StackingContexts have a SortCode, which is the crux of
the change.

pub struct SortCode {
    segments: Vec<SortCodeSegment>,
    number_of_pseudo_contexts: usize,
}

struct SortCodeSegment(StackingContextId, u32, DisplayListSection, i32);

The elements of the SortCode segment are the StackingContextId, the
index of this particular stacking context in the parent stacking
context, the section of the display list (corresponding to sections in
CSS2 appendix E) and the z-index. Every StackingContext's SortCode
contains the segments of its ancestors.

Each display item contains an implicit SortCode that is composed of the
id of its containing StackingContext along with the section of the
display list recorded in the DisplayListEntry. This information allows
any item to be sorted against any other item.

The idea for the final design is:

1. Fast sequential traversal: assign StackingContexts to every flow item
and SortCodes to every StackingContext
2. Build the display list result for every item. This can be done in any
order and also completely parallel across the entire tree.
3. Collect all display items and sort them.

Some features of the new design:
* Other than noting where layer boundaries are, all layers are created
and managed by the PaintTask. WebRender can simply ignore the layer_info
member of StackingContexts and handle LayeredItems how it pleases. In
the end, waiting until the last moment to slice up the DisplayList into
layers made the code much simpler.
* Pseudo-stacking contexts now have StackingContext structs.
* Since, for the moment, StackingContext transformations are built up
iteratively, traversal through the DisplayList is done with a special
iterator.

What's missing:
* Hit testing
* Display list optimization/culling
* Stacking context assignment optimization

Really this is just meant as a trigger to discuss the design. I'm still
working out a lot of bugs at the moment.

Here's the Github link:
https://github.com/mrobinson/servo/tree/flat-display-list

--Martin

_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to