Skip to content

Commit

Permalink
auto merge of #3860 : pcwalton/servo/reflow-out-of-flow, r=glennw
Browse files Browse the repository at this point in the history
This is the last PR and most of the work for the maze solver and RoboHornet. 

r? @glennw 
cc @cgaebel
  • Loading branch information
bors-servo committed Oct 31, 2014
2 parents 4418a28 + 08fc7c2 commit 035ff19
Show file tree
Hide file tree
Showing 21 changed files with 655 additions and 388 deletions.
432 changes: 251 additions & 181 deletions components/layout/block.rs

Large diffs are not rendered by default.

43 changes: 41 additions & 2 deletions components/layout/construct.rs
Expand Up @@ -27,7 +27,7 @@ use fragment::{InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragment};
use fragment::{InlineBlockFragmentInfo, InputFragment, SpecificFragmentInfo, TableCellFragment};
use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment};
use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
use incremental::RestyleDamage;
use incremental::{ReconstructFlow, RestyleDamage};
use inline::InlineFlow;
use parallel;
use table_wrapper::TableWrapperFlow;
Expand All @@ -38,7 +38,7 @@ use table_rowgroup::TableRowGroupFlow;
use table_row::TableRowFlow;
use table_cell::TableCellFlow;
use text::TextRunScanner;
use util::{LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
use util::{HasNewlyConstructedFlow, LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
use wrapper::{Before, After, Normal};

Expand Down Expand Up @@ -942,6 +942,44 @@ impl<'a> FlowConstructor<'a> {

FlowConstructionResult(flow, Descendants::new())
}

/// Attempts to perform incremental repair to account for recent changes to this node. This
/// can fail and return false, indicating that flows will need to be reconstructed.
///
/// TODO(pcwalton): Add some more fast paths, like toggling `display: none`, adding block kids
/// to block parents with no {ib} splits, adding out-of-flow kids, etc.
pub fn repair_if_possible(&mut self, node: &ThreadSafeLayoutNode) -> bool {
// We can skip reconstructing the flow if we don't have to reconstruct and none of our kids
// did either.
if node.restyle_damage().contains(ReconstructFlow) {
return false
}

let mut need_to_reconstruct = false;
for kid in node.children() {
if kid.flags().contains(HasNewlyConstructedFlow) {
kid.remove_flags(HasNewlyConstructedFlow);
need_to_reconstruct = true
}
}
if need_to_reconstruct {
return false
}

match node.swap_out_construction_result() {
NoConstructionResult => true,
FlowConstructionResult(mut flow, _) => {
// The node's flow is of the same type and has the same set of children and can
// therefore be repaired by simply propagating damage and style to the flow.
flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage());
flow.repair_style(node.style());
true
}
ConstructionItemConstructionResult(_) => {
false
}
}
}
}

impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
Expand Down Expand Up @@ -1088,6 +1126,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
}
}

node.insert_flags(HasNewlyConstructedFlow);
true
}
}
Expand Down
95 changes: 44 additions & 51 deletions components/layout/css/matching.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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>,
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}


Expand Down Expand Up @@ -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 => {}
}
Expand Down Expand Up @@ -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.
//
Expand All @@ -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);
}
}
14 changes: 0 additions & 14 deletions components/layout/css/node_style.rs
Expand Up @@ -5,7 +5,6 @@
// Style retrieval from DOM elements.

use css::node_util::NodeUtil;
use incremental::RestyleDamage;
use wrapper::ThreadSafeLayoutNode;

use style::ComputedValues;
Expand All @@ -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> {
Expand All @@ -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);
}
}
24 changes: 1 addition & 23 deletions components/layout/css/node_util.rs
Expand Up @@ -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};
Expand All @@ -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> {
Expand Down Expand Up @@ -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"),
}
}
}

0 comments on commit 035ff19

Please sign in to comment.