Title: [252868] trunk/Source/WebCore
Revision
252868
Author
[email protected]
Date
2019-11-25 15:18:05 -0800 (Mon, 25 Nov 2019)

Log Message

User Variant for RenderBlockFlow line layout
https://bugs.webkit.org/show_bug.cgi?id=204591

Reviewed by Zalan Bujtas.

Move complex and simple line layout structures into a Variant to avoid wasting memory, and to allow easy expansion with an LFC path

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::willBeDestroyed):
(WebCore::RenderBlockFlow::layoutInlineChildren):
(WebCore::RenderBlockFlow::styleDidChange):
(WebCore::RenderBlockFlow::deleteLines):
(WebCore::RenderBlockFlow::hitTestInlineChildren):
(WebCore::RenderBlockFlow::addOverflowFromInlineChildren):
(WebCore::RenderBlockFlow::markLinesDirtyInBlockRange):
(WebCore::RenderBlockFlow::inlineSelectionGaps):
(WebCore::RenderBlockFlow::paintInlineChildren):
(WebCore::RenderBlockFlow::hasLines const):
(WebCore::RenderBlockFlow::invalidateLineLayoutPath):
(WebCore::RenderBlockFlow::layoutSimpleLines):
(WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
(WebCore::RenderBlockFlow::ensureLineBoxes):
* rendering/RenderBlockFlow.h:
(WebCore::RenderBlockFlow::firstRootBox const):
(WebCore::RenderBlockFlow::lastRootBox const):
(WebCore::RenderBlockFlow::hasComplexLineLayout const):
(WebCore::RenderBlockFlow::complexLineLayout const):
(WebCore::RenderBlockFlow::complexLineLayout):
(WebCore::RenderBlockFlow::hasSimpleLineLayout const):
(WebCore::RenderBlockFlow::simpleLineLayout const):
(WebCore::RenderBlockFlow::simpleLineLayout):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (252867 => 252868)


--- trunk/Source/WebCore/ChangeLog	2019-11-25 22:18:59 UTC (rev 252867)
+++ trunk/Source/WebCore/ChangeLog	2019-11-25 23:18:05 UTC (rev 252868)
@@ -1,3 +1,37 @@
+2019-11-25  Antti Koivisto  <[email protected]>
+
+        User Variant for RenderBlockFlow line layout
+        https://bugs.webkit.org/show_bug.cgi?id=204591
+
+        Reviewed by Zalan Bujtas.
+
+        Move complex and simple line layout structures into a Variant to avoid wasting memory, and to allow easy expansion with an LFC path
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::willBeDestroyed):
+        (WebCore::RenderBlockFlow::layoutInlineChildren):
+        (WebCore::RenderBlockFlow::styleDidChange):
+        (WebCore::RenderBlockFlow::deleteLines):
+        (WebCore::RenderBlockFlow::hitTestInlineChildren):
+        (WebCore::RenderBlockFlow::addOverflowFromInlineChildren):
+        (WebCore::RenderBlockFlow::markLinesDirtyInBlockRange):
+        (WebCore::RenderBlockFlow::inlineSelectionGaps):
+        (WebCore::RenderBlockFlow::paintInlineChildren):
+        (WebCore::RenderBlockFlow::hasLines const):
+        (WebCore::RenderBlockFlow::invalidateLineLayoutPath):
+        (WebCore::RenderBlockFlow::layoutSimpleLines):
+        (WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
+        (WebCore::RenderBlockFlow::ensureLineBoxes):
+        * rendering/RenderBlockFlow.h:
+        (WebCore::RenderBlockFlow::firstRootBox const):
+        (WebCore::RenderBlockFlow::lastRootBox const):
+        (WebCore::RenderBlockFlow::hasComplexLineLayout const):
+        (WebCore::RenderBlockFlow::complexLineLayout const):
+        (WebCore::RenderBlockFlow::complexLineLayout):
+        (WebCore::RenderBlockFlow::hasSimpleLineLayout const):
+        (WebCore::RenderBlockFlow::simpleLineLayout const):
+        (WebCore::RenderBlockFlow::simpleLineLayout):
+
 2019-11-25  Zalan Bujtas  <[email protected]>
 
         [LFC] Do not run layout when setNeedsLayout is disabled

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (252867 => 252868)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2019-11-25 22:18:59 UTC (rev 252867)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2019-11-25 23:18:05 UTC (rev 252868)
@@ -152,8 +152,8 @@
             parent()->dirtyLinesFromChangedChild(*this);
     }
 
-    if (m_complexLineLayout)
-        m_complexLineLayout->lineBoxes().deleteLineBoxes();
+    if (complexLineLayout())
+        complexLineLayout()->lineBoxes().deleteLineBoxes();
 
     blockWillBeDestroyed();
 
@@ -675,12 +675,10 @@
         return;
     }
 
-    m_simpleLineLayout = nullptr;
+    if (!complexLineLayout())
+        m_lineLayout = makeUnique<ComplexLineLayout>(*this);
 
-    if (!m_complexLineLayout)
-        m_complexLineLayout = makeUnique<ComplexLineLayout>(*this);
-
-    m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+    complexLineLayout()->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
 }
 
 void RenderBlockFlow::layoutBlockChild(RenderBox& child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
@@ -2071,7 +2069,7 @@
 
     if (diff >= StyleDifference::Repaint) {
         // FIXME: This could use a cheaper style-only test instead of SimpleLineLayout::canUseFor.
-        if (selfNeedsLayout() || !m_simpleLineLayout || !SimpleLineLayout::canUseFor(*this))
+        if (selfNeedsLayout() || !simpleLineLayout() || !SimpleLineLayout::canUseFor(*this))
             invalidateLineLayoutPath();
     }
 
@@ -2108,11 +2106,10 @@
     if (containsFloats())
         m_floatingObjects->clearLineBoxTreePointers();
 
-    if (m_simpleLineLayout) {
-        ASSERT(!m_complexLineLayout);
-        m_simpleLineLayout = nullptr;
-    } else if (m_complexLineLayout)
-        m_complexLineLayout->lineBoxes().deleteLineBoxTree();
+    if (complexLineLayout())
+        complexLineLayout()->lineBoxes().deleteLineBoxTree();
+    else
+        m_lineLayout = nullptr;
 
     RenderBlock::deleteLines();
 }
@@ -2949,7 +2946,7 @@
     if (auto simpleLineLayout = this->simpleLineLayout())
         return SimpleLineLayout::hitTestFlow(*this, *simpleLineLayout, request, result, locationInContainer, accumulatedOffset, hitTestAction);
 
-    return m_complexLineLayout && m_complexLineLayout->lineBoxes().hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
+    return complexLineLayout() && complexLineLayout()->lineBoxes().hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
 }
 
 void RenderBlockFlow::addOverflowFromInlineChildren()
@@ -2960,7 +2957,7 @@
         return;
     }
 
-    m_complexLineLayout->addOverflowFromInlineChildren();
+    complexLineLayout()->addOverflowFromInlineChildren();
 }
 
 void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
@@ -3041,7 +3038,7 @@
         return;
 
     // Floats currently affect the choice whether to use simple line layout path.
-    if (m_simpleLineLayout) {
+    if (simpleLineLayout()) {
         invalidateLineLayoutPath();
         return;
     }
@@ -3128,7 +3125,7 @@
 GapRects RenderBlockFlow::inlineSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
 {
-    ASSERT(!m_simpleLineLayout);
+    ASSERT(!simpleLineLayout());
 
     GapRects result;
 
@@ -3543,8 +3540,8 @@
         return;
     }
 
-    if (m_complexLineLayout)
-        m_complexLineLayout->lineBoxes().paint(this, paintInfo, paintOffset);
+    if (complexLineLayout())
+        complexLineLayout()->lineBoxes().paint(this, paintInfo, paintOffset);
 }
 
 bool RenderBlockFlow::relayoutForPagination()
@@ -3599,7 +3596,7 @@
     if (auto simpleLineLayout = this->simpleLineLayout())
         return simpleLineLayout->lineCount();
 
-    return m_complexLineLayout && m_complexLineLayout->lineBoxes().firstLineBox();
+    return complexLineLayout() && complexLineLayout()->lineBoxes().firstLineBox();
 }
 
 void RenderBlockFlow::invalidateLineLayoutPath()
