aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/main/css/matching.rs45
-rw-r--r--src/components/main/layout/layout_task.rs13
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);
}
}