content, layout: Very, very early beginnings of support for incremental reflow.

Don't perform CSS selector matching when the window is resized.
This commit is contained in:
Patrick Walton 2012-11-18 22:19:01 -08:00
parent c31bd43570
commit 1ddfc14881
2 changed files with 45 additions and 8 deletions

View file

@ -9,7 +9,8 @@ use dom::node::{Node, NodeScope, define_bindings};
use dom::event::{Event, ResizeEvent, ReflowEvent};
use dom::window::Window;
use layout::layout_task;
use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, LayoutTask};
use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, Damage, LayoutTask};
use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage};
use core::comm::{Port, Chan, listen, select2};
use core::either;
@ -96,6 +97,9 @@ pub struct Content {
resource_task: ResourceTask,
compartment: Option<compartment>,
// What parts of layout are dirty.
mut damage: Damage,
}
fn Content(layout_task: LayoutTask,
@ -136,7 +140,9 @@ fn Content(layout_task: LayoutTask,
window_size : Size2D(800u, 600u),
resource_task : resource_task,
compartment : compartment
compartment : compartment,
damage : MatchSelectorsDamage,
};
cx.set_cx_private(ptr::to_unsafe_ptr(&*content) as *());
@ -196,7 +202,10 @@ impl Content {
let document = Document(root, self.scope);
let window = Window(self.control_chan.clone());
self.damage.add(MatchSelectorsDamage);
self.relayout(&document, &url);
self.document = Some(@move document);
self.window = Some(@move window);
self.doc_url = Some(move url);
@ -302,7 +311,8 @@ impl Content {
url: copy *doc_url,
dom_event_chan: self.event_chan.clone(),
window_size: self.window_size,
content_join_chan: move join_chan
content_join_chan: move join_chan,
damage: replace(&mut self.damage, NoDamage),
};
self.layout_task.send(BuildMsg(move data));
@ -331,6 +341,7 @@ impl Content {
match event {
ResizeEvent(new_width, new_height, response_chan) => {
debug!("content got resize event: %u, %u", new_width, new_height);
self.damage.add(ReflowDamage);
self.window_size = Size2D(new_width, new_height);
match copy self.document {
None => {
@ -346,6 +357,7 @@ impl Content {
}
ReflowEvent => {
debug!("content got reflow event");
self.damage.add(MatchSelectorsDamage);
match copy self.document {
None => {
// Nothing to do.

View file

@ -57,12 +57,31 @@ pub enum Msg {
ExitMsg
}
// Dirty bits for layout.
pub enum Damage {
NoDamage, // Document is clean; do nothing.
ReflowDamage, // Reflow; don't perform CSS selector matching.
MatchSelectorsDamage, // Perform CSS selector matching and reflow.
}
impl Damage {
fn add(&mut self, new_damage: Damage) {
match (*self, new_damage) {
(NoDamage, _) => *self = new_damage,
(ReflowDamage, NoDamage) => *self = ReflowDamage,
(ReflowDamage, new_damage) => *self = new_damage,
(MatchSelectorsDamage, _) => *self = MatchSelectorsDamage
}
}
}
struct BuildData {
node: Node,
url: Url,
dom_event_chan: pipes::SharedChan<Event>,
window_size: Size2D<uint>,
content_join_chan: pipes::Chan<()>
content_join_chan: pipes::Chan<()>,
damage: Damage,
}
fn LayoutTask(render_task: RenderTask,
@ -147,7 +166,6 @@ impl Layout {
}
fn handle_build(data: BuildData) {
let node = &data.node;
// FIXME: Bad copy
let doc_url = copy data.url;
@ -155,6 +173,7 @@ impl Layout {
let dom_event_chan = data.dom_event_chan.clone();
debug!("layout: received layout request for: %s", doc_url.to_str());
debug!("layout: damage is %?", data.damage);
debug!("layout: parsed Node tree");
debug!("%?", node.dump());
@ -176,9 +195,15 @@ impl Layout {
node.initialize_style_for_subtree(&self.layout_refs);
}
do time("layout: selector matching") {
do self.css_select_ctx.borrow_imm |ctx| {
node.restyle_subtree(ctx);
// Perform CSS selector matching if necessary.
match data.damage {
NoDamage | ReflowDamage => {}
MatchSelectorsDamage => {
do time("layout: selector matching") {
do self.css_select_ctx.borrow_imm |ctx| {
node.restyle_subtree(ctx);
}
}
}
}