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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutBlock.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index d1c5f99454c92fcc0afca68a6a31b76a164f570f..b30940bec880727f48b8c1b17aaf374cc1e98cf5 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -753,85 +753,90 @@ void LayoutBlock::layoutPositionedObjects(bool relayoutChildren,
if (!positionedDescendants)
return;
- bool isPaginated = view()->layoutState()->isPaginated();
-
for (auto* positionedObject : *positionedDescendants) {
- positionedObject->setMayNeedPaintInvalidation();
-
- SubtreeLayoutScope layoutScope(*positionedObject);
- // If positionedObject is fixed-positioned and moves with an absolute-
- // positioned ancestor (other than the LayoutView, which cannot move),
- // mark it for layout now.
- markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope);
- if (info == LayoutOnlyFixedPositionedObjects) {
- positionedObject->layoutIfNeeded();
- continue;
- }
+ layoutPositionedObject(positionedObject, relayoutChildren, info);
+ }
+}
- if (!positionedObject->normalChildNeedsLayout() &&
- (relayoutChildren || m_heightAvailableToChildrenChanged ||
- needsLayoutDueToStaticPosition(positionedObject)))
- layoutScope.setChildNeedsLayout(positionedObject);
-
- // If relayoutChildren is set and the child has percentage padding or an
- // embedded content box, we also need to invalidate the childs pref widths.
- if (relayoutChildren &&
- positionedObject->needsPreferredWidthsRecalculation())
- positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis);
-
- LayoutUnit logicalTopEstimate;
- bool needsBlockDirectionLocationSetBeforeLayout =
- isPaginated &&
- positionedObject->getPaginationBreakability() != ForbidBreaks;
- if (needsBlockDirectionLocationSetBeforeLayout) {
- // Out-of-flow objects are normally positioned after layout (while in-flow
- // objects are positioned before layout). If the child object is paginated
- // in the same context as we are, estimate its logical top now. We need to
- // know this up-front, to correctly evaluate if we need to mark for
- // relayout, and, if our estimate is correct, we'll even be able to insert
- // correct pagination struts on the first attempt.
- LogicalExtentComputedValues computedValues;
- positionedObject->computeLogicalHeight(positionedObject->logicalHeight(),
- positionedObject->logicalTop(),
- computedValues);
- logicalTopEstimate = computedValues.m_position;
- positionedObject->setLogicalTop(logicalTopEstimate);
- }
+void LayoutBlock::layoutPositionedObject(LayoutBox* positionedObject,
+ bool relayoutChildren,
+ PositionedLayoutBehavior info) {
+ positionedObject->setMayNeedPaintInvalidation();
- if (!positionedObject->needsLayout())
- markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope);
+ SubtreeLayoutScope layoutScope(*positionedObject);
+ // If positionedObject is fixed-positioned and moves with an absolute-
+ // positioned ancestor (other than the LayoutView, which cannot move),
+ // mark it for layout now.
+ markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope);
+ if (info == LayoutOnlyFixedPositionedObjects) {
+ positionedObject->layoutIfNeeded();
+ return;
+ }
- // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout()
- // here instead of a full layout. Need to investigate why it does not
- // trigger the correct invalidations in that case. crbug.com/350756
- if (info == ForcedLayoutAfterContainingBlockMoved)
- positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved,
- MarkOnlyThis);
+ if (!positionedObject->normalChildNeedsLayout() &&
+ (relayoutChildren || m_heightAvailableToChildrenChanged ||
+ needsLayoutDueToStaticPosition(positionedObject)))
+ layoutScope.setChildNeedsLayout(positionedObject);
- positionedObject->layoutIfNeeded();
+ // If relayoutChildren is set and the child has percentage padding or an
+ // embedded content box, we also need to invalidate the childs pref widths.
+ if (relayoutChildren && positionedObject->needsPreferredWidthsRecalculation())
+ positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis);
- LayoutObject* parent = positionedObject->parent();
- bool layoutChanged = false;
- if (parent->isFlexibleBox() &&
- toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout(
- *positionedObject)) {
- // The static position of an abspos child of a flexbox depends on its size
- // (for example, they can be centered). So we may have to reposition the
- // item after layout.
- // TODO(cbiesinger): We could probably avoid a layout here and just
- // reposition?
- positionedObject->forceChildLayout();
- layoutChanged = true;
- }
+ LayoutUnit logicalTopEstimate;
+ bool isPaginated = view()->layoutState()->isPaginated();
+ bool needsBlockDirectionLocationSetBeforeLayout =
+ isPaginated &&
+ positionedObject->getPaginationBreakability() != ForbidBreaks;
+ if (needsBlockDirectionLocationSetBeforeLayout) {
+ // Out-of-flow objects are normally positioned after layout (while in-flow
+ // objects are positioned before layout). If the child object is paginated
+ // in the same context as we are, estimate its logical top now. We need to
+ // know this up-front, to correctly evaluate if we need to mark for
+ // relayout, and, if our estimate is correct, we'll even be able to insert
+ // correct pagination struts on the first attempt.
+ LogicalExtentComputedValues computedValues;
+ positionedObject->computeLogicalHeight(positionedObject->logicalHeight(),
+ positionedObject->logicalTop(),
+ computedValues);
+ logicalTopEstimate = computedValues.m_position;
+ positionedObject->setLogicalTop(logicalTopEstimate);
+ }
- // Lay out again if our estimate was wrong.
- if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout &&
- logicalTopEstimate != logicalTopForChild(*positionedObject))
- positionedObject->forceChildLayout();
+ if (!positionedObject->needsLayout())
+ markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope);
- if (isPaginated)
- updateFragmentationInfoForChild(*positionedObject);
+ // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout()
+ // here instead of a full layout. Need to investigate why it does not
+ // trigger the correct invalidations in that case. crbug.com/350756
+ if (info == ForcedLayoutAfterContainingBlockMoved) {
+ positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved,
+ MarkOnlyThis);
}
+
+ positionedObject->layoutIfNeeded();
+
+ LayoutObject* parent = positionedObject->parent();
+ bool layoutChanged = false;
+ if (parent->isFlexibleBox() &&
+ toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout(
+ *positionedObject)) {
+ // The static position of an abspos child of a flexbox depends on its size
+ // (for example, they can be centered). So we may have to reposition the
+ // item after layout.
+ // TODO(cbiesinger): We could probably avoid a layout here and just
+ // reposition?
+ positionedObject->forceChildLayout();
+ layoutChanged = true;
+ }
+
+ // Lay out again if our estimate was wrong.
+ if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout &&
+ logicalTopEstimate != logicalTopForChild(*positionedObject))
+ positionedObject->forceChildLayout();
+
+ if (isPaginated)
+ updateFragmentationInfoForChild(*positionedObject);
}
void LayoutBlock::markPositionedObjectsForLayout() {
« 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