mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
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:
parent
c31bd43570
commit
1ddfc14881
2 changed files with 45 additions and 8 deletions
|
@ -9,7 +9,8 @@ use dom::node::{Node, NodeScope, define_bindings};
|
||||||
use dom::event::{Event, ResizeEvent, ReflowEvent};
|
use dom::event::{Event, ResizeEvent, ReflowEvent};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use layout::layout_task;
|
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::comm::{Port, Chan, listen, select2};
|
||||||
use core::either;
|
use core::either;
|
||||||
|
@ -96,6 +97,9 @@ pub struct Content {
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
|
|
||||||
compartment: Option<compartment>,
|
compartment: Option<compartment>,
|
||||||
|
|
||||||
|
// What parts of layout are dirty.
|
||||||
|
mut damage: Damage,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Content(layout_task: LayoutTask,
|
fn Content(layout_task: LayoutTask,
|
||||||
|
@ -136,7 +140,9 @@ fn Content(layout_task: LayoutTask,
|
||||||
window_size : Size2D(800u, 600u),
|
window_size : Size2D(800u, 600u),
|
||||||
|
|
||||||
resource_task : resource_task,
|
resource_task : resource_task,
|
||||||
compartment : compartment
|
compartment : compartment,
|
||||||
|
|
||||||
|
damage : MatchSelectorsDamage,
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.set_cx_private(ptr::to_unsafe_ptr(&*content) as *());
|
cx.set_cx_private(ptr::to_unsafe_ptr(&*content) as *());
|
||||||
|
@ -196,7 +202,10 @@ impl Content {
|
||||||
|
|
||||||
let document = Document(root, self.scope);
|
let document = Document(root, self.scope);
|
||||||
let window = Window(self.control_chan.clone());
|
let window = Window(self.control_chan.clone());
|
||||||
|
|
||||||
|
self.damage.add(MatchSelectorsDamage);
|
||||||
self.relayout(&document, &url);
|
self.relayout(&document, &url);
|
||||||
|
|
||||||
self.document = Some(@move document);
|
self.document = Some(@move document);
|
||||||
self.window = Some(@move window);
|
self.window = Some(@move window);
|
||||||
self.doc_url = Some(move url);
|
self.doc_url = Some(move url);
|
||||||
|
@ -302,7 +311,8 @@ impl Content {
|
||||||
url: copy *doc_url,
|
url: copy *doc_url,
|
||||||
dom_event_chan: self.event_chan.clone(),
|
dom_event_chan: self.event_chan.clone(),
|
||||||
window_size: self.window_size,
|
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));
|
self.layout_task.send(BuildMsg(move data));
|
||||||
|
@ -331,6 +341,7 @@ impl Content {
|
||||||
match event {
|
match event {
|
||||||
ResizeEvent(new_width, new_height, response_chan) => {
|
ResizeEvent(new_width, new_height, response_chan) => {
|
||||||
debug!("content got resize event: %u, %u", new_width, new_height);
|
debug!("content got resize event: %u, %u", new_width, new_height);
|
||||||
|
self.damage.add(ReflowDamage);
|
||||||
self.window_size = Size2D(new_width, new_height);
|
self.window_size = Size2D(new_width, new_height);
|
||||||
match copy self.document {
|
match copy self.document {
|
||||||
None => {
|
None => {
|
||||||
|
@ -346,6 +357,7 @@ impl Content {
|
||||||
}
|
}
|
||||||
ReflowEvent => {
|
ReflowEvent => {
|
||||||
debug!("content got reflow event");
|
debug!("content got reflow event");
|
||||||
|
self.damage.add(MatchSelectorsDamage);
|
||||||
match copy self.document {
|
match copy self.document {
|
||||||
None => {
|
None => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
|
|
@ -57,12 +57,31 @@ pub enum Msg {
|
||||||
ExitMsg
|
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 {
|
struct BuildData {
|
||||||
node: Node,
|
node: Node,
|
||||||
url: Url,
|
url: Url,
|
||||||
dom_event_chan: pipes::SharedChan<Event>,
|
dom_event_chan: pipes::SharedChan<Event>,
|
||||||
window_size: Size2D<uint>,
|
window_size: Size2D<uint>,
|
||||||
content_join_chan: pipes::Chan<()>
|
content_join_chan: pipes::Chan<()>,
|
||||||
|
damage: Damage,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn LayoutTask(render_task: RenderTask,
|
fn LayoutTask(render_task: RenderTask,
|
||||||
|
@ -147,7 +166,6 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_build(data: BuildData) {
|
fn handle_build(data: BuildData) {
|
||||||
|
|
||||||
let node = &data.node;
|
let node = &data.node;
|
||||||
// FIXME: Bad copy
|
// FIXME: Bad copy
|
||||||
let doc_url = copy data.url;
|
let doc_url = copy data.url;
|
||||||
|
@ -155,6 +173,7 @@ impl Layout {
|
||||||
let dom_event_chan = data.dom_event_chan.clone();
|
let dom_event_chan = data.dom_event_chan.clone();
|
||||||
|
|
||||||
debug!("layout: received layout request for: %s", doc_url.to_str());
|
debug!("layout: received layout request for: %s", doc_url.to_str());
|
||||||
|
debug!("layout: damage is %?", data.damage);
|
||||||
debug!("layout: parsed Node tree");
|
debug!("layout: parsed Node tree");
|
||||||
debug!("%?", node.dump());
|
debug!("%?", node.dump());
|
||||||
|
|
||||||
|
@ -176,9 +195,15 @@ impl Layout {
|
||||||
node.initialize_style_for_subtree(&self.layout_refs);
|
node.initialize_style_for_subtree(&self.layout_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
do time("layout: selector matching") {
|
// Perform CSS selector matching if necessary.
|
||||||
do self.css_select_ctx.borrow_imm |ctx| {
|
match data.damage {
|
||||||
node.restyle_subtree(ctx);
|
NoDamage | ReflowDamage => {}
|
||||||
|
MatchSelectorsDamage => {
|
||||||
|
do time("layout: selector matching") {
|
||||||
|
do self.css_select_ctx.borrow_imm |ctx| {
|
||||||
|
node.restyle_subtree(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue