зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #3715 - Fixes the table_percentage_width_a.html reftest with incremental reflow turned on (from cgaebel:fix-table-percentage-width); r=pcwalton
This also enables incremental reflow by default. \o/ r? @pcwalton Source-Repo: https://github.com/servo/servo Source-Revision: f6941b35e3b945f4a6dcd2cf03daa345ad2bcaed
This commit is contained in:
Родитель
feabe3b678
Коммит
81a95caa86
|
@ -1592,12 +1592,13 @@ impl Flow for BlockFlow {
|
|||
"block"
|
||||
});
|
||||
|
||||
self.base.floats = Floats::new(self.base.writing_mode);
|
||||
|
||||
if self.is_root() {
|
||||
debug!("Setting root position");
|
||||
self.base.position.start = LogicalPoint::zero(self.base.writing_mode);
|
||||
self.base.block_container_inline_size = LogicalSize::from_physical(
|
||||
self.base.writing_mode, layout_context.shared.screen_size).inline;
|
||||
self.base.floats = Floats::new(self.base.writing_mode);
|
||||
|
||||
// The root element is never impacted by floats.
|
||||
self.base.flags.set_impacted_by_left_floats(false);
|
||||
|
@ -1847,6 +1848,7 @@ impl fmt::Show for BlockFlow {
|
|||
}
|
||||
|
||||
/// The inputs for the inline-sizes-and-margins constraint equation.
|
||||
#[deriving(Show)]
|
||||
pub struct ISizeConstraintInput {
|
||||
pub computed_inline_size: MaybeAuto,
|
||||
pub inline_start_margin: MaybeAuto,
|
||||
|
|
|
@ -10,12 +10,6 @@
|
|||
//! intermediate data that goes with a DOM node and hasn't found its "home" yet-maybe it's a box,
|
||||
//! maybe it's an absolute or fixed position thing that hasn't found its containing block yet.
|
||||
//! Construction items bubble up the tree from children to parents until they find their homes.
|
||||
//!
|
||||
//! TODO(pcwalton): There is no incremental reflow yet. This scheme requires that nodes either have
|
||||
//! weak references to flows or that there be some mechanism to efficiently (O(1) time) "blow
|
||||
//! apart" a flow tree and have the flows migrate "home" to their respective DOM nodes while we
|
||||
//! perform flow tree construction. The precise mechanism for this will take some experimentation
|
||||
//! to get right.
|
||||
|
||||
#![deny(unsafe_block)]
|
||||
|
||||
|
@ -85,11 +79,11 @@ pub enum ConstructionResult {
|
|||
|
||||
impl ConstructionResult {
|
||||
pub fn swap_out(&mut self) -> ConstructionResult {
|
||||
if opts::get().incremental_layout {
|
||||
return (*self).clone();
|
||||
if opts::get().nonincremental_layout {
|
||||
return mem::replace(self, NoConstructionResult)
|
||||
}
|
||||
|
||||
mem::replace(self, NoConstructionResult)
|
||||
(*self).clone()
|
||||
}
|
||||
|
||||
pub fn debug_id(&self) -> uint {
|
||||
|
|
|
@ -32,7 +32,7 @@ use floats::Floats;
|
|||
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
|
||||
use flow_ref::FlowRef;
|
||||
use fragment::{Fragment, TableRowFragment, TableCellFragment};
|
||||
use incremental::{RestyleDamage, Reflow};
|
||||
use incremental::RestyleDamage;
|
||||
use inline::InlineFlow;
|
||||
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
|
||||
use parallel::FlowParallelInfo;
|
||||
|
@ -435,10 +435,6 @@ pub trait MutableFlowUtils {
|
|||
fn collect_static_block_offsets_from_children(self);
|
||||
|
||||
fn propagate_restyle_damage(self);
|
||||
|
||||
/// At the moment, reflow isn't idempotent. This function resets this flow
|
||||
/// (and all its descendants, recursively), and marks them as needing reflow.
|
||||
fn nonincremental_reset(self);
|
||||
}
|
||||
|
||||
pub trait MutableOwnedFlowUtils {
|
||||
|
@ -1219,34 +1215,6 @@ impl<'a> MutableFlowUtils for &'a mut Flow + 'a {
|
|||
|
||||
doit(self, RestyleDamage::empty(), &mut DirtyFloats { left: false, right: false });
|
||||
}
|
||||
|
||||
fn nonincremental_reset(self) {
|
||||
fn reset_flow(flow: &mut Flow) {
|
||||
let base = mut_base(flow);
|
||||
|
||||
if !base.restyle_damage.contains(Reflow) {
|
||||
return
|
||||
}
|
||||
|
||||
let writing_mode = base.writing_mode;
|
||||
|
||||
base.position = LogicalRect::zero(writing_mode);
|
||||
base.overflow = LogicalRect::zero(writing_mode);
|
||||
base.floats = Floats::new(writing_mode);
|
||||
base.collapsible_margins = CollapsibleMargins::new();
|
||||
base.abs_position = Zero::zero();
|
||||
base.block_container_explicit_block_size = None;
|
||||
base.display_list = DisplayList::new();
|
||||
base.layers = DList::new();
|
||||
base.absolute_position_info = AbsolutePositionInfo::new(writing_mode);
|
||||
}
|
||||
|
||||
reset_flow(self);
|
||||
|
||||
for child in child_iter(self) {
|
||||
child.nonincremental_reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MutableOwnedFlowUtils for FlowRef {
|
||||
|
|
|
@ -630,15 +630,6 @@ impl LayoutTask {
|
|||
layout_root.propagate_restyle_damage();
|
||||
});
|
||||
|
||||
profile(time::LayoutNonIncrementalReset,
|
||||
Some((&data.url, data.iframe, self.first_reflow.get())),
|
||||
self.time_profiler_chan.clone(),
|
||||
|| {
|
||||
if opts::get().incremental_layout {
|
||||
layout_root.nonincremental_reset();
|
||||
}
|
||||
});
|
||||
|
||||
// Verification of the flow tree, which ensures that all nodes were either marked as leaves
|
||||
// or as non-leaves. This becomes a no-op in release builds. (It is inconsequential to
|
||||
// memory safety but is a useful debugging tool.)
|
||||
|
@ -665,10 +656,6 @@ impl LayoutTask {
|
|||
}
|
||||
});
|
||||
|
||||
if opts::get().dump_flow_tree {
|
||||
layout_root.dump();
|
||||
}
|
||||
|
||||
// Build the display list if necessary, and send it to the renderer.
|
||||
if data.goal == ReflowForDisplay {
|
||||
let writing_mode = flow::base(layout_root.deref()).writing_mode;
|
||||
|
@ -784,7 +771,9 @@ impl LayoutTask {
|
|||
}
|
||||
|
||||
unsafe fn dirty_all_nodes(node: &mut LayoutNode) {
|
||||
node.set_changed(true);
|
||||
// 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);
|
||||
|
|
|
@ -322,7 +322,7 @@ impl IntrinsicISizesContribution {
|
|||
}
|
||||
|
||||
/// Useful helper data type when computing values for blocks and positioned elements.
|
||||
#[deriving(PartialEq)]
|
||||
#[deriving(PartialEq, Show)]
|
||||
pub enum MaybeAuto {
|
||||
Auto,
|
||||
Specified(Au),
|
||||
|
@ -388,4 +388,3 @@ pub fn padding_from_style(style: &ComputedValues, containing_block_inline_size:
|
|||
specified(padding_style.padding_bottom, containing_block_inline_size),
|
||||
specified(padding_style.padding_left, containing_block_inline_size)))
|
||||
}
|
||||
|
||||
|
|
|
@ -252,6 +252,7 @@ impl Flow for TableFlow {
|
|||
}
|
||||
|
||||
let inline_size_computer = InternalTable;
|
||||
|
||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||
layout_context,
|
||||
containing_block_inline_size);
|
||||
|
@ -260,6 +261,7 @@ impl Flow for TableFlow {
|
|||
let padding_and_borders = self.block_flow.fragment.border_padding.inline_start_end();
|
||||
let content_inline_size =
|
||||
self.block_flow.fragment.border_box.size.inline - padding_and_borders;
|
||||
|
||||
match self.table_layout {
|
||||
FixedLayout => {
|
||||
// In fixed table layout, we distribute extra space among the unspecified columns
|
||||
|
@ -346,6 +348,7 @@ impl ISizeAndMarginsComputer for InternalTable {
|
|||
parent_flow_inline_size,
|
||||
ctx);
|
||||
let solution = self.solve_inline_size_constraints(block, &input);
|
||||
|
||||
self.set_inline_size_constraint_solutions(block, solution);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ impl Flow for TableCellFlow {
|
|||
let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
|
||||
|
||||
let inline_size_computer = InternalTable;
|
||||
|
||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||
ctx,
|
||||
containing_block_inline_size);
|
||||
|
|
|
@ -40,7 +40,13 @@ pub enum TableLayout {
|
|||
pub struct TableWrapperFlow {
|
||||
pub block_flow: BlockFlow,
|
||||
|
||||
/// Inline-size information for each column.
|
||||
/// Intrinsic column inline sizes according to INTRINSIC § 4.1
|
||||
pub intrinsic_column_inline_sizes: Vec<ColumnInlineSize>,
|
||||
|
||||
/// Computed inline-size for each column.
|
||||
///
|
||||
/// FIXME: This should be a separate type that only contains computed inline
|
||||
/// sizes.
|
||||
pub column_inline_sizes: Vec<ColumnInlineSize>,
|
||||
|
||||
/// Table-layout property
|
||||
|
@ -60,6 +66,7 @@ impl TableWrapperFlow {
|
|||
};
|
||||
TableWrapperFlow {
|
||||
block_flow: block_flow,
|
||||
intrinsic_column_inline_sizes: vec!(),
|
||||
column_inline_sizes: vec!(),
|
||||
table_layout: table_layout
|
||||
}
|
||||
|
@ -77,6 +84,7 @@ impl TableWrapperFlow {
|
|||
};
|
||||
TableWrapperFlow {
|
||||
block_flow: block_flow,
|
||||
intrinsic_column_inline_sizes: vec!(),
|
||||
column_inline_sizes: vec!(),
|
||||
table_layout: table_layout
|
||||
}
|
||||
|
@ -95,6 +103,7 @@ impl TableWrapperFlow {
|
|||
};
|
||||
TableWrapperFlow {
|
||||
block_flow: block_flow,
|
||||
intrinsic_column_inline_sizes: vec!(),
|
||||
column_inline_sizes: vec!(),
|
||||
table_layout: table_layout
|
||||
}
|
||||
|
@ -244,7 +253,7 @@ impl Flow for TableWrapperFlow {
|
|||
for kid in self.block_flow.base.child_iter() {
|
||||
debug_assert!(kid.is_table_caption() || kid.is_table());
|
||||
if kid.is_table() {
|
||||
self.column_inline_sizes = kid.column_inline_sizes().clone()
|
||||
self.intrinsic_column_inline_sizes = kid.column_inline_sizes().clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,6 +268,8 @@ impl Flow for TableWrapperFlow {
|
|||
"table_wrapper"
|
||||
});
|
||||
|
||||
self.column_inline_sizes = self.intrinsic_column_inline_sizes.clone();
|
||||
|
||||
// Table wrappers are essentially block formatting contexts and are therefore never
|
||||
// impacted by floats.
|
||||
self.block_flow.base.flags.set_impacted_by_left_floats(false);
|
||||
|
@ -293,6 +304,7 @@ impl Flow for TableWrapperFlow {
|
|||
self.block_flow.propagate_assigned_inline_size_to_children(inline_start_content_edge,
|
||||
content_inline_size,
|
||||
assigned_column_inline_sizes);
|
||||
|
||||
}
|
||||
|
||||
fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) {
|
||||
|
@ -564,4 +576,3 @@ impl ExcessInlineSizeDistributionInfo {
|
|||
amount_to_distribute
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use construct::FlowConstructor;
|
|||
use context::LayoutContext;
|
||||
use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
|
||||
use flow;
|
||||
use incremental::RestyleDamage;
|
||||
use incremental::{RestyleDamage, BubbleISizes, Reflow};
|
||||
use wrapper::{layout_node_to_unsafe_layout_node, LayoutNode};
|
||||
use wrapper::{PostorderNodeMutTraversal, ThreadSafeLayoutNode, UnsafeLayoutNode};
|
||||
use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
|
||||
|
@ -205,7 +205,7 @@ impl<'a> PostorderDomTraversal for ConstructFlows<'a> {
|
|||
let tnode = ThreadSafeLayoutNode::new(&node);
|
||||
|
||||
// Always re-construct if incremental layout is turned off.
|
||||
if !opts::get().incremental_layout {
|
||||
if opts::get().nonincremental_layout {
|
||||
unsafe {
|
||||
node.set_dirty_descendants(true);
|
||||
}
|
||||
|
@ -283,6 +283,11 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> {
|
|||
fn process(&self, flow: &mut Flow) {
|
||||
flow.bubble_inline_sizes();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn should_process(&self, flow: &mut Flow) -> bool {
|
||||
flow::base(flow).restyle_damage.contains(BubbleISizes)
|
||||
}
|
||||
}
|
||||
|
||||
/// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`.
|
||||
|
@ -295,6 +300,11 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> {
|
|||
fn process(&self, flow: &mut Flow) {
|
||||
flow.assign_inline_sizes(self.layout_context);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn should_process(&self, flow: &mut Flow) -> bool {
|
||||
flow::base(flow).restyle_damage.contains(Reflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// The assign-block-sizes-and-store-overflow traversal, the last (and most expensive) part of
|
||||
|
@ -318,7 +328,8 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {
|
|||
|
||||
#[inline]
|
||||
fn should_process(&self, flow: &mut Flow) -> bool {
|
||||
!flow::base(flow).flags.impacted_by_floats()
|
||||
let base = flow::base(flow);
|
||||
base.restyle_damage.contains(Reflow) && !base.flags.impacted_by_floats()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ pub struct Opts {
|
|||
/// sequential algorithm.
|
||||
pub layout_threads: uint,
|
||||
|
||||
pub incremental_layout: bool,
|
||||
pub nonincremental_layout: bool,
|
||||
|
||||
/// True to exit after the page load (`-x`).
|
||||
pub exit_after_load: bool,
|
||||
|
@ -132,7 +132,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
|
|||
getopts::optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10"),
|
||||
getopts::optflag("x", "exit", "Exit after load flag"),
|
||||
getopts::optopt("y", "layout-threads", "Number of threads to use for layout", "1"),
|
||||
getopts::optflag("i", "incremental-layout", "Whether or not to use incremental layout."),
|
||||
getopts::optflag("i", "nonincremental-layout", "Enable to turn off incremental layout."),
|
||||
getopts::optflag("z", "headless", "Headless mode"),
|
||||
getopts::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"),
|
||||
getopts::optflag("b", "bubble-widths", "Bubble intrinsic widths separately like other engines"),
|
||||
|
@ -196,7 +196,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
|
|||
None => cmp::max(rt::default_sched_threads() * 3 / 4, 1),
|
||||
};
|
||||
|
||||
let incremental_layout = opt_match.opt_present("i");
|
||||
let nonincremental_layout = opt_match.opt_present("i");
|
||||
|
||||
let mut bubble_inline_sizes_separately = opt_match.opt_present("b");
|
||||
|
||||
|
@ -231,7 +231,7 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
|
|||
memory_profiler_period: memory_profiler_period,
|
||||
enable_experimental: opt_match.opt_present("e"),
|
||||
layout_threads: layout_threads,
|
||||
incremental_layout: incremental_layout,
|
||||
nonincremental_layout: nonincremental_layout,
|
||||
exit_after_load: opt_match.opt_present("x"),
|
||||
output_file: opt_match.opt_str("o"),
|
||||
headless: opt_match.opt_present("z"),
|
||||
|
|
|
@ -59,7 +59,7 @@ pub extern "C" fn cef_run_message_loop() {
|
|||
memory_profiler_period: None,
|
||||
enable_experimental: false,
|
||||
layout_threads: 1,
|
||||
incremental_layout: false,
|
||||
nonincremental_layout: false,
|
||||
//layout_threads: cmp::max(rt::default_sched_threads() * 3 / 4, 1),
|
||||
exit_after_load: false,
|
||||
output_file: None,
|
||||
|
|
Загрузка…
Ссылка в новой задаче