Title: [136324] trunk
Revision
136324
Author
t...@chromium.org
Date
2012-12-02 02:39:51 -0800 (Sun, 02 Dec 2012)

Log Message

Avoid a second layout of flex items in layoutAndPlaceChildren()
https://bugs.webkit.org/show_bug.cgi?id=102352

Reviewed by Ojan Vafai.

Source/WebCore:

Avoid doing a second layout if we're going to get the same size as before.
This prevents us from doing an exponential number of layouts in some
common cases.

Test: css3/flexbox/stretch-after-sibling-size-change.html

* html/shadow/SliderThumbElement.cpp:
(WebCore::RenderSliderContainer::layout): Force a layout of the track, which positions the thumb.
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::needToStretchChild): Determine if a child is going to stretch.
(WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis): Makes sure we're in a consistent state before
we apply auto margins.
(WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
* rendering/RenderFlexibleBox.h: Add needToStretchChild.

LayoutTests:

Add a test case to make sure we relayout when a sibling is stretching.

* css3/flexbox/stretch-after-sibling-size-change-expected.txt: Added.
* css3/flexbox/stretch-after-sibling-size-change.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (136323 => 136324)


--- trunk/LayoutTests/ChangeLog	2012-12-02 10:31:42 UTC (rev 136323)
+++ trunk/LayoutTests/ChangeLog	2012-12-02 10:39:51 UTC (rev 136324)
@@ -1,3 +1,15 @@
+2012-12-02  Tony Chang  <t...@chromium.org>
+
+        Avoid a second layout of flex items in layoutAndPlaceChildren()
+        https://bugs.webkit.org/show_bug.cgi?id=102352
+
+        Reviewed by Ojan Vafai.
+
+        Add a test case to make sure we relayout when a sibling is stretching.
+
+        * css3/flexbox/stretch-after-sibling-size-change-expected.txt: Added.
+        * css3/flexbox/stretch-after-sibling-size-change.html: Added.
+
 2012-12-02  Yongjun Zhang  <yongjun_zh...@apple.com>
 
         Need a method to close all idle localstorage databases immediately.

Added: trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change-expected.txt (0 => 136324)


--- trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change-expected.txt	2012-12-02 10:39:51 UTC (rev 136324)
@@ -0,0 +1 @@
+PASS

Added: trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change.html (0 => 136324)


--- trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change.html	                        (rev 0)
+++ trunk/LayoutTests/css3/flexbox/stretch-after-sibling-size-change.html	2012-12-02 10:39:51 UTC (rev 136324)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link href="" rel="stylesheet">
+<script src=""
+<script>
+window._onload_ = function()
+{
+    document.getElementById("a").style.height = "20px"
+    checkLayout(".flexbox");
+};
+</script>
+</head>
+<body>
+<div data-expected-width="100" data-expected-height="20" class="flexbox" style="width: 100px">
+    <div id=a class="flex-one" data-expected-width="50" data-expected-height="20" style="background-color: blue; height: 30px;"></div>
+    <div id=b class="flex-one" data-expected-width="50" data-expected-height="20" style="background-color: green"></div>
+</div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (136323 => 136324)


--- trunk/Source/WebCore/ChangeLog	2012-12-02 10:31:42 UTC (rev 136323)
+++ trunk/Source/WebCore/ChangeLog	2012-12-02 10:39:51 UTC (rev 136324)
@@ -1,3 +1,25 @@
+2012-12-02  Tony Chang  <t...@chromium.org>
+
+        Avoid a second layout of flex items in layoutAndPlaceChildren()
+        https://bugs.webkit.org/show_bug.cgi?id=102352
+
+        Reviewed by Ojan Vafai.
+
+        Avoid doing a second layout if we're going to get the same size as before.
+        This prevents us from doing an exponential number of layouts in some
+        common cases.
+
+        Test: css3/flexbox/stretch-after-sibling-size-change.html
+
+        * html/shadow/SliderThumbElement.cpp:
+        (WebCore::RenderSliderContainer::layout): Force a layout of the track, which positions the thumb.
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::needToStretchChild): Determine if a child is going to stretch.
+        (WebCore::RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis): Makes sure we're in a consistent state before
+        we apply auto margins.
+        (WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
+        * rendering/RenderFlexibleBox.h: Add needToStretchChild.
+
 2012-12-02  Yongjun Zhang  <yongjun_zh...@apple.com>
 
         Need a method to close all idle localstorage databases immediately.

Modified: trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp (136323 => 136324)


--- trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp	2012-12-02 10:31:42 UTC (rev 136323)
+++ trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp	2012-12-02 10:39:51 UTC (rev 136324)
@@ -178,10 +178,13 @@
     }
 
     RenderBox* thumb = 0;
+    RenderBox* track = 0;
     if (input->sliderThumbElement() && input->sliderThumbElement()->renderer()) {
         thumb = toRenderBox(input->sliderThumbElement()->renderer());
-        // Reset the thumb location before layout.
-        thumb->setLocation(LayoutPoint());
+        track = toRenderBox(thumb->parent());
+        // Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
+        // FIXME: Make a custom Render class for the track and move the thumb positioning code there.
+        track->setChildNeedsLayout(true, MarkOnlyThis);
     }
 
     RenderFlexibleBox::layout();
@@ -190,7 +193,6 @@
     // These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector).
     if (!thumb)
         return;
-    RenderBox* track = toRenderBox(thumb->parent());
 
     double percentageOffset = sliderPosition(input).toDouble();
     LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth();

Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (136323 => 136324)


--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp	2012-12-02 10:31:42 UTC (rev 136323)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp	2012-12-02 10:39:51 UTC (rev 136324)
@@ -1065,6 +1065,21 @@
     return count;
 }
 
+bool RenderFlexibleBox::needToStretchChild(RenderBox* child)
+{
+    if (alignmentForChild(child) != AlignStretch)
+        return false;
+
+    Length crossAxisLength = isHorizontalFlow() ? child->style()->height() : child->style()->width();
+    return crossAxisLength.isAuto();
+}
+
+void RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox* child)
+{
+    if (hasAutoMarginsInCrossAxis(child))
+        child->updateLogicalHeight();
+}
+
 void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts)
 {
     ASSERT(childSizes.size() == children.size());
@@ -1090,7 +1105,12 @@
         LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(child);
         setLogicalOverrideSize(child, childPreferredSize);
         // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
-        child->setChildNeedsLayout(true, MarkOnlyThis);
+        if (needToStretchChild(child) || childPreferredSize != mainAxisExtentForChild(child))
+            child->setChildNeedsLayout(true, MarkOnlyThis);
+        else {
+            // To avoid double applying margin changes in updateAutoMarginsInCrossAxis, we reset the margins here.
+            resetAutoMarginsAndLogicalTopInCrossAxis(child);
+        }
         child->layoutIfNeeded();
 
         updateAutoMarginsInMainAxis(child, autoMarginOffset);

Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (136323 => 136324)


--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h	2012-12-02 10:31:42 UTC (rev 136323)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h	2012-12-02 10:39:51 UTC (rev 136324)
@@ -134,6 +134,8 @@
     bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
     void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&);
 
+    void resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox*);
+    bool needToStretchChild(RenderBox*);
     void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
     void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
     size_t numberOfInFlowPositionedChildren(const OrderedFlexItemList&) const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to