diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2014-10-30 13:27:35 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2014-10-31 12:24:40 -0700 |
commit | 08fc7c2795ebfbb53b409ad563e9b1131c99f669 (patch) | |
tree | 7cba247ef4993af57d6106ef6e7265680dab73e6 /components/layout/css | |
parent | 7712052e137cdefc567d17366b233c060cf2477b (diff) | |
download | servo-08fc7c2795ebfbb53b409ad563e9b1131c99f669.tar.gz servo-08fc7c2795ebfbb53b409ad563e9b1131c99f669.zip |
layout: Make incremental reflow more fine-grained by introducing "reflow
out-of-flow" and "reconstruct flow" damage bits.
This is needed for good performance on the maze solver.
Diffstat (limited to 'components/layout/css')
-rw-r--r-- | components/layout/css/matching.rs | 95 | ||||
-rw-r--r-- | components/layout/css/node_style.rs | 14 | ||||
-rw-r--r-- | components/layout/css/node_util.rs | 24 |
3 files changed, 45 insertions, 88 deletions
diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 29c4f5208f4..62374477181 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -5,11 +5,9 @@ //! High-level interface to CSS selector matching. use css::node_style::StyledNode; -use incremental; -use incremental::RestyleDamage; +use incremental::{mod, RestyleDamage}; use util::{LayoutDataAccess, LayoutDataWrapper}; -use wrapper::{LayoutElement, LayoutNode, ThreadSafeLayoutNode}; -use wrapper::{TLayoutNode}; +use wrapper::{LayoutElement, LayoutNode, TLayoutNode}; use script::dom::node::{TextNodeTypeId}; use servo_util::bloom::BloomFilter; @@ -339,8 +337,8 @@ pub enum StyleSharingResult<'ln> { /// is shareable at all. CannotShare(bool), /// The node's style can be shared. The integer specifies the index in the LRU cache that was - /// hit. - StyleWasShared(uint), + /// hit and the damage that was done. + StyleWasShared(uint, RestyleDamage), } pub trait MatchMethods { @@ -385,7 +383,8 @@ trait PrivateMatchMethods { style: &mut Option<Arc<ComputedValues>>, applicable_declarations_cache: &mut ApplicableDeclarationsCache, - shareable: bool) -> RestyleDamage; + shareable: bool) + -> RestyleDamage; fn share_style_with_candidate_if_possible(&self, parent_node: Option<LayoutNode>, @@ -400,7 +399,8 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { style: &mut Option<Arc<ComputedValues>>, applicable_declarations_cache: &mut ApplicableDeclarationsCache, - shareable: bool) -> RestyleDamage { + shareable: bool) + -> RestyleDamage { let this_style; let cacheable; match parent_style { @@ -432,9 +432,10 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> { applicable_declarations_cache.insert(applicable_declarations, this_style.clone()); } - let ret = incremental::compute_damage(&*style, this_style.deref()); + // Calculate style difference and write. + let damage = incremental::compute_damage(style, &*this_style); *style = Some(this_style); - ret + damage } @@ -526,12 +527,11 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { Some(shared_style) => { // Yay, cache hit. Share the style. let mut layout_data_ref = self.mutate_layout_data(); - let layout_data = layout_data_ref.as_mut().unwrap(); - let style = &mut layout_data.shared_data.style; - layout_data.data.restyle_damage.insert( - incremental::compute_damage(&*style, &*shared_style)); + let shared_data = &mut layout_data_ref.as_mut().unwrap().shared_data; + let style = &mut shared_data.style; + let damage = incremental::compute_damage(style, &*shared_style); *style = Some(shared_style); - return StyleWasShared(i) + return StyleWasShared(i, damage) } None => {} } @@ -585,8 +585,6 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { parent: Option<LayoutNode>, applicable_declarations: &ApplicableDeclarations, applicable_declarations_cache: &mut ApplicableDeclarationsCache) { - let mut restyle_damage = ThreadSafeLayoutNode::new(self).restyle_damage(); - // Get our parent's style. This must be unsafe so that we don't touch the parent's // borrow flags. // @@ -602,51 +600,46 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { } }; - - { - let mut layout_data_ref = self.mutate_layout_data(); - let layout_data = layout_data_ref.as_mut().expect("no layout_data"); - match self.type_id() { - Some(TextNodeTypeId) => { - // Text nodes get a copy of the parent style. This ensures - // that during fragment construction any non-inherited - // CSS properties (such as vertical-align) are correctly - // set on the fragment(s). - let cloned_parent_style = parent_style.unwrap().clone(); - restyle_damage.insert( - incremental::compute_damage(&layout_data.shared_data.style, &*cloned_parent_style)); - layout_data.shared_data.style = Some(cloned_parent_style); - } - _ => { - restyle_damage.insert( - self.cascade_node_pseudo_element( + let mut layout_data_ref = self.mutate_layout_data(); + match &mut *layout_data_ref { + &None => fail!("no layout data"), + &Some(ref mut layout_data) => { + match self.type_id() { + Some(TextNodeTypeId) => { + // Text nodes get a copy of the parent style. This ensures + // that during fragment construction any non-inherited + // CSS properties (such as vertical-align) are correctly + // set on the fragment(s). + let cloned_parent_style = parent_style.unwrap().clone(); + layout_data.shared_data.style = Some(cloned_parent_style); + } + _ => { + let mut damage = self.cascade_node_pseudo_element( parent_style, applicable_declarations.normal.as_slice(), &mut layout_data.shared_data.style, applicable_declarations_cache, - applicable_declarations.normal_shareable)); - if applicable_declarations.before.len() > 0 { - restyle_damage.insert( - self.cascade_node_pseudo_element( - Some(layout_data.shared_data.style.as_ref().unwrap()), - applicable_declarations.before.as_slice(), - &mut layout_data.data.before_style, - applicable_declarations_cache, - false)); - } - if applicable_declarations.after.len() > 0 { - restyle_damage.insert( - self.cascade_node_pseudo_element( + applicable_declarations.normal_shareable); + if applicable_declarations.before.len() > 0 { + damage = damage | self.cascade_node_pseudo_element( + Some(layout_data.shared_data.style.as_ref().unwrap()), + applicable_declarations.before.as_slice(), + &mut layout_data.data.before_style, + applicable_declarations_cache, + false); + } + if applicable_declarations.after.len() > 0 { + damage = damage | self.cascade_node_pseudo_element( Some(layout_data.shared_data.style.as_ref().unwrap()), applicable_declarations.after.as_slice(), &mut layout_data.data.after_style, applicable_declarations_cache, - false)); + false); + } + layout_data.data.restyle_damage = damage; } } } } - - ThreadSafeLayoutNode::new(self).set_restyle_damage(restyle_damage); } } diff --git a/components/layout/css/node_style.rs b/components/layout/css/node_style.rs index 35bb1b1a8fa..ecfb3383453 100644 --- a/components/layout/css/node_style.rs +++ b/components/layout/css/node_style.rs @@ -5,7 +5,6 @@ // Style retrieval from DOM elements. use css::node_util::NodeUtil; -use incremental::RestyleDamage; use wrapper::ThreadSafeLayoutNode; use style::ComputedValues; @@ -15,8 +14,6 @@ use sync::Arc; pub trait StyledNode { fn style<'a>(&'a self) -> &'a Arc<ComputedValues>; fn unstyle(self); - fn restyle_damage(self) -> RestyleDamage; - fn set_restyle_damage(self, damage: RestyleDamage); } impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> { @@ -28,15 +25,4 @@ impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> { fn unstyle(self) { self.remove_css_select_results() } - - fn restyle_damage(self) -> RestyleDamage { - self.get_restyle_damage() - } - - fn set_restyle_damage(self, damage: RestyleDamage) { - fn doit<N: NodeUtil>(n: N, damage: RestyleDamage) { - n.set_restyle_damage(damage); - } - doit(self, damage); - } } diff --git a/components/layout/css/node_util.rs b/components/layout/css/node_util.rs index 80144d50022..eb447b0cf6b 100644 --- a/components/layout/css/node_util.rs +++ b/components/layout/css/node_util.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use incremental::RestyleDamage; use util::LayoutDataAccess; use wrapper::ThreadSafeLayoutNode; use wrapper::{After, Before, Normal}; @@ -15,9 +14,6 @@ pub trait NodeUtil { fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues>; fn have_css_select_results(&self) -> bool; fn remove_css_select_results(self); - - fn get_restyle_damage(self) -> RestyleDamage; - fn set_restyle_damage(self, damage: RestyleDamage); } impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { @@ -75,23 +71,5 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> { *style = None; } - - /// Get the description of how to account for recent style changes. - /// This is a simple bitfield and fine to copy by value. - fn get_restyle_damage(self) -> RestyleDamage { - let layout_data_ref = self.borrow_layout_data(); - layout_data_ref - .as_ref().unwrap() - .data - .restyle_damage - } - - /// Set the restyle damage field. - fn set_restyle_damage(self, damage: RestyleDamage) { - let mut layout_data_ref = self.mutate_layout_data(); - match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.restyle_damage = damage, - _ => fail!("no layout data for this node"), - } - } } + |