Changeset 295633 in webkit


Ignore:
Timestamp:
Jun 17, 2022 6:35:02 AM (2 years ago)
Author:
Alan Bujtas
Message:

Remove redundant logical right computation for grid items in RenderBlock::computeOverflow
https://bugs.webkit.org/show_bug.cgi?id=241689

Reviewed by Simon Fraser.

If the grid content produces layout overflow, we should not need to re-compute it again by looping through the grid items.

  1. Decouple "include padding end" and "include child's margin end" logic
  2. Decouple "include padding after" and "include padding end" logic.
  3. Restore RenderFlexibleBox and RenderGrid computeOverflow calls to pre-r282463 (when clientLogicalRightAndBottomAfterRepositioning was introduced)
  • LayoutTests/fast/overflow/grid-horizontal-overflow-with-padding-end-expected.html: Added.
  • LayoutTests/fast/overflow/grid-horizontal-overflow-with-padding-end.html: Added.
  • Source/WebCore/rendering/RenderBlock.cpp:

(WebCore::RenderBlock::computeOverflow):
(WebCore::RenderBlock::layoutOverflowLogicalBottom):
(WebCore::RenderBlock::clientLogicalRightAndBottomAfterRepositioning const): Deleted.

  • Source/WebCore/rendering/RenderBlock.h:
  • Source/WebCore/rendering/RenderBox.cpp:

(WebCore::RenderBox::layoutOverflowRectForPropagation const):

  • Source/WebCore/rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::layoutBlock):

  • Source/WebCore/rendering/RenderGrid.cpp:

(WebCore::RenderGrid::layoutBlock):

Canonical link: https://commits.webkit.org/251638@main

Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r295630 r295633  
    682682}
    683683
    684 LayoutSize RenderBlock::clientLogicalRightAndBottomAfterRepositioning() const
    685 {
    686     LayoutUnit maxChildLogicalRight;
    687     LayoutUnit maxChildLogicalBottom;
    688     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    689         if (child->isOutOfFlowPositioned())
    690             continue;
    691         LayoutUnit childLogicalRight = logicalLeftForChild(*child) + logicalWidthForChild(*child) + marginEndForChild(*child);
    692         LayoutUnit childLogicalBottom = logicalTopForChild(*child) + logicalHeightForChild(*child) + marginAfterForChild(*child);
    693         maxChildLogicalRight = std::max(maxChildLogicalRight, childLogicalRight);
    694         maxChildLogicalBottom = std::max(maxChildLogicalBottom, childLogicalBottom);
    695 
    696     }
    697     return LayoutSize(maxChildLogicalRight + paddingRight(), std::max(clientLogicalBottom(), maxChildLogicalBottom + paddingAfter()));
    698 }
    699 
    700 
    701684// Overflow is always relative to the border-box of the element in question.
    702685// Therefore, if the element has a vertical scrollbar placed on the left, an overflow rect at x=2px would conceptually intersect the scrollbar.
     
    709692
    710693    if (hasNonVisibleOverflow()) {
    711         // Set the axis we don't care about to be 1, since we want this overflow to always be considered reachable.
    712         LayoutUnit rectWidth = 1_lu;
    713         // For grid, width of the overflow rect should be the width of the grid area of the items rather than the container block.
    714         // As per https://github.com/w3c/csswg-drafts/issues/3653, child's margins along with padding should contribute to the
    715         // scrollable overflow area.
    716         if (this->isRenderGrid())
    717             rectWidth = clientLogicalRightAndBottomAfterRepositioning().width();
    718 
    719         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
    720         // and bottom padding.
    721         LayoutRect clientRect(flippedClientBoxRect());
    722         LayoutRect rectToApply;
    723         if (isHorizontalWritingMode())
    724             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), rectWidth, std::max(0_lu, oldClientAfterEdge - clientRect.y()));
    725         else
    726             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), std::max(0_lu, oldClientAfterEdge - clientRect.x()), rectWidth);
    727         addLayoutOverflow(rectToApply);
     694        auto includePaddingEnd = [&] {
     695            // As per https://github.com/w3c/csswg-drafts/issues/3653 padding should contribute to the scrollable overflow area.
     696            if (!paddingEnd())
     697                return;
     698            // FIXME: Expand it to non-grid cases when applicable.
     699            if (!is<RenderGrid>(*this))
     700                return;
     701
     702            auto layoutOverflowRect = this->layoutOverflowRect();
     703            auto layoutOverflowLogicalWidthIncludingPaddingEnd = [&] {
     704                if (hasHorizontalLayoutOverflow())
     705                    return (isHorizontalWritingMode() ? layoutOverflowRect.width() : layoutOverflowRect.height()) + paddingEnd();
     706
     707                // FIXME: This is not sufficient for BFC layout (missing non-formatting-context root descendants).
     708                auto contentLogicalRight = LayoutUnit { };
     709                for (auto& child : childrenOfType<RenderBox>(*this)) {
     710                    if (child.isOutOfFlowPositioned())
     711                        continue;
     712                    auto childLogicalRight = logicalLeftForChild(child) + logicalWidthForChild(child) + std::max(0_lu, marginEndForChild(child));
     713                    contentLogicalRight = std::max(contentLogicalRight, childLogicalRight);
     714                }
     715                auto logicalRightWithPaddingEnd = contentLogicalRight + paddingEnd();
     716                // Use padding box as the reference box.
     717                return logicalRightWithPaddingEnd - (isHorizontalWritingMode() ? borderLeft() : borderTop());
     718            };
     719
     720            if (isHorizontalWritingMode())
     721                layoutOverflowRect.setWidth(layoutOverflowLogicalWidthIncludingPaddingEnd());
     722            else
     723                layoutOverflowRect.setHeight(layoutOverflowLogicalWidthIncludingPaddingEnd());
     724            addLayoutOverflow(layoutOverflowRect);
     725        };
     726        includePaddingEnd();
     727
     728        auto includePaddingAfter = [&] {
     729            // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins and bottom padding.
     730            auto clientRect = flippedClientBoxRect();
     731            auto rectToApply = clientRect;
     732            // Set the axis we don't care about to be 1, since we want this overflow to always be considered reachable.
     733            if (isHorizontalWritingMode()) {
     734                rectToApply.setWidth(1);
     735                rectToApply.setHeight(std::max(0_lu, oldClientAfterEdge - clientRect.y()));
     736            } else {
     737                rectToApply.setWidth(std::max(0_lu, oldClientAfterEdge - clientRect.x()));
     738                rectToApply.setHeight(1);
     739            }
     740            addLayoutOverflow(rectToApply);
     741        };
     742        includePaddingAfter();
    728743        if (hasRenderOverflow())
    729744            m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
     
    35113526#endif
    35123527}
    3513    
     3528
     3529LayoutUnit RenderBlock::layoutOverflowLogicalBottom(const RenderBlock& renderer)
     3530{
     3531    ASSERT(is<RenderGrid>(renderer) || is<RenderFlexibleBox>(renderer));
     3532    auto maxChildLogicalBottom = LayoutUnit { };
     3533    for (auto& child : childrenOfType<RenderBox>(renderer)) {
     3534        if (child.isOutOfFlowPositioned())
     3535            continue;
     3536        auto childLogicalBottom = renderer.logicalTopForChild(child) + renderer.logicalHeightForChild(child) + renderer.marginAfterForChild(child);
     3537        maxChildLogicalBottom = std::max(maxChildLogicalBottom, childLogicalBottom);
     3538    }
     3539    return std::max(renderer.clientLogicalBottom(), maxChildLogicalBottom + renderer.paddingAfter());
     3540}
     3541
    35143542} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r294607 r295633  
    232232    void paintExcludedChildrenInBorder(PaintInfo&, const LayoutPoint&);
    233233   
    234     LayoutSize clientLogicalRightAndBottomAfterRepositioning() const;
    235234    // Accessors for logical width/height and margins in the containing block's block-flow direction.
    236235    enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
     
    379378    bool childBoxIsUnsplittableForFragmentation(const RenderBox& child) const;
    380379
     380    static LayoutUnit layoutOverflowLogicalBottom(const RenderBlock&);
     381
    381382public:
    382383    virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r295124 r295633  
    52345234{
    52355235    // Only propagate interior layout overflow if we don't completely clip it.
    5236     LayoutRect rect = borderBoxRect();
     5236    auto rect = borderBoxRect();
     5237    if (isGridItem()) {
     5238        // As per https://github.com/w3c/csswg-drafts/issues/3653, child's margins should contribute to the scrollable overflow area.
     5239        // FIXME: Expand it to non-grid cases when applicable.
     5240        rect.setWidth(rect.width() + std::max(0_lu, marginEnd()));
     5241    }
    52375242    if (!shouldApplyLayoutContainment()) {
    52385243        if (style().overflowX() == Overflow::Clip && style().overflowY() == Overflow::Visible) {
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r295283 r295633  
    408408        repaintChildrenDuringLayoutIfMoved(oldChildRects);
    409409        // FIXME: css3/flexbox/repaint-rtl-column.html seems to repaint more overflow than it needs to.
    410         computeOverflow(clientLogicalRightAndBottomAfterRepositioning().height());
     410        computeOverflow(layoutOverflowLogicalBottom(*this));
    411411    }
    412412    updateLayerTransform();
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r293943 r295633  
    370370        m_trackSizingAlgorithm.reset();
    371371
    372         computeOverflow(clientLogicalRightAndBottomAfterRepositioning().height());
     372        computeOverflow(layoutOverflowLogicalBottom(*this));
    373373    }
    374374
Note: See TracChangeset for help on using the changeset viewer.