mirror of
https://github.com/servo/servo.git
synced 2025-06-10 09:33:13 +00:00
layout: Make incremental reflow more fine-grained by introducing "reflow
out-of-flow" and "reconstruct flow" damage bits. This is needed for good performance on the maze solver.
This commit is contained in:
parent
7712052e13
commit
08fc7c2795
20 changed files with 644 additions and 403 deletions
|
@ -27,7 +27,7 @@ use fragment::{InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragment};
|
|||
use fragment::{InlineBlockFragmentInfo, InputFragment, SpecificFragmentInfo, TableCellFragment};
|
||||
use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment};
|
||||
use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
|
||||
use incremental::RestyleDamage;
|
||||
use incremental::{ReconstructFlow, RestyleDamage};
|
||||
use inline::InlineFlow;
|
||||
use parallel;
|
||||
use table_wrapper::TableWrapperFlow;
|
||||
|
@ -38,7 +38,7 @@ use table_rowgroup::TableRowGroupFlow;
|
|||
use table_row::TableRowFlow;
|
||||
use table_cell::TableCellFlow;
|
||||
use text::TextRunScanner;
|
||||
use util::{LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
|
||||
use util::{HasNewlyConstructedFlow, LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
|
||||
use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
|
||||
use wrapper::{Before, After, Normal};
|
||||
|
||||
|
@ -942,6 +942,44 @@ impl<'a> FlowConstructor<'a> {
|
|||
|
||||
FlowConstructionResult(flow, Descendants::new())
|
||||
}
|
||||
|
||||
/// Attempts to perform incremental repair to account for recent changes to this node. This
|
||||
/// can fail and return false, indicating that flows will need to be reconstructed.
|
||||
///
|
||||
/// TODO(pcwalton): Add some more fast paths, like toggling `display: none`, adding block kids
|
||||
/// to block parents with no {ib} splits, adding out-of-flow kids, etc.
|
||||
pub fn repair_if_possible(&mut self, node: &ThreadSafeLayoutNode) -> bool {
|
||||
// We can skip reconstructing the flow if we don't have to reconstruct and none of our kids
|
||||
// did either.
|
||||
if node.restyle_damage().contains(ReconstructFlow) {
|
||||
return false
|
||||
}
|
||||
|
||||
let mut need_to_reconstruct = false;
|
||||
for kid in node.children() {
|
||||
if kid.flags().contains(HasNewlyConstructedFlow) {
|
||||
kid.remove_flags(HasNewlyConstructedFlow);
|
||||
need_to_reconstruct = true
|
||||
}
|
||||
}
|
||||
if need_to_reconstruct {
|
||||
return false
|
||||
}
|
||||
|
||||
match node.swap_out_construction_result() {
|
||||
NoConstructionResult => true,
|
||||
FlowConstructionResult(mut flow, _) => {
|
||||
// The node's flow is of the same type and has the same set of children and can
|
||||
// therefore be repaired by simply propagating damage and style to the flow.
|
||||
flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage());
|
||||
flow.repair_style(node.style());
|
||||
true
|
||||
}
|
||||
ConstructionItemConstructionResult(_) => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
||||
|
@ -1088,6 +1126,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
node.insert_flags(HasNewlyConstructedFlow);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue