Rewrite flow construction to be incrementalizable and parallelizable.

This replaces flow construction with a strict bottom-up tree traversal,
allowing for parallelism. Each step of the traversal creates a flow or
a `ConstructionItem`, similar to how Gecko works. {ib} splits are
handled by not creating `InlineFlow`s until the containing block is
reached.

This should be able to be incrementalized by storing the `Flow` from
layout to layout, and performing fixups during flow construction
and/or wiping containing blocks in a previous pass.
This commit is contained in:
Patrick Walton 2013-11-09 21:39:39 -08:00
parent 37f9427b6c
commit 155befe10d
24 changed files with 1259 additions and 889 deletions

View file

@ -196,14 +196,14 @@ impl LineboxScanner {
debug!("LineboxScanner: Trying to place first box of line {}", self.lines.len());
let first_box_size = first_box.base().position.get().size;
debug!("LineboxScanner: box size: {}", first_box_size);
let splitable = first_box.can_split();
let splittable = first_box.can_split();
debug!("LineboxScanner: box size: {}, splittable: {}", first_box_size, splittable);
let line_is_empty: bool = self.pending_line.range.length() == 0;
// Initally, pretend a splitable box has 0 width.
// Initally, pretend a splittable box has 0 width.
// We will move it later if it has nonzero width
// and that causes problems.
let placement_width = if splitable {
let placement_width = if splittable {
Au::new(0)
} else {
first_box_size.width
@ -231,7 +231,7 @@ impl LineboxScanner {
// If not, but we can't split the box, then we'll place
// the line here and it will overflow.
if !splitable {
if !splittable {
debug!("LineboxScanner: case=line doesn't fit, but is unsplittable");
return (line_bounds, first_box_size.width);
}
@ -467,6 +467,15 @@ impl InlineFlow {
}
}
pub fn from_boxes(base: FlowData, boxes: ~[@RenderBox]) -> InlineFlow {
InlineFlow {
base: base,
boxes: boxes,
lines: ~[],
elems: ElementMapping::new(),
}
}
pub fn teardown(&mut self) {
for box in self.boxes.iter() {
box.teardown();