@@ -3607,15 +3604,15 @@
     switch (lineLayoutPath()) {
     case UndeterminedPath:
     case ForceLineBoxesPath:
-        ASSERT(!m_simpleLineLayout);
+        ASSERT(!simpleLineLayout());
         return;
     case LineBoxesPath:
-        ASSERT(!m_simpleLineLayout);
+        ASSERT(!simpleLineLayout());
         setLineLayoutPath(UndeterminedPath);
         return;
     case SimpleLinesPath:
         // The simple line layout may have become invalid.
-        m_simpleLineLayout = nullptr;
+        m_lineLayout = nullptr;
         setLineLayoutPath(UndeterminedPath);
         if (needsLayout())
             return;
@@ -3628,19 +3625,22 @@
 
 void RenderBlockFlow::layoutSimpleLines(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
 {
-    bool needsLayout = selfNeedsLayout() || relayoutChildren || !m_simpleLineLayout;
+    bool needsLayout = selfNeedsLayout() || relayoutChildren || !simpleLineLayout();
     if (needsLayout) {
         deleteLineBoxesBeforeSimpleLineLayout();
-        m_simpleLineLayout = SimpleLineLayout::create(*this);
+        m_lineLayout = SimpleLineLayout::create(*this);
     }
+    auto& simpleLineLayout = *this->simpleLineLayout();
+
     if (view().frameView().layoutContext().layoutState() && view().frameView().layoutContext().layoutState()->isPaginated()) {
-        m_simpleLineLayout->setIsPaginated();
-        SimpleLineLayout::adjustLinePositionsForPagination(*m_simpleLineLayout, *this);
+        simpleLineLayout.setIsPaginated();
+        SimpleLineLayout::adjustLinePositionsForPagination(simpleLineLayout, *this);
     }
+
     for (auto& renderer : childrenOfType<RenderObject>(*this))
         renderer.clearNeedsLayout();
-    ASSERT(!m_complexLineLayout);
-    LayoutUnit lineLayoutHeight = SimpleLineLayout::computeFlowHeight(*this, *m_simpleLineLayout);
+
+    LayoutUnit lineLayoutHeight = SimpleLineLayout::computeFlowHeight(*this, simpleLineLayout);
     LayoutUnit lineLayoutTop = borderAndPaddingBefore();
     repaintLogicalTop = lineLayoutTop;
     repaintLogicalBottom = needsLayout ? repaintLogicalTop + lineLayoutHeight + borderAndPaddingAfter() : repaintLogicalTop;
@@ -3651,8 +3651,8 @@
 {
     ASSERT(lineLayoutPath() == SimpleLinesPath);
 
-    if (m_complexLineLayout)
-        m_complexLineLayout->lineBoxes().deleteLineBoxes();
+    if (complexLineLayout())
+        complexLineLayout()->lineBoxes().deleteLineBoxes();
 
     for (auto& renderer : childrenOfType<RenderObject>(*this)) {
         if (is<RenderText>(renderer))
@@ -3663,7 +3663,7 @@
             ASSERT_NOT_REACHED();
     }
 
-    m_complexLineLayout = nullptr;
+    m_lineLayout = nullptr;
 }
 
 void RenderBlockFlow::ensureLineBoxes()
@@ -3673,20 +3673,20 @@
 
     setLineLayoutPath(ForceLineBoxesPath);
 
-    if (!m_simpleLineLayout)
+    if (!simpleLineLayout())
         return;
 
-    ASSERT(!m_complexLineLayout);
-    m_complexLineLayout = makeUnique<ComplexLineLayout>(*this);
+    auto simpleLineLayout = makeRef(*this->simpleLineLayout());
 
-    if (SimpleLineLayout::canUseForLineBoxTree(*this, *m_simpleLineLayout)) {
-        SimpleLineLayout::generateLineBoxTree(*this, *m_simpleLineLayout);
-        m_simpleLineLayout = nullptr;
+    m_lineLayout = makeUnique<ComplexLineLayout>(*this);
+
+    if (SimpleLineLayout::canUseForLineBoxTree(*this, simpleLineLayout.get())) {
+        SimpleLineLayout::generateLineBoxTree(*this, simpleLineLayout.get());
         return;
     }
-    bool isPaginated = m_simpleLineLayout->isPaginated();
-    m_simpleLineLayout = nullptr;
 
+    auto& complexLineLayout = *this->complexLineLayout();
+
 #if !ASSERT_DISABLED
     LayoutUnit oldHeight = logicalHeight();
 #endif
@@ -3695,16 +3695,16 @@
     bool relayoutChildren = false;
     LayoutUnit repaintLogicalTop;
     LayoutUnit repaintLogicalBottom;
-    if (isPaginated) {
+    if (simpleLineLayout->isPaginated()) {
         PaginatedLayoutStateMaintainer state(*this);
-        m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+        complexLineLayout.layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
         // This matches relayoutToAvoidWidows.
         if (shouldBreakAtLineToAvoidWidow())
-            m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+            complexLineLayout.layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
         // FIXME: This is needed as long as simple and normal line layout produce different line breakings.
         repaint();
     } else
-        m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+        complexLineLayout.layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
 
     updateLogicalHeight();
     ASSERT(didNeedLayout || logicalHeight() == oldHeight);

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (252867 => 252868)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2019-11-25 22:18:59 UTC (rev 252867)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2019-11-25 23:18:05 UTC (rev 252868)
@@ -72,8 +72,8 @@
 
     void dirtyLinesFromChangedChild(RenderObject& child) final
     {
-        if (m_complexLineLayout)
-            m_complexLineLayout->lineBoxes().dirtyLinesFromChangedChild(*this, child);
+        if (complexLineLayout())
+            complexLineLayout()->lineBoxes().dirtyLinesFromChangedChild(*this, child);
     }
 
     void paintColumnRules(PaintInfo&, const LayoutPoint&) override;
@@ -332,8 +332,8 @@
 
     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject&, const LayoutPoint&) const;
 
-    RootInlineBox* firstRootBox() const { return m_complexLineLayout ? m_complexLineLayout->firstRootBox() : nullptr; }
-    RootInlineBox* lastRootBox() const { return m_complexLineLayout ? m_complexLineLayout->lastRootBox() : nullptr; }
+    RootInlineBox* firstRootBox() const { return complexLineLayout() ? complexLineLayout()->firstRootBox() : nullptr; }
+    RootInlineBox* lastRootBox() const { return complexLineLayout() ? complexLineLayout()->lastRootBox() : nullptr; }
 
     bool hasLines() const;
     void invalidateLineLayoutPath() final;
@@ -354,6 +354,10 @@
     bool containsNonZeroBidiLevel() const;
 
     const SimpleLineLayout::Layout* simpleLineLayout() const;
+    SimpleLineLayout::Layout* simpleLineLayout();
+    const ComplexLineLayout* complexLineLayout() const;
+    ComplexLineLayout* complexLineLayout();
+
     void deleteLineBoxesBeforeSimpleLineLayout();
     void ensureLineBoxes();
     void generateLineBoxTree();
@@ -523,12 +527,13 @@
     void addFocusRingRectsForInlineChildren(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) override;
 
 public:
-    ComplexLineLayout* complexLineLayout() { return m_complexLineLayout.get(); }
-
     virtual Optional<TextAlignMode> overrideTextAlignmentForLine(bool /* endsWithSoftBreak */) const { return { }; }
     virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
 
 private:
+    bool hasSimpleLineLayout() const;
+    bool hasComplexLineLayout() const;
+
     void layoutSimpleLines(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
 
     void adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
@@ -567,9 +572,8 @@
     std::unique_ptr<FloatingObjects> m_floatingObjects;
     std::unique_ptr<RenderBlockFlowRareData> m_rareBlockFlowData;
 
-    // FIXME: Only one of these should be needed at any given time.
-    std::unique_ptr<ComplexLineLayout> m_complexLineLayout;
-    RefPtr<SimpleLineLayout::Layout> m_simpleLineLayout;
+private:
+    Variant<std::nullptr_t, std::unique_ptr<ComplexLineLayout>, Ref<SimpleLineLayout::Layout>> m_lineLayout;
 
     friend class LineBreaker;
     friend class LineWidth; // Needs to know FloatingObject
@@ -576,12 +580,36 @@
     friend class ComplexLineLayout;
 };
 
+inline bool RenderBlockFlow::hasComplexLineLayout() const
+{
+    return WTF::holds_alternative<std::unique_ptr<ComplexLineLayout>>(m_lineLayout);
+}
+
+inline const ComplexLineLayout* RenderBlockFlow::complexLineLayout() const
+{
+    return hasComplexLineLayout() ? WTF::get<std::unique_ptr<ComplexLineLayout>>(m_lineLayout).get() : nullptr;
+}
+
+inline ComplexLineLayout* RenderBlockFlow::complexLineLayout()
+{
+    return hasComplexLineLayout() ? WTF::get<std::unique_ptr<ComplexLineLayout>>(m_lineLayout).get() : nullptr;
+}
+
+inline bool RenderBlockFlow::hasSimpleLineLayout() const
+{
+    return WTF::holds_alternative<Ref<SimpleLineLayout::Layout>>(m_lineLayout);
+}
+
 inline const SimpleLineLayout::Layout* RenderBlockFlow::simpleLineLayout() const
 {
-    ASSERT(lineLayoutPath() == SimpleLinesPath || !m_simpleLineLayout);
-    return m_simpleLineLayout.get();
+    return hasSimpleLineLayout() ? WTF::get<Ref<SimpleLineLayout::Layout>>(m_lineLayout).ptr() : nullptr;
 }
 
+inline SimpleLineLayout::Layout* RenderBlockFlow::simpleLineLayout()
+{
+    return hasSimpleLineLayout() ? WTF::get<Ref<SimpleLineLayout::Layout>>(m_lineLayout).ptr() : nullptr;
+}
+
 } // namespace WebCore
 
 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderBlockFlow, isRenderBlockFlow())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to