aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/main/layout/layout_task.rs
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2013-08-01 15:42:26 -0700
committerbors-servo <release+servo@mozilla.com>2013-08-01 15:42:26 -0700
commit1d04d5f1bc90d7ddd27718fe7ea2b9866f94d79b (patch)
tree77b0021787f706cf03c3d2fe8fb84991f8e1b948 /src/components/main/layout/layout_task.rs
parentbb51a9d6fb784e71ac279e501e21064fe6bdad5b (diff)
parentb266b5a949103b0c0f11a38a0506c232723f7692 (diff)
downloadservo-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.rs48
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