Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlock.cpp

Issue 2513953002: [css-grid] Avoid double loop in positioned objects layout (Closed)
Patch Set: New version overriding layoutPositionedObjects() Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com) 4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } 746 }
747 return false; 747 return false;
748 } 748 }
749 749
750 void LayoutBlock::layoutPositionedObjects(bool relayoutChildren, 750 void LayoutBlock::layoutPositionedObjects(bool relayoutChildren,
751 PositionedLayoutBehavior info) { 751 PositionedLayoutBehavior info) {
752 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); 752 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects();
753 if (!positionedDescendants) 753 if (!positionedDescendants)
754 return; 754 return;
755 755
756 bool isPaginated = view()->layoutState()->isPaginated();
757
758 for (auto* positionedObject : *positionedDescendants) { 756 for (auto* positionedObject : *positionedDescendants) {
759 positionedObject->setMayNeedPaintInvalidation(); 757 layoutPositionedObject(positionedObject, relayoutChildren, info);
760
761 SubtreeLayoutScope layoutScope(*positionedObject);
762 // If positionedObject is fixed-positioned and moves with an absolute-
763 // positioned ancestor (other than the LayoutView, which cannot move),
764 // mark it for layout now.
765 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope);
766 if (info == LayoutOnlyFixedPositionedObjects) {
767 positionedObject->layoutIfNeeded();
768 continue;
769 }
770
771 if (!positionedObject->normalChildNeedsLayout() &&
772 (relayoutChildren || m_heightAvailableToChildrenChanged ||
773 needsLayoutDueToStaticPosition(positionedObject)))
774 layoutScope.setChildNeedsLayout(positionedObject);
775
776 // If relayoutChildren is set and the child has percentage padding or an
777 // embedded content box, we also need to invalidate the childs pref widths.
778 if (relayoutChildren &&
779 positionedObject->needsPreferredWidthsRecalculation())
780 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis);
781
782 LayoutUnit logicalTopEstimate;
783 bool needsBlockDirectionLocationSetBeforeLayout =
784 isPaginated &&
785 positionedObject->getPaginationBreakability() != ForbidBreaks;
786 if (needsBlockDirectionLocationSetBeforeLayout) {
787 // Out-of-flow objects are normally positioned after layout (while in-flow
788 // objects are positioned before layout). If the child object is paginated
789 // in the same context as we are, estimate its logical top now. We need to
790 // know this up-front, to correctly evaluate if we need to mark for
791 // relayout, and, if our estimate is correct, we'll even be able to insert
792 // correct pagination struts on the first attempt.
793 LogicalExtentComputedValues computedValues;
794 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(),
795 positionedObject->logicalTop(),
796 computedValues);
797 logicalTopEstimate = computedValues.m_position;
798 positionedObject->setLogicalTop(logicalTopEstimate);
799 }
800
801 if (!positionedObject->needsLayout())
802 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope);
803
804 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout()
805 // here instead of a full layout. Need to investigate why it does not
806 // trigger the correct invalidations in that case. crbug.com/350756
807 if (info == ForcedLayoutAfterContainingBlockMoved)
808 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved,
809 MarkOnlyThis);
810
811 positionedObject->layoutIfNeeded();
812
813 LayoutObject* parent = positionedObject->parent();
814 bool layoutChanged = false;
815 if (parent->isFlexibleBox() &&
816 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout(
817 *positionedObject)) {
818 // The static position of an abspos child of a flexbox depends on its size
819 // (for example, they can be centered). So we may have to reposition the
820 // item after layout.
821 // TODO(cbiesinger): We could probably avoid a layout here and just
822 // reposition?
823 positionedObject->forceChildLayout();
824 layoutChanged = true;
825 }
826
827 // Lay out again if our estimate was wrong.
828 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout &&
829 logicalTopEstimate != logicalTopForChild(*positionedObject))
830 positionedObject->forceChildLayout();
831
832 if (isPaginated)
833 updateFragmentationInfoForChild(*positionedObject);
834 } 758 }
835 } 759 }
836 760
761 void LayoutBlock::layoutPositionedObject(LayoutBox* positionedObject,
762 bool relayoutChildren,
763 PositionedLayoutBehavior info) {
764 positionedObject->setMayNeedPaintInvalidation();
765
766 SubtreeLayoutScope layoutScope(*positionedObject);
767 // If positionedObject is fixed-positioned and moves with an absolute-
768 // positioned ancestor (other than the LayoutView, which cannot move),
769 // mark it for layout now.
770 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope);
771 if (info == LayoutOnlyFixedPositionedObjects) {
772 positionedObject->layoutIfNeeded();
773 return;
774 }
775
776 if (!positionedObject->normalChildNeedsLayout() &&
777 (relayoutChildren || m_heightAvailableToChildrenChanged ||
778 needsLayoutDueToStaticPosition(positionedObject)))
779 layoutScope.setChildNeedsLayout(positionedObject);
780
781 // If relayoutChildren is set and the child has percentage padding or an
782 // embedded content box, we also need to invalidate the childs pref widths.
783 if (relayoutChildren && positionedObject->needsPreferredWidthsRecalculation())
784 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis);
785
786 LayoutUnit logicalTopEstimate;
787 bool isPaginated = view()->layoutState()->isPaginated();
788 bool needsBlockDirectionLocationSetBeforeLayout =
789 isPaginated &&
790 positionedObject->getPaginationBreakability() != ForbidBreaks;
791 if (needsBlockDirectionLocationSetBeforeLayout) {
792 // Out-of-flow objects are normally positioned after layout (while in-flow
793 // objects are positioned before layout). If the child object is paginated
794 // in the same context as we are, estimate its logical top now. We need to
795 // know this up-front, to correctly evaluate if we need to mark for
796 // relayout, and, if our estimate is correct, we'll even be able to insert
797 // correct pagination struts on the first attempt.
798 LogicalExtentComputedValues computedValues;
799 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(),
800 positionedObject->logicalTop(),
801 computedValues);
802 logicalTopEstimate = computedValues.m_position;
803 positionedObject->setLogicalTop(logicalTopEstimate);
804 }
805
806 if (!positionedObject->needsLayout())
807 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope);
808
809 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout()
810 // here instead of a full layout. Need to investigate why it does not
811 // trigger the correct invalidations in that case. crbug.com/350756
812 if (info == ForcedLayoutAfterContainingBlockMoved) {
813 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved,
814 MarkOnlyThis);
815 }
816
817 positionedObject->layoutIfNeeded();
818
819 LayoutObject* parent = positionedObject->parent();
820 bool layoutChanged = false;
821 if (parent->isFlexibleBox() &&
822 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout(
823 *positionedObject)) {
824 // The static position of an abspos child of a flexbox depends on its size
825 // (for example, they can be centered). So we may have to reposition the
826 // item after layout.
827 // TODO(cbiesinger): We could probably avoid a layout here and just
828 // reposition?
829 positionedObject->forceChildLayout();
830 layoutChanged = true;
831 }
832
833 // Lay out again if our estimate was wrong.
834 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout &&
835 logicalTopEstimate != logicalTopForChild(*positionedObject))
836 positionedObject->forceChildLayout();
837
838 if (isPaginated)
839 updateFragmentationInfoForChild(*positionedObject);
840 }
841
837 void LayoutBlock::markPositionedObjectsForLayout() { 842 void LayoutBlock::markPositionedObjectsForLayout() {
838 if (TrackedLayoutBoxListHashSet* positionedDescendants = 843 if (TrackedLayoutBoxListHashSet* positionedDescendants =
839 positionedObjects()) { 844 positionedObjects()) {
840 for (auto* descendant : *positionedDescendants) 845 for (auto* descendant : *positionedDescendants)
841 descendant->setChildNeedsLayout(); 846 descendant->setChildNeedsLayout();
842 } 847 }
843 } 848 }
844 849
845 void LayoutBlock::paint(const PaintInfo& paintInfo, 850 void LayoutBlock::paint(const PaintInfo& paintInfo,
846 const LayoutPoint& paintOffset) const { 851 const LayoutPoint& paintOffset) const {
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 } 2212 }
2208 2213
2209 return availableHeight; 2214 return availableHeight;
2210 } 2215 }
2211 2216
2212 bool LayoutBlock::hasDefiniteLogicalHeight() const { 2217 bool LayoutBlock::hasDefiniteLogicalHeight() const {
2213 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1); 2218 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1);
2214 } 2219 }
2215 2220
2216 } // namespace blink 2221 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBlock.h ('k') | third_party/WebKit/Source/core/layout/LayoutGrid.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698