diff options
author | bors-servo <release+servo@mozilla.com> | 2013-08-01 15:42:26 -0700 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2013-08-01 15:42:26 -0700 |
commit | 1d04d5f1bc90d7ddd27718fe7ea2b9866f94d79b (patch) | |
tree | 77b0021787f706cf03c3d2fe8fb84991f8e1b948 /src/components/main/layout/layout_task.rs | |
parent | bb51a9d6fb784e71ac279e501e21064fe6bdad5b (diff) | |
parent | b266b5a949103b0c0f11a38a0506c232723f7692 (diff) | |
download | servo-1d04d5f1bc90d7ddd27718fe7ea2b9866f94d79b.tar.gz servo-1d04d5f1bc90d7ddd27718fe7ea2b9866f94d79b.zip |
auto merge of #646 : kmcallister/servo/incremental-layout, r=metajack
This is a first attempt at incremental layout. When recomputing styles, we compare old and new CSS properties to determine which layout steps can be skipped.
Since I'm new to Servo I'm not sure that my code matches the idioms of the project. Please don't hold back with review comments :)
Diffstat (limited to 'src/components/main/layout/layout_task.rs')
-rw-r--r-- | src/components/main/layout/layout_task.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index 68ba371d110..1581ba5f2e8 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -13,6 +13,7 @@ use layout::box_builder::LayoutTreeBuilder; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder}; use layout::flow::FlowContext; +use layout::incremental::{RestyleDamage, BubbleWidths}; use std::cast::transmute; use std::cell::Cell; @@ -193,6 +194,8 @@ impl LayoutTask { self.doc_url = Some(doc_url); let screen_size = Size2D(Au::from_px(data.window_size.width as int), Au::from_px(data.window_size.height as int)); + let resized = self.screen_size != Some(screen_size); + debug!("resized: %?", resized); self.screen_size = Some(screen_size); // Create a layout context for use throughout the following passes. @@ -227,20 +230,59 @@ impl LayoutTask { layout_root }; + // Propagate restyle damage up and down the tree, as appropriate. + // FIXME: Merge this with flow tree building and/or the other traversals. + for layout_root.traverse_preorder |flow| { + // Also set any damage implied by resize. + if resized { + do flow.with_mut_base |base| { + base.restyle_damage.union_in_place(RestyleDamage::for_resize()); + } + } + + let prop = flow.with_base(|base| base.restyle_damage.propagate_down()); + if prop.is_nonempty() { + for flow.each_child |kid_ctx| { + do kid_ctx.with_mut_base |kid| { + kid.restyle_damage.union_in_place(prop); + } + } + } + } + + for layout_root.traverse_postorder |flow| { + do flow.with_base |base| { + match base.parent { + None => {}, + Some(parent_ctx) => { + let prop = base.restyle_damage.propagate_up(); + do parent_ctx.with_mut_base |parent| { + parent.restyle_damage.union_in_place(prop); + } + } + } + } + } + debug!("layout: constructed Flow tree"); - debug!("", layout_root.dump()); + debug!("%?", layout_root.dump()); // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. do profile(time::LayoutMainCategory, self.profiler_chan.clone()) { - for layout_root.traverse_postorder |flow| { + for layout_root.traverse_postorder_prune(|f| f.restyle_damage().lacks(BubbleWidths)) |flow| { flow.bubble_widths(&mut layout_ctx); }; + + // FIXME: We want to do + // for layout_root.traverse_preorder_prune(|f| f.restyle_damage().lacks(Reflow)) |flow| { + // but FloatContext values can't be reused, so we need to recompute them every time. for layout_root.traverse_preorder |flow| { flow.assign_widths(&mut layout_ctx); }; // For now, this is an inorder traversal + // FIXME: prune this traversal as well layout_root.assign_height(&mut layout_ctx); } @@ -272,8 +314,6 @@ impl LayoutTask { } // time(layout: display list building) } - debug!("%?", layout_root.dump()); - // Tell script that we're done. // // FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without |