[LFC] LayoutState constructor shouldn't take LayoutTreeContent
https://bugs.webkit.org/show_bug.cgi?id=206471

Reviewed by Zalan Bujtas.

It just needs the root container.

This is preparation for more performant layout box construction and ownership model in the integration code.

* layout/LayoutContext.h:
* layout/LayoutState.cpp:
(WebCore::Layout::LayoutState::LayoutState):

Take Document (to compute quirks mode) and the root box only.

(WebCore::Layout::LayoutState::displayBoxForRootLayoutBox):
(WebCore::Layout::LayoutState::setViewportSize):
(WebCore::Layout::LayoutState::viewportSize const):
(WebCore::Layout::LayoutState::setIsIntegratedRootBoxFirstChild):
(WebCore::Layout::LayoutState::isIntegratedRootBoxFirstChild const): Deleted.

Make this a bit set by the integration code.

* layout/LayoutState.h:
(WebCore::Layout::LayoutState::root const):
(WebCore::Layout::LayoutState::isIntegratedRootBoxFirstChild const):
(WebCore::Layout::LayoutState::rootRenderer const): Deleted.
* layout/Verification.cpp:
(WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::constraintsForLine):
* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::layout):

Also allocate LayoutState directly from LineLayout using Optional.

* layout/integration/LayoutIntegrationLineLayout.h:
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::printLayoutTreeForLiveDocuments):
* page/FrameViewLayoutContext.cpp:
(WebCore::FrameViewLayoutContext::layoutUsingFormattingContext):
* rendering/updating/RenderTreeUpdater.cpp:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 650ba10..ab4c8ef 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,48 @@
+2020-01-18  Antti Koivisto  <antti@apple.com>
+
+        [LFC] LayoutState constructor shouldn't take LayoutTreeContent
+        https://bugs.webkit.org/show_bug.cgi?id=206471
+
+        Reviewed by Zalan Bujtas.
+
+        It just needs the root container.
+
+        This is preparation for more performant layout box construction and ownership model in the integration code.
+
+        * layout/LayoutContext.h:
+        * layout/LayoutState.cpp:
+        (WebCore::Layout::LayoutState::LayoutState):
+
+        Take Document (to compute quirks mode) and the root box only.
+
+        (WebCore::Layout::LayoutState::displayBoxForRootLayoutBox):
+        (WebCore::Layout::LayoutState::setViewportSize):
+        (WebCore::Layout::LayoutState::viewportSize const):
+        (WebCore::Layout::LayoutState::setIsIntegratedRootBoxFirstChild):
+        (WebCore::Layout::LayoutState::isIntegratedRootBoxFirstChild const): Deleted.
+
+        Make this a bit set by the integration code.
+
+        * layout/LayoutState.h:
+        (WebCore::Layout::LayoutState::root const):
+        (WebCore::Layout::LayoutState::isIntegratedRootBoxFirstChild const):
+        (WebCore::Layout::LayoutState::rootRenderer const): Deleted.
+        * layout/Verification.cpp:
+        (WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree):
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::constraintsForLine):
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::LineLayout::layout):
+
+        Also allocate LayoutState directly from LineLayout using Optional.
+
+        * layout/integration/LayoutIntegrationLineLayout.h:
+        * layout/layouttree/LayoutTreeBuilder.cpp:
+        (WebCore::Layout::printLayoutTreeForLiveDocuments):
+        * page/FrameViewLayoutContext.cpp:
+        (WebCore::FrameViewLayoutContext::layoutUsingFormattingContext):
+        * rendering/updating/RenderTreeUpdater.cpp:
+
 2020-01-18  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Rename trailing collapsible content to trailing trimmable
diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h
index e454f1b..a071804 100644
--- a/Source/WebCore/layout/LayoutContext.h
+++ b/Source/WebCore/layout/LayoutContext.h
@@ -63,7 +63,7 @@
     static void paint(const LayoutState&, GraphicsContext&, const IntRect& dirtyRect);
 #ifndef NDEBUG
     // For testing purposes only
-    static void verifyAndOutputMismatchingLayoutTree(const LayoutState&);
+    static void verifyAndOutputMismatchingLayoutTree(const LayoutState&, const RenderView&);
 #endif
 
 private:
diff --git a/Source/WebCore/layout/LayoutState.cpp b/Source/WebCore/layout/LayoutState.cpp
index 718f0e5..e0c8e78 100644
--- a/Source/WebCore/layout/LayoutState.cpp
+++ b/Source/WebCore/layout/LayoutState.cpp
@@ -44,14 +44,13 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(LayoutState);
 
