The Servo Browser Engine -- A Learner's Notebook

Layout

The main job for layout is to determine the position and size of each renderers (elements to be displayed.) The layout task takes a snapshot of the DOM, calculates its style and construct a flow tree (components/layout/flow.rs). The flow tree is used to calculate the display list (components/gfx/display_list/mod.rs) to be send to the renderer.

The layout task is located in components/layout/layout_task.rs. The main routine that does the layout is layout_tasks.rs::handle_reflow<'a>(...)

In handle_reflow, three major steps happens:

  1. Traverse the DOM tree to construct the flow tree (traverse_dom_preorder)
  2. Compute the exact position of the boxes by going through the flow tree (solve_constraints)
  3. Build the display list from the flow tree and send it the the painter (build_display_list_for_reflow)

The first two steps has ae sequential version and a parallel version, located in sequential.rs and parallel.rs respectively. We'll first look at the sequential version.

The sequential::traverse_dom_preorder goes through the DOM tree in a recursive way. First, the RecalcStyleForNode calculates the style applies to the current node. Then, before ConstructFlows is called to construct the flow tree, the children of the current nodes are processed recursively.

In RecalcStyleForNode, if the we are using non-incremental layour, or the node has a dirty bit set (needs to re-layout), we will recalculate is CSS style. First, the existing styles is removed (node.unstyle()). To reduce the space and time need for storing and using style, the style can be shared between nodes using a style_sharing_candidate_cache. If the we can find a shared style for the node, we create a ThreadSafeLayoutNode from the current node and set its restyle damage, which is a bitmap indicating which layout action needs to be performed on the current node. If no shared style is found. We simply perform a CSS selector matching (node.match_node()). Finally, the node is inserted into a bloom filter. This bloom filter can help with the CSS selector matching process by reducing the cost of walking up the tree to look for ancestors (see components/layout/traversal for explanation).

TODO:

Reference: