servo: Merge #3826 - Layout: Fix resize (which just plain doesn't work right now) (from cgaebel:fix-resize); r=pcwalton

Currently, both restyle/flow construction _and_ reflow are skipped
during resize. Reflow should not be in that list. This patch fixes
that.

Source-Repo: https://github.com/servo/servo
Source-Revision: 3b6e035d0d5e4055adfdc396e322fab82759fe9e
This commit is contained in:
Clark Gaebel 2014-10-28 12:00:51 -06:00
Родитель 1df0853045
Коммит a7812bae62
1 изменённых файлов: 40 добавлений и 14 удалений

Просмотреть файл

@ -11,6 +11,7 @@ use context::SharedLayoutContext;
use flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
use flow;
use flow_ref::FlowRef;
use incremental::{Reflow, Repaint};
use layout_debug;
use parallel::UnsafeFlow;
use parallel;
@ -478,9 +479,13 @@ impl LayoutTask {
}
/// Retrieves the flow tree root from the root node.
fn get_layout_root(&self, node: LayoutNode) -> FlowRef {
fn try_get_layout_root(&self, node: LayoutNode) -> Option<FlowRef> {
let mut layout_data_ref = node.mutate_layout_data();
let layout_data = layout_data_ref.as_mut().expect("no layout data for root node");
let layout_data =
match layout_data_ref.as_mut() {
None => return None,
Some(layout_data) => layout_data,
};
let result = layout_data.data.flow_construction_result.swap_out();
@ -494,11 +499,16 @@ impl LayoutTask {
flow.set_absolute_descendants(abs_descendants);
flow
}
_ => fail!("Flow construction didn't result in a flow at the root of the tree!"),
_ => return None,
};
flow.mark_as_root();
flow
Some(flow)
}
fn get_layout_root(&self, node: LayoutNode) -> FlowRef {
self.try_get_layout_root(node).expect("no layout root")
}
/// Performs layout constraint solving.
@ -580,6 +590,7 @@ impl LayoutTask {
// http://www.w3.org/TR/css-device-adapt/#actual-viewport
let viewport_size = data.window_size.initial_viewport;
let old_screen_size = rw_data.screen_size;
let current_screen_size = Size2D(Au::from_frac32_px(viewport_size.width.get()),
Au::from_frac32_px(viewport_size.height.get()));
rw_data.screen_size = current_screen_size;
@ -592,8 +603,12 @@ impl LayoutTask {
&data.url);
// Handle conditions where the entire flow tree is invalid.
let mut needs_dirtying = false;
needs_dirtying |= rw_data.stylesheet_dirty;
let needs_dirtying = rw_data.stylesheet_dirty;
let mut needs_reflow = current_screen_size != old_screen_size;
// If the entire flow tree is invalid, then it will be reflowed anyhow.
needs_reflow &= !needs_dirtying;
unsafe {
if needs_dirtying {
@ -601,6 +616,11 @@ impl LayoutTask {
}
}
if needs_reflow {
self.try_get_layout_root(*node).map(
|mut flow| LayoutTask::reflow_all_nodes(flow.deref_mut()));
}
rw_data.stylesheet_dirty = false;
let mut layout_root = profile(time::LayoutStyleRecalcCategory,
@ -771,15 +791,21 @@ impl LayoutTask {
}
unsafe fn dirty_all_nodes(node: &mut LayoutNode) {
// TODO(cgaebel): mark nodes which are sensitive to media queries as
// "changed":
// > node.set_changed(true);
node.set_dirty(true);
node.set_dirty_siblings(true);
node.set_dirty_descendants(true);
for node in node.traverse_preorder() {
// TODO(cgaebel): mark nodes which are sensitive to media queries as
// "changed":
// > node.set_changed(true);
node.set_dirty(true);
node.set_dirty_siblings(true);
node.set_dirty_descendants(true);
}
}
for mut kid in node.children() {
LayoutTask::dirty_all_nodes(&mut kid);
fn reflow_all_nodes(flow: &mut Flow) {
flow::mut_base(flow).restyle_damage.insert(Reflow | Repaint);
for child in flow::child_iter(flow) {
LayoutTask::reflow_all_nodes(child);
}
}