-LayoutState::LayoutState(const LayoutTreeContent& layoutTreeContent)
-    : m_layoutTreeContent(makeWeakPtr(layoutTreeContent))
+LayoutState::LayoutState(const Document& document, const Container& rootContainer)
+    : m_rootContainer(makeWeakPtr(rootContainer))
 {
     // It makes absolutely no sense to construct a dedicated layout state for a non-formatting context root (layout would be a no-op).
-    ASSERT(m_layoutTreeContent->rootLayoutBox().establishesFormattingContext());
+    ASSERT(root().establishesFormattingContext());
 
     auto quirksMode = [&] {
-        auto& document = m_layoutTreeContent->rootRenderer().document();
         if (document.inLimitedQuirksMode())
             return LayoutState::QuirksMode::Limited;
         if (document.inQuirksMode())
@@ -65,7 +64,7 @@
 
 Display::Box& LayoutState::displayBoxForRootLayoutBox()
 {
-    return ensureDisplayBoxForLayoutBox(m_layoutTreeContent->rootLayoutBox());
+    return ensureDisplayBoxForLayoutBox(root());
 }
 
 Display::Box& LayoutState::ensureDisplayBoxForLayoutBoxSlow(const Box& layoutBox)
@@ -139,30 +138,20 @@
 
 void LayoutState::setViewportSize(const LayoutSize& viewportSize)
 {
-    if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()) {
-        m_viewportSize = viewportSize;
-        return;
-    }
-    ASSERT_NOT_REACHED();
+    ASSERT(RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled());
+    m_viewportSize = viewportSize;
 }
 
 LayoutSize LayoutState::viewportSize() const
 {
-    if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled())
-        return m_viewportSize;
-    ASSERT_NOT_REACHED();
-    return { };
+    ASSERT(RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled());
+    return m_viewportSize;
 }
 
-bool LayoutState::isIntegratedRootBoxFirstChild() const
+void LayoutState::setIsIntegratedRootBoxFirstChild(bool value)
 {
-    if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()) {
-        auto& rootRenderer = m_layoutTreeContent->rootRenderer();
-        ASSERT(rootRenderer.parent());
-        return rootRenderer.parent()->firstChild() == &rootRenderer;
-    }
-    ASSERT_NOT_REACHED();
-    return false;
+    ASSERT(RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled());
+    m_isIntegratedRootBoxFirstChild = value;
 }
 
 }
diff --git a/Source/WebCore/layout/LayoutState.h b/Source/WebCore/layout/LayoutState.h
index b71be40..8088b5e 100644
--- a/Source/WebCore/layout/LayoutState.h
+++ b/Source/WebCore/layout/LayoutState.h
@@ -28,7 +28,6 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "LayoutContainer.h"
-#include "LayoutTreeBuilder.h"
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/IsoMalloc.h>
@@ -48,7 +47,7 @@
 class LayoutState : public CanMakeWeakPtr<LayoutState> {
     WTF_MAKE_ISO_ALLOCATED(LayoutState);
 public:
-    LayoutState(const LayoutTreeContent&);
+    LayoutState(const Document&, const Container& rootContainer);
     ~LayoutState();
 
     FormattingState& createFormattingStateForFormattingRootIfNeeded(const Container& formattingContextRoot);
@@ -72,15 +71,13 @@
     bool inLimitedQuirksMode() const { return m_quirksMode == QuirksMode::Limited; }
     bool inNoQuirksMode() const { return m_quirksMode == QuirksMode::No; }
 
-    const Container& root() const { return m_layoutTreeContent->rootLayoutBox(); }
-#ifndef NDEBUG
-    const RenderBox& rootRenderer() const { return m_layoutTreeContent->rootRenderer(); }
-#endif
+    const Container& root() const { return *m_rootContainer; }
 
     // LFC integration only. Full LFC has proper ICB access.
     void setViewportSize(const LayoutSize&);
     LayoutSize viewportSize() const;
-    bool isIntegratedRootBoxFirstChild() const;
+    bool isIntegratedRootBoxFirstChild() const { return m_isIntegratedRootBoxFirstChild; }
+    void setIsIntegratedRootBoxFirstChild(bool);
 
 private:
     void setQuirksMode(QuirksMode quirksMode) { m_quirksMode = quirksMode; }
@@ -93,9 +90,11 @@
     HashMap<const Box*, std::unique_ptr<Display::Box>> m_layoutToDisplayBox;
     QuirksMode m_quirksMode { QuirksMode::No };
 
-    WeakPtr<const LayoutTreeContent> m_layoutTreeContent;
+    WeakPtr<const Container> m_rootContainer;
+
     // LFC integration only.
     LayoutSize m_viewportSize;
+    bool m_isIntegratedRootBoxFirstChild { false };
 };
 
 inline bool LayoutState::hasDisplayBox(const Box& layoutBox) const
diff --git a/Source/WebCore/layout/Verification.cpp b/Source/WebCore/layout/Verification.cpp
index 7e19148..da10510 100644
--- a/Source/WebCore/layout/Verification.cpp
+++ b/Source/WebCore/layout/Verification.cpp
@@ -334,11 +334,10 @@
     return mismtachingGeometry;
 }
 
-void LayoutContext::verifyAndOutputMismatchingLayoutTree(const LayoutState& layoutState)
+void LayoutContext::verifyAndOutputMismatchingLayoutTree(const LayoutState& layoutState, const RenderView& rootRenderer)
 {
     TextStream stream;
     auto& layoutRoot = layoutState.root();
-    auto& rootRenderer = layoutState.rootRenderer();
     auto mismatchingGeometry = verifyAndOutputSubtree(stream, layoutState, rootRenderer, layoutRoot);
     if (!mismatchingGeometry)
         return;
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
index ab6cc2e..b2a5318 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
@@ -422,8 +422,9 @@
             // Unless otherwise specified by the each-line and/or hanging keywords, only lines that are the first formatted line
             // of an element are affected.
             // For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
-            isFormattingContextRootCandidateToTextIndent = RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled() ?
-            layoutState().isIntegratedRootBoxFirstChild() : root.parent()->firstInFlowChild() == &root;
+            isFormattingContextRootCandidateToTextIndent = RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()
+                ? layoutState().isIntegratedRootBoxFirstChild()
+                : root.parent()->firstInFlowChild() == &root;
         }
         if (!isFormattingContextRootCandidateToTextIndent)
             return InlineLayoutUnit { };
diff --git a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
index ec12389..2f63977 100644
--- a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
+++ b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
@@ -95,8 +95,10 @@
 
 void LineLayout::layout()
 {
-    if (!m_layoutState)
-        m_layoutState = makeUnique<Layout::LayoutState>(*m_treeContent);
+    if (!m_layoutState) {
+        m_layoutState.emplace(m_flow.document(), m_treeContent->rootLayoutBox());
+        m_layoutState->setIsIntegratedRootBoxFirstChild(m_flow.parent()->firstChild() == &m_flow);
+    }
 
     prepareRootGeometryForLayout();
 
diff --git a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
index 0ca6503..cf625c3 100644
--- a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
+++ b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "LayoutPoint.h"
+#include "LayoutState.h"
 #include "LineLayoutTraversal.h"
 #include "RenderObjectEnums.h"
 
@@ -47,7 +48,6 @@
 
 namespace Layout {
 class LayoutTreeContent;
-class LayoutState;
 }
 
 namespace LayoutIntegration {
@@ -87,7 +87,7 @@
 
     const RenderBlockFlow& m_flow;
     std::unique_ptr<Layout::LayoutTreeContent> m_treeContent;
-    std::unique_ptr<Layout::LayoutState> m_layoutState;
+    Optional<Layout::LayoutState> m_layoutState;
     LayoutUnit m_contentLogicalHeight;
 };
 
diff --git a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
index 0de605e..1fd3986 100644
--- a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
+++ b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
@@ -452,7 +452,7 @@
         // FIXME: Need to find a way to output geometry without layout context.
         auto& renderView = *document->renderView();
         auto layoutTreeContent = TreeBuilder::buildLayoutTree(renderView);
-        auto layoutState = LayoutState { *layoutTreeContent };
+        auto layoutState = LayoutState { *document, layoutTreeContent->rootLayoutBox() };
 
         auto& layoutRoot = layoutState.root();
         auto invalidationState = InvalidationState { };
diff --git a/Source/WebCore/page/FrameViewLayoutContext.cpp b/Source/WebCore/page/FrameViewLayoutContext.cpp
index 0e7844d..5b3b6cd 100644
--- a/Source/WebCore/page/FrameViewLayoutContext.cpp
+++ b/Source/WebCore/page/FrameViewLayoutContext.cpp
@@ -72,7 +72,7 @@
         m_layoutState = nullptr;
     }
     if (!m_layoutState)
-        m_layoutState = makeUnique<Layout::LayoutState>(*m_layoutTreeContent);
+        m_layoutState = makeUnique<Layout::LayoutState>(*document(), m_layoutTreeContent->rootLayoutBox());
 
     // FIXME: This is not the real invalidation yet.
     auto invalidationState = Layout::InvalidationState { };
@@ -91,7 +91,7 @@
     }
 
 #ifndef NDEBUG
-    Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree(*m_layoutState);
+    Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree(*m_layoutState, renderView);
 #endif
 }
 
diff --git a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
index 231bb08..38c3be0 100644
--- a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
+++ b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
@@ -56,6 +56,7 @@
 #include "FrameView.h"
 #include "FrameViewLayoutContext.h"
 #include "LayoutState.h"
+#include "LayoutTreeBuilder.h"
 #endif
 
 #if PLATFORM(IOS_FAMILY)