diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/main/css/matching.rs | 45 | ||||
-rw-r--r-- | src/components/main/layout/layout_task.rs | 13 |
2 files changed, 47 insertions, 11 deletions
diff --git a/src/components/main/css/matching.rs b/src/components/main/css/matching.rs index c777a676505..f7da616f19e 100644 --- a/src/components/main/css/matching.rs +++ b/src/components/main/css/matching.rs @@ -5,6 +5,12 @@ // High-level interface to CSS selector matching. use std::cell::Cell; +use std::comm; +use std::rt::default_sched_threads; +use std::task; +use std::vec; +use extra::arc::RWArc; + use css::node_style::StyledNode; use css::node_util::NodeUtil; use layout::incremental; @@ -16,7 +22,7 @@ use servo_util::tree::TreeNodeRef; pub trait MatchMethods { fn match_node(&self, stylist: &Stylist); - fn match_subtree(&self, stylist: &Stylist); + fn match_subtree(&self, stylist: RWArc<Stylist>); fn cascade_node(&self, parent: Option<AbstractNode<LayoutView>>); fn cascade_subtree(&self, parent: Option<AbstractNode<LayoutView>>); @@ -36,14 +42,41 @@ impl MatchMethods for AbstractNode<LayoutView> { data.applicable_declarations = cell.take(); } } - fn match_subtree(&self, stylist: &Stylist) { - self.match_node(stylist); + fn match_subtree(&self, stylist: RWArc<Stylist>) { + let num_tasks = default_sched_threads() * 2; + let mut node_count = 0; + let mut nodes_per_task = vec::from_elem(num_tasks, ~[]); - for kid in self.children() { - if kid.is_element() { - kid.match_subtree(stylist); + for node in self.traverse_preorder() { + if node.is_element() { + nodes_per_task[node_count % num_tasks].push(node); + node_count += 1; + } + } + + let (port, chan) = comm::stream(); + let chan = comm::SharedChan::new(chan); + let mut num_spawned = 0; + + for nodes in nodes_per_task.move_iter() { + if nodes.len() > 0 { + let chan = chan.clone(); + let stylist = stylist.clone(); + do task::spawn_with((nodes, stylist)) |(nodes, stylist)| { + let nodes = Cell::new(nodes); + do stylist.read |stylist| { + for node in nodes.take().move_iter() { + node.match_node(stylist); + } + } + chan.send(()); + } + num_spawned += 1; } } + for _ in range(0, num_spawned) { + port.recv(); + } } fn cascade_node(&self, parent: Option<AbstractNode<LayoutView>>) { diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index a894ffc3896..a0a2161e2da 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -20,7 +20,7 @@ use std::cast::transmute; use std::cell::Cell; use std::comm::{Port}; use std::task; -use extra::arc::Arc; +use extra::arc::{Arc, RWArc}; use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; @@ -65,7 +65,7 @@ struct LayoutTask { display_list: Option<Arc<DisplayList<AbstractNode<()>>>>, - stylist: Stylist, + stylist: RWArc<Stylist>, profiler_chan: ProfilerChan, } @@ -241,7 +241,7 @@ impl LayoutTask { display_list: None, - stylist: new_stylist(), + stylist: RWArc::new(new_stylist()), profiler_chan: profiler_chan, } } @@ -294,7 +294,10 @@ impl LayoutTask { } fn handle_add_stylesheet(&mut self, sheet: Stylesheet) { - self.stylist.add_stylesheet(sheet, AuthorOrigin); + let sheet = Cell::new(sheet); + do self.stylist.write |stylist| { + stylist.add_stylesheet(sheet.take(), AuthorOrigin) + } } /// Performs layout constraint solving. @@ -359,7 +362,7 @@ impl LayoutTask { ReflowDocumentDamage => {} MatchSelectorsDocumentDamage => { do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) { - node.match_subtree(&self.stylist); + node.match_subtree(self.stylist.clone()); node.cascade_subtree(None); } } |