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.
This commit is contained in:
Patrick Walton 2016-03-18 15:23:08 -07:00
parent 9b2ae3a62f
commit b29719e36b
15 changed files with 346 additions and 184 deletions

View file

@ -20,8 +20,7 @@ use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use model::MaybeAuto;
@ -336,11 +335,6 @@ impl Flow for TableWrapperFlow {
}
}).collect::<Vec<_>>();
// Table wrappers are essentially block formatting contexts and are therefore never
// impacted by floats.
self.block_flow.base.flags.remove(IMPACTED_BY_LEFT_FLOATS);
self.block_flow.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS);
// Our inline-size was set to the inline-size of the containing block by the flow's parent.
// Now compute the real value.
let containing_block_inline_size = self.block_flow.base.block_container_inline_size;