mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
parallel selector matching
This commit is contained in:
parent
1a7e9e5e2c
commit
901dfc45e5
2 changed files with 47 additions and 11 deletions
|
@ -5,6 +5,12 @@
|
||||||
// High-level interface to CSS selector matching.
|
// High-level interface to CSS selector matching.
|
||||||
|
|
||||||
use std::cell::Cell;
|
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_style::StyledNode;
|
||||||
use css::node_util::NodeUtil;
|
use css::node_util::NodeUtil;
|
||||||
use layout::incremental;
|
use layout::incremental;
|
||||||
|
@ -16,7 +22,7 @@ use servo_util::tree::TreeNodeRef;
|
||||||
|
|
||||||
pub trait MatchMethods {
|
pub trait MatchMethods {
|
||||||
fn match_node(&self, stylist: &Stylist);
|
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_node(&self, parent: Option<AbstractNode<LayoutView>>);
|
||||||
fn cascade_subtree(&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();
|
data.applicable_declarations = cell.take();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn match_subtree(&self, stylist: &Stylist) {
|
fn match_subtree(&self, stylist: RWArc<Stylist>) {
|
||||||
self.match_node(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() {
|
for node in self.traverse_preorder() {
|
||||||
if kid.is_element() {
|
if node.is_element() {
|
||||||
kid.match_subtree(stylist);
|
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>>) {
|
fn cascade_node(&self, parent: Option<AbstractNode<LayoutView>>) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::cast::transmute;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::comm::{Port};
|
use std::comm::{Port};
|
||||||
use std::task;
|
use std::task;
|
||||||
use extra::arc::Arc;
|
use extra::arc::{Arc, RWArc};
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
|
@ -65,7 +65,7 @@ struct LayoutTask {
|
||||||
|
|
||||||
display_list: Option<Arc<DisplayList<AbstractNode<()>>>>,
|
display_list: Option<Arc<DisplayList<AbstractNode<()>>>>,
|
||||||
|
|
||||||
stylist: Stylist,
|
stylist: RWArc<Stylist>,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ impl LayoutTask {
|
||||||
|
|
||||||
display_list: None,
|
display_list: None,
|
||||||
|
|
||||||
stylist: new_stylist(),
|
stylist: RWArc::new(new_stylist()),
|
||||||
profiler_chan: profiler_chan,
|
profiler_chan: profiler_chan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,10 @@ impl LayoutTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_add_stylesheet(&mut self, sheet: Stylesheet) {
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The high-level routine that performs layout tasks.
|
/// The high-level routine that performs layout tasks.
|
||||||
|
@ -335,7 +338,7 @@ impl LayoutTask {
|
||||||
ReflowDocumentDamage => {}
|
ReflowDocumentDamage => {}
|
||||||
MatchSelectorsDocumentDamage => {
|
MatchSelectorsDocumentDamage => {
|
||||||
do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) {
|
do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) {
|
||||||
node.match_subtree(&self.stylist);
|
node.match_subtree(self.stylist.clone());
|
||||||
node.cascade_subtree(None);
|
node.cascade_subtree(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue