Diff
Modified: trunk/LayoutTests/ChangeLog (252715 => 252716)
--- trunk/LayoutTests/ChangeLog 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/LayoutTests/ChangeLog 2019-11-20 23:52:40 UTC (rev 252716)
@@ -1,3 +1,13 @@
+2019-11-20 Zalan Bujtas <[email protected]>
+
+ Flexbox sizing logic triggers full repaint on the flex items.
+ https://bugs.webkit.org/show_bug.cgi?id=204380
+ <rdar://problem/57236404>
+
+ Reviewed by Simon Fraser.
+
+ * fast/repaint/align-items-change-expected.txt: progression.
+
2019-11-20 Justin Fan <[email protected]>
webgl/1.0.3/conformance/context/context-release-upon-reload.html is flaky
Modified: trunk/LayoutTests/fast/repaint/align-items-change-expected.txt (252715 => 252716)
--- trunk/LayoutTests/fast/repaint/align-items-change-expected.txt 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/LayoutTests/fast/repaint/align-items-change-expected.txt 2019-11-20 23:52:40 UTC (rev 252716)
@@ -1,10 +1,10 @@
Tests invalidation on align-items style change. Passes if there is no red.
(repaint rects
- (rect 0 52 100 300)
- (rect 0 51 100 1)
- (rect 100 52 100 300)
- (rect 100 51 100 1)
+ (rect 0 154 100 198)
+ (rect 0 153 100 1)
+ (rect 100 204 100 148)
+ (rect 100 203 100 1)
(rect 0 52 200 300)
)
Modified: trunk/Source/WebCore/ChangeLog (252715 => 252716)
--- trunk/Source/WebCore/ChangeLog 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/ChangeLog 2019-11-20 23:52:40 UTC (rev 252716)
@@ -1,3 +1,44 @@
+2019-11-20 Zalan Bujtas <[email protected]>
+
+ Flexbox sizing logic triggers full repaint on the flex items.
+ https://bugs.webkit.org/show_bug.cgi?id=204380
+ <rdar://problem/57236404>
+
+ Reviewed by Simon Fraser.
+
+ RenderFlexibleBox::applyStretchAlignmentToChild explicitly sets the child renderer's height to 0 before issuing layout on it.
+ This confuses the child's repaint logic and could trigger unnecessary repaints on complete subtrees.
+
+ Many ::layout functions plant a LayoutRepainter stack object to track and report paint invalidations.
+ It works as long as the renderer's geometry change happens within the scope of this LayoutRepainter.
+ When the parent (RenderFlexibleBox) mutates the renderer's geometry, the LayoutRepainter object sees
+ this already mutated state as the initial state and will happily issue repaints even when the final
+ geometry remains the same.
+
+ This patch addresses the redundant repaint by pushing the height reset from the parent down to the child, inside the LayoutRepainter scope.
+
+ * rendering/RenderBlock.h: Restrict it to RenderBlock level for now. It might need to go all the way up to RenderBox.
+ (WebCore::RenderBlock::shouldResetChildLogicalHeightBeforeLayout const):
+ * rendering/RenderBlockFlow.cpp:
+ (WebCore::RenderBlockFlow::layoutBlock):
+ * rendering/RenderBlockFlow.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::resetLogicalHeightBeforeLayoutIfNeeded):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::shouldResetLogicalHeightBeforeLayout const):
+ * rendering/RenderDeprecatedFlexibleBox.cpp:
+ (WebCore::RenderDeprecatedFlexibleBox::layoutBlock):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutBlock):
+ (WebCore::RenderFlexibleBox::applyStretchAlignmentToChild):
+ * rendering/RenderFlexibleBox.h:
+ * rendering/RenderGrid.cpp:
+ (WebCore::RenderGrid::layoutBlock):
+ * rendering/RenderGrid.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::layout):
+ * rendering/RenderTable.h:
+
2019-11-20 Myles C. Maxfield <[email protected]>
[Cocoa] Add ui-sans-serif as a sibling to ui-serif, ui-monospace, and ui-rounded
Modified: trunk/Source/WebCore/rendering/RenderBlock.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderBlock.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderBlock.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -315,7 +315,9 @@
Optional<LayoutUnit> availableLogicalHeightForPercentageComputation() const;
bool hasDefiniteLogicalHeight() const;
-
+
+ virtual bool shouldResetChildLogicalHeightBeforeLayout(const RenderBox&) const { return false; }
+
protected:
RenderFragmentedFlow* locateEnclosingFragmentedFlow() const override;
void willBeDestroyed() override;
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -472,7 +472,7 @@
LayoutUnit previousHeight = logicalHeight();
// FIXME: should this start out as borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(),
// for consistency with other render classes?
- setLogicalHeight(0);
+ resetLogicalHeightBeforeLayoutIfNeeded();
bool pageLogicalHeightChanged = false;
checkForPaginationLogicalHeightChange(relayoutChildren, pageLogicalHeight, pageLogicalHeightChanged);
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -391,6 +391,8 @@
void addFloatsToNewParent(RenderBlockFlow& toBlockFlow) const;
protected:
+ bool shouldResetLogicalHeightBeforeLayout() const override { return true; }
+
void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -567,6 +567,12 @@
return hasOverflowClip() && layer() ? layer()->scrollPosition().y() : 0;
}
+void RenderBox::resetLogicalHeightBeforeLayoutIfNeeded()
+{
+ if (shouldResetLogicalHeightBeforeLayout() || (is<RenderBlock>(parent()) && downcast<RenderBlock>(*parent()).shouldResetChildLogicalHeightBeforeLayout(*this)))
+ setLogicalHeight(0_lu);
+}
+
static void setupWheelEventMonitor(RenderLayer& layer)
{
Page& page = layer.renderer().page();
Modified: trunk/Source/WebCore/rendering/RenderBox.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderBox.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderBox.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -654,6 +654,9 @@
bool createsNewFormattingContext() const;
+ virtual bool shouldResetLogicalHeightBeforeLayout() const { return false; }
+ void resetLogicalHeightBeforeLayoutIfNeeded();
+
virtual ItemPosition selfAlignmentNormalBehavior(const RenderBox* = nullptr) const { return ItemPosition::Stretch; }
// Returns false if it could not cheaply compute the extent (e.g. fixed background), in which case the returned rect may be incorrect.
Modified: trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -285,6 +285,7 @@
{
LayoutStateMaintainer statePusher(*this, locationOffset(), hasTransform() || hasReflection() || style().isFlippedBlocksWritingMode());
+ resetLogicalHeightBeforeLayoutIfNeeded();
preparePaginationBeforeBlockLayout(relayoutChildren);
LayoutSize previousSize = size();
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -262,6 +262,7 @@
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+ resetLogicalHeightBeforeLayoutIfNeeded();
m_relaidOutChildren.clear();
bool oldInLayout = m_inLayout;
@@ -1839,10 +1840,10 @@
if (childNeedsRelayout || !child.hasOverrideContentLogicalHeight())
child.setOverrideContentLogicalHeight(desiredLogicalHeight - child.borderAndPaddingLogicalHeight());
if (childNeedsRelayout) {
- child.setLogicalHeight(0_lu);
+ SetForScope<bool> resetChildLogicalHeight(m_shouldResetChildLogicalHeightBeforeLayout, true);
// We cache the child's intrinsic content logical height to avoid it being
// reset to the stretched height.
- // FIXME: This is fragile. RendertBoxes should be smart enough to
+ // FIXME: This is fragile. RenderBoxes should be smart enough to
// determine their intrinsic content logical height correctly even when
// there's an overrideHeight.
LayoutUnit childIntrinsicContentLogicalHeight = cachedChildIntrinsicContentLogicalHeight(child);
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -92,6 +92,8 @@
void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
void computePreferredLogicalWidths() override;
+ bool shouldResetChildLogicalHeightBeforeLayout(const RenderBox&) const override { return m_shouldResetChildLogicalHeightBeforeLayout; }
+
private:
enum FlexSign {
PositiveFlexibility,
@@ -211,6 +213,7 @@
// This is SizeIsUnknown outside of layoutBlock()
mutable SizeDefiniteness m_hasDefiniteHeight { SizeDefiniteness::Unknown };
bool m_inLayout { false };
+ bool m_shouldResetChildLogicalHeightBeforeLayout { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderGrid.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -219,7 +219,7 @@
m_trackSizingAlgorithm.cacheBaselineAlignedItem(*child, GridRowAxis);
}
m_baselineItemsCached = true;
- setLogicalHeight(0);
+ resetLogicalHeightBeforeLayoutIfNeeded();
updateLogicalWidth();
// Fieldsets need to find their legend and position it inside the border of the object.
Modified: trunk/Source/WebCore/rendering/RenderGrid.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderGrid.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderGrid.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -186,6 +186,8 @@
LayoutUnit translateOutOfFlowRTLCoordinate(const RenderBox&, LayoutUnit) const;
LayoutUnit translateRTLCoordinate(LayoutUnit) const;
+ bool shouldResetLogicalHeightBeforeLayout() const override { return true; }
+
Grid m_grid;
GridTrackSizingAlgorithm m_trackSizingAlgorithm;
Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderTable.cpp 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp 2019-11-20 23:52:40 UTC (rev 252716)
@@ -433,7 +433,7 @@
LayoutUnit oldLogicalWidth = logicalWidth();
LayoutUnit oldLogicalHeight = logicalHeight();
- setLogicalHeight(0);
+ resetLogicalHeightBeforeLayoutIfNeeded();
updateLogicalWidth();
if (logicalWidth() != oldLogicalWidth) {
Modified: trunk/Source/WebCore/rendering/RenderTable.h (252715 => 252716)
--- trunk/Source/WebCore/rendering/RenderTable.h 2019-11-20 23:31:01 UTC (rev 252715)
+++ trunk/Source/WebCore/rendering/RenderTable.h 2019-11-20 23:52:40 UTC (rev 252716)
@@ -361,6 +361,8 @@
return false;
}
+ bool shouldResetLogicalHeightBeforeLayout() const override { return true; }
+
LayoutUnit m_hSpacing;
LayoutUnit m_vSpacing;
LayoutUnit m_borderStart;