aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/sequential.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2016-03-18 15:23:08 -0700
committerPatrick Walton <pcwalton@mimiga.net>2016-03-25 18:39:16 -0700
commitb29719e36bdf2867b1391bbc3b017675975e27ae (patch)
treed45bd79776dc8c60df8868627e4c7c73bd8c2f26 /components/layout/sequential.rs
parent9b2ae3a62faafceb3149dc455fc6123de2b306f7 (diff)
downloadservo-b29719e36bdf2867b1391bbc3b017675975e27ae.tar.gz
servo-b29719e36bdf2867b1391bbc3b017675975e27ae.zip
layout: Rewrite the block formatting context/float inline-size
speculation code. The old code tried to do the speculation as a single bottom-up pass after intrinsic inline-size calculation, which was unable to handle cases like this: <div> <div style="float: left">Foo</div> </div> <div> <div style="overflow: hidden">Bar</div> </div> No single bottom-up pass could possibly handle this case, because the inline-size of the float flowing out of the "Foo" block could never make it down to the "Bar" block, where it is needed for speculation. On the pages I tried, this regresses layout performance by 1%-2%. I first noticed this breaking some pages, like the Google SERPs, several months ago.
Diffstat (limited to 'components/layout/sequential.rs')
-rw-r--r--components/layout/sequential.rs26
1 files changed, 23 insertions, 3 deletions
diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs
index dbf469db082..f63e2a8bfcd 100644
--- a/components/layout/sequential.rs
+++ b/components/layout/sequential.rs
@@ -8,17 +8,18 @@ use app_units::Au;
use context::{LayoutContext, SharedLayoutContext};
use display_list_builder::DisplayListBuildState;
use euclid::point::Point2D;
+use floats::SpeculatedFloatPlacement;
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
use flow_ref::{self, FlowRef};
use fragment::FragmentBorderBoxIterator;
use generated_content::ResolveGeneratedContent;
use gfx::display_list::{DisplayListEntry, StackingContext};
-use incremental::STORE_OVERFLOW;
+use incremental::{REFLOW, STORE_OVERFLOW};
use style::dom::TNode;
use style::traversal::DomTraversalContext;
-use traversal::{AssignBSizes, AssignISizes};
-use traversal::{BubbleISizes, BuildDisplayList, ComputeAbsolutePositions, PostorderNodeMutTraversal};
+use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
+use traversal::{ComputeAbsolutePositions, PostorderNodeMutTraversal};
use util::opts;
pub use style::sequential::traverse_dom;
@@ -133,3 +134,22 @@ pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
flow::mut_base(flow).restyle_damage.remove(STORE_OVERFLOW);
}
+/// Guesses how much inline size will be taken up by floats on the left and right sides of the
+/// given flow. This is needed to speculatively calculate the inline sizes of block formatting
+/// contexts. The speculation typically succeeds, but if it doesn't we have to lay it out again.
+pub fn guess_float_placement(flow: &mut Flow) {
+ if !flow::base(flow).restyle_damage.intersects(REFLOW) {
+ return
+ }
+
+ let mut floats_in = SpeculatedFloatPlacement::compute_floats_in_for_first_child(flow);
+ for kid in flow::mut_base(flow).child_iter() {
+ floats_in.compute_floats_in(kid);
+ flow::mut_base(kid).speculated_float_placement_in = floats_in;
+ guess_float_placement(kid);
+ floats_in = flow::base(kid).speculated_float_placement_out;
+ }
+ floats_in.compute_floats_out(flow);
+ flow::mut_base(flow).speculated_float_placement_out = floats_in
+}
+