Title: [256099] trunk/Source/WebCore
Revision
256099
Author
[email protected]
Date
2020-02-08 19:45:11 -0800 (Sat, 08 Feb 2020)

Log Message

[LFC][BFC] Pre-compute vertical position only when we really need it.
https://bugs.webkit.org/show_bug.cgi?id=207432
<rdar://problem/59288539>

Reviewed by Antti Koivisto.

Instead of pre-computing the vertical position at computeStaticVerticalPosition, let's compute it when
1. we are about to layout a new non-float-avoider/float clear FC (e.g. so that intrusive floats can shrink the lines inside IFCs)
2. we are about to compute the non-static vertical position of a float avoider block level box.

* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::layoutInFlowContent):
(WebCore::Layout::BlockFormattingContext::computeStaticVerticalPosition):
(WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForAncestors):
(WebCore::Layout::BlockFormattingContext::precomputeVerticalPositionForFormattingRoot):
(WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats):
(WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear):
(WebCore::Layout::BlockFormattingContext::computeStaticPosition): Deleted.
(WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForFormattingRoot): Deleted.
(WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForFloatClear): Deleted.
(WebCore::Layout::BlockFormattingContext::hasPrecomputedMarginBefore const): Deleted.
(WebCore::Layout::BlockFormattingContext::computeFloatingPosition): Deleted.
* layout/blockformatting/BlockFormattingContext.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (256098 => 256099)


--- trunk/Source/WebCore/ChangeLog	2020-02-09 02:51:46 UTC (rev 256098)
+++ trunk/Source/WebCore/ChangeLog	2020-02-09 03:45:11 UTC (rev 256099)
@@ -1,5 +1,31 @@
 2020-02-08  Zalan Bujtas  <[email protected]>
 
+        [LFC][BFC] Pre-compute vertical position only when we really need it.
+        https://bugs.webkit.org/show_bug.cgi?id=207432
+        <rdar://problem/59288539>
+
+        Reviewed by Antti Koivisto.
+
+        Instead of pre-computing the vertical position at computeStaticVerticalPosition, let's compute it when
+        1. we are about to layout a new non-float-avoider/float clear FC (e.g. so that intrusive floats can shrink the lines inside IFCs)
+        2. we are about to compute the non-static vertical position of a float avoider block level box.
+
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::BlockFormattingContext::computeStaticVerticalPosition):
+        (WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForAncestors):
+        (WebCore::Layout::BlockFormattingContext::precomputeVerticalPositionForFormattingRoot):
+        (WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats):
+        (WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear):
+        (WebCore::Layout::BlockFormattingContext::computeStaticPosition): Deleted.
+        (WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForFormattingRoot): Deleted.
+        (WebCore::Layout::BlockFormattingContext::computeEstimatedVerticalPositionForFloatClear): Deleted.
+        (WebCore::Layout::BlockFormattingContext::hasPrecomputedMarginBefore const): Deleted.
+        (WebCore::Layout::BlockFormattingContext::computeFloatingPosition): Deleted.
+        * layout/blockformatting/BlockFormattingContext.h:
+
+2020-02-08  Zalan Bujtas  <[email protected]>
+
         [LFC][BFC] Remove establishesBlockFormattingContextOnly and establishesInlineFormattingContextOnly
         https://bugs.webkit.org/show_bug.cgi?id=207431
         <rdar://problem/59288366>

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (256098 => 256099)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2020-02-09 02:51:46 UTC (rev 256098)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp	2020-02-09 03:45:11 UTC (rev 256099)
@@ -120,7 +120,7 @@
             auto verticalConstraints = verticalConstraintsForLayoutBox(layoutBox);
 
             computeBorderAndPadding(layoutBox, horizontalConstraints.containingBlock);
-            computeStaticVerticalPosition(floatingContext, layoutBox, horizontalConstraints, verticalConstraints);
+            computeStaticVerticalPosition(layoutBox, verticalConstraints);
             computeWidthAndMargin(floatingContext, layoutBox, horizontalConstraints);
             computeStaticHorizontalPosition(layoutBox, horizontalConstraints);
 
@@ -127,6 +127,7 @@
             if (layoutBox.establishesFormattingContext()) {
                 if (is<Container>(layoutBox) && downcast<Container>(layoutBox).hasInFlowOrFloatingChild()) {
                     // Layout the inflow descendants of this formatting context root.
+                    precomputeVerticalPositionForFormattingRoot(floatingContext, layoutBox, horizontalConstraints, verticalConstraints);
                     auto& rootDisplayBox = geometryForBox(layoutBox);
                     auto horizontalConstraintsForFormattingContext = Geometry::horizontalConstraintsForInFlow(rootDisplayBox);
                     auto verticalConstraintsForFormattingContext = Geometry::verticalConstraintsForInFlow(rootDisplayBox);
@@ -158,11 +159,11 @@
             }
             // Resolve final positions.
             placeInFlowPositionedChildren(layoutBox, horizontalConstraints);
-            if (layoutBox.isFloatingPositioned()) {
-                computeFloatingPosition(floatingContext, layoutBox);
-                floatingContext.append(layoutBox);
-            } else if (layoutBox.isFloatAvoider())
-                computePositionToAvoidFloats(floatingContext, layoutBox);
+            if (layoutBox.isFloatAvoider()) {
+                computePositionToAvoidFloats(floatingContext, layoutBox, horizontalConstraints, verticalConstraints);
+                if (layoutBox.isFloatingPositioned())
+                    floatingContext.append(layoutBox);
+            }
 
             if (appendNextToLayoutQueue(layoutBox, LayoutDirection::Sibling))
                 break;
@@ -222,13 +223,9 @@
     LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> parent: " << &layoutBox);
 }
 
-void BlockFormattingContext::computeStaticVerticalPosition(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
+void BlockFormattingContext::computeStaticVerticalPosition(const Box& layoutBox, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
 {
     formattingState().displayBox(layoutBox).setTop(geometry().staticVerticalPosition(layoutBox, verticalConstraints.containingBlock));
-    if (layoutBox.hasFloatClear())
-        computeEstimatedVerticalPositionForFloatClear(floatingContext, layoutBox, horizontalConstraints, verticalConstraints);
-    else if (layoutBox.establishesFormattingContext())
-        computeEstimatedVerticalPositionForFormattingRoot(layoutBox, horizontalConstraints, verticalConstraints);
 }
 
 void BlockFormattingContext::computeStaticHorizontalPosition(const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints)
@@ -236,12 +233,6 @@
     formattingState().displayBox(layoutBox).setLeft(geometry().staticHorizontalPosition(layoutBox, horizontalConstraints.containingBlock));
 }
 
-void BlockFormattingContext::computeStaticPosition(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
-{
-    computeStaticVerticalPosition(floatingContext, layoutBox, horizontalConstraints, verticalConstraints);
-    computeStaticHorizontalPosition(layoutBox, horizontalConstraints);
-}
-
 void BlockFormattingContext::computeEstimatedVerticalPosition(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
 {
     auto computedVerticalMargin = geometry().computedVerticalMargin(layoutBox, horizontalConstraints);
@@ -274,6 +265,7 @@
     // So when we get to the point where we intersect the box with the float to decide if the box needs to move, we don't yet have the final vertical position.
     //
     // The idea here is that as long as we don't cross the block formatting context boundary, we should be able to pre-compute the final top position.
+    // FIXME: we currently don't account for the "clear" property when computing the final position for an ancestor.
     for (auto* ancestor = layoutBox.containingBlock(); ancestor && !ancestor->establishesBlockFormattingContext(); ancestor = ancestor->containingBlock()) {
         // FIXME: with incremental layout, we might actually have a valid (non-estimated) margin top as well.
         if (hasEstimatedMarginBefore(*ancestor))
@@ -290,34 +282,49 @@
     }
 }
 
-void BlockFormattingContext::computeEstimatedVerticalPositionForFormattingRoot(const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
+void BlockFormattingContext::precomputeVerticalPositionForFormattingRoot(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
 {
     ASSERT(layoutBox.establishesFormattingContext());
-    ASSERT(!layoutBox.hasFloatClear());
+    if (layoutBox.isFloatAvoider() && !layoutBox.hasFloatClear())
+        return;
+    // We need the final vertical position when the formatting context inherits floats from the parent FC.
+    computeEstimatedVerticalPositionForAncestors(layoutBox, horizontalConstraints, verticalConstraints);
+    computeEstimatedVerticalPosition(layoutBox, horizontalConstraints.containingBlock, verticalConstraints.containingBlock);
+    if (layoutBox.hasFloatClear()) {
+        // if we just let the box sit at the static vertical position, we might find unrelated float boxes there (boxes that we need to clear).
+        computeVerticalPositionForFloatClear(floatingContext, layoutBox);
+    }
+}
 
+void BlockFormattingContext::computePositionToAvoidFloats(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
+{
+    ASSERT(layoutBox.isFloatAvoider());
+    // In order to position a float avoider we need to know its vertical position relative to its formatting context root (and not just its containing block),
+    // because all the already-placed floats (floats that we are trying to avoid here) in this BFC might belong
+    // to a different set of containing blocks (but they all descendants of the BFC root).
+    // However according to the BFC rules, at this point of the layout flow we don't yet have computed vertical positions for the ancestors.
     if (layoutBox.isFloatingPositioned()) {
         computeEstimatedVerticalPositionForAncestors(layoutBox, horizontalConstraints, verticalConstraints);
+        formattingState().displayBox(layoutBox).setTopLeft(floatingContext.positionForFloat(layoutBox));
         return;
     }
-
-    computeEstimatedVerticalPosition(layoutBox, horizontalConstraints.containingBlock, verticalConstraints.containingBlock);
+    // Non-float positioned float avoiders (formatting context roots and clear boxes) should be fine unless there are floats in this context.
+    if (floatingContext.isEmpty())
+        return;
     computeEstimatedVerticalPositionForAncestors(layoutBox, horizontalConstraints, verticalConstraints);
+    if (layoutBox.hasFloatClear())
+        return computeVerticalPositionForFloatClear(floatingContext, layoutBox);
 
-    // We only need the final vertical position if the formatting context does let intrusive floats in (aka not a float avoider).
-    if (!layoutBox.isFloatAvoider()) {
-        computeEstimatedVerticalPosition(layoutBox, horizontalConstraints.containingBlock, verticalConstraints.containingBlock);
-        computeEstimatedVerticalPositionForAncestors(layoutBox, horizontalConstraints, verticalConstraints);
-    }
+    ASSERT(layoutBox.establishesFormattingContext());
+    if (auto adjustedPosition = floatingContext.positionForFormattingContextRoot(layoutBox))
+        formattingState().displayBox(layoutBox).setTopLeft(*adjustedPosition);
 }
 
-void BlockFormattingContext::computeEstimatedVerticalPositionForFloatClear(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints, const ConstraintsPair<VerticalConstraints>& verticalConstraints)
+void BlockFormattingContext::computeVerticalPositionForFloatClear(const FloatingContext& floatingContext, const Box& layoutBox)
 {
     ASSERT(layoutBox.hasFloatClear());
     if (floatingContext.isEmpty())
         return;
-    // The static position with clear requires margin esitmation to see if clearance is needed.
-    computeEstimatedVerticalPosition(layoutBox, horizontalConstraints.containingBlock, verticalConstraints.containingBlock);
-    computeEstimatedVerticalPositionForAncestors(layoutBox, horizontalConstraints, verticalConstraints);
     auto verticalPositionAndClearance = floatingContext.verticalPositionWithClearance(layoutBox);
     if (!verticalPositionAndClearance.position) {
         ASSERT(!verticalPositionAndClearance.clearance);
@@ -331,40 +338,6 @@
         displayBox.setHasClearance();
 }
 
-#if ASSERT_ENABLED
-bool BlockFormattingContext::hasPrecomputedMarginBefore(const Box& layoutBox) const
-{
-    for (auto* ancestor = layoutBox.containingBlock(); ancestor && !ancestor->establishesBlockFormattingContext(); ancestor = ancestor->containingBlock()) {
-        if (hasEstimatedMarginBefore(*ancestor))
-            continue;
-        return false;
-    }
-    return true;
-}
-#endif // ASSERT_ENABLED
-
-void BlockFormattingContext::computeFloatingPosition(const FloatingContext& floatingContext, const Box& layoutBox)
-{
-    ASSERT(layoutBox.isFloatingPositioned());
-    ASSERT(hasPrecomputedMarginBefore(layoutBox));
-    formattingState().displayBox(layoutBox).setTopLeft(floatingContext.positionForFloat(layoutBox));
-}
-
-void BlockFormattingContext::computePositionToAvoidFloats(const FloatingContext& floatingContext, const Box& layoutBox)
-{
-    // Formatting context roots avoid floats.
-    ASSERT(layoutBox.establishesBlockFormattingContext());
-    ASSERT(!layoutBox.isFloatingPositioned());
-    ASSERT(!layoutBox.hasFloatClear());
-    ASSERT(hasPrecomputedMarginBefore(layoutBox));
-
-    if (floatingContext.isEmpty())
-        return;
-
-    if (auto adjustedPosition = floatingContext.positionForFormattingContextRoot(layoutBox))
-        formattingState().displayBox(layoutBox).setTopLeft(*adjustedPosition);
-}
-
 void BlockFormattingContext::computeWidthAndMargin(const FloatingContext& floatingContext, const Box& layoutBox, const ConstraintsPair<HorizontalConstraints>& horizontalConstraints)
 {
     auto compute = [&](Optional<LayoutUnit> usedWidth) -> ContentWidthAndMargin {

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (256098 => 256099)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2020-02-09 02:51:46 UTC (rev 256098)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h	2020-02-09 03:45:11 UTC (rev 256099)
@@ -63,15 +63,13 @@
     void computeHeightAndMargin(const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
 
     void computeStaticHorizontalPosition(const Box&, const ConstraintsPair<HorizontalConstraints>&);
-    void computeStaticVerticalPosition(const FloatingContext&, const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
-    void computeStaticPosition(const FloatingContext&, const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
-    void computeFloatingPosition(const FloatingContext&, const Box&);
-    void computePositionToAvoidFloats(const FloatingContext&, const Box&);
+    void computeStaticVerticalPosition(const Box&, const ConstraintsPair<VerticalConstraints>&);
+    void computePositionToAvoidFloats(const FloatingContext&, const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
+    void computeVerticalPositionForFloatClear(const FloatingContext&, const Box&);
 
     void computeEstimatedVerticalPosition(const Box&, const HorizontalConstraints&, const VerticalConstraints&);
     void computeEstimatedVerticalPositionForAncestors(const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
-    void computeEstimatedVerticalPositionForFormattingRoot(const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
-    void computeEstimatedVerticalPositionForFloatClear(const FloatingContext&, const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
+    void precomputeVerticalPositionForFormattingRoot(const FloatingContext&, const Box&, const ConstraintsPair<HorizontalConstraints>&, const ConstraintsPair<VerticalConstraints>&);
 
     IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
     LayoutUnit verticalPositionWithMargin(const Box&, const UsedVerticalMargin&, const VerticalConstraints&) const;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to