Title: [254806] trunk/Source/WebCore
Revision
254806
Author
[email protected]
Date
2020-01-19 08:30:27 -0800 (Sun, 19 Jan 2020)

Log Message

[LFC][Integration] Use integration specific layout tree builder and data structures
https://bugs.webkit.org/show_bug.cgi?id=206483

Reviewed by Zalan Bujtas.

The generic tree builder and the LayoutTreeContent class are not optimal for integrated layout.

This patch adds LayoutIntegration::BoxTree type for building and owning Layout::Boxes for a single flow.
It also devirtualizes Layout::Box for faster destruction (the only virtual function was the destructor).

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/integration/LayoutIntegrationBoxTree.cpp: Added.
(WebCore::LayoutIntegration::BoxTree::BoxTree):
(WebCore::LayoutIntegration::BoxTree::buildTree):

Only handle supported content.

(WebCore::LayoutIntegration::BoxTree::layoutBoxForRenderer const):
(WebCore::LayoutIntegration::BoxTree::rendererForLayoutBox const):

For small content just traverse the vector. Construct lookup maps lazily for larger content.

* layout/integration/LayoutIntegrationBoxTree.h: Copied from Source/WebCore/layout/layouttree/LayoutContainer.h.
(WebCore::LayoutIntegration::BoxTree::rootLayoutBox const):
(WebCore::LayoutIntegration::BoxTree::rootLayoutBox):
* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::LineLayout):
(WebCore::LayoutIntegration::LineLayout::layout):
(WebCore::LayoutIntegration::LineLayout::textBoxesFor const):
(WebCore::LayoutIntegration::LineLayout::elementBoxFor const):
(WebCore::LayoutIntegration::LineLayout::rootLayoutBox const):
(WebCore::LayoutIntegration::LineLayout::rootLayoutBox):
(WebCore::LayoutIntegration::LineLayout::hitTest):
* layout/integration/LayoutIntegrationLineLayout.h:
* layout/layouttree/LayoutBox.cpp:
(WebCore::Layout::Box::~Box):
* layout/layouttree/LayoutBox.h:

Devirtualize.

* layout/layouttree/LayoutContainer.cpp:
(WebCore::Layout::Container::appendChild):
* layout/layouttree/LayoutContainer.h:
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::TreeBuilder::createBox):
(WebCore::Layout::TreeBuilder::createTextBox):
(WebCore::Layout::TreeBuilder::createContainer):
(WebCore::Layout::TreeBuilder::createLayoutBox):

Factor ownership handling to these create functions.

(WebCore::Layout::TreeBuilder::buildTableStructure):
(WebCore::Layout::TreeBuilder::buildSubTree):
* layout/layouttree/LayoutTreeBuilder.h:
(WebCore::Layout::LayoutTreeContent::addBox):
(WebCore::Layout::LayoutTreeContent::addContainer):

Put Boxes and Containers to different maps for correct destruction.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (254805 => 254806)


--- trunk/Source/WebCore/ChangeLog	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/ChangeLog	2020-01-19 16:30:27 UTC (rev 254806)
@@ -1,3 +1,65 @@
+2020-01-19  Antti Koivisto  <[email protected]>
+
+        [LFC][Integration] Use integration specific layout tree builder and data structures
+        https://bugs.webkit.org/show_bug.cgi?id=206483
+
+        Reviewed by Zalan Bujtas.
+
+        The generic tree builder and the LayoutTreeContent class are not optimal for integrated layout.
+
+        This patch adds LayoutIntegration::BoxTree type for building and owning Layout::Boxes for a single flow.
+        It also devirtualizes Layout::Box for faster destruction (the only virtual function was the destructor).
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/integration/LayoutIntegrationBoxTree.cpp: Added.
+        (WebCore::LayoutIntegration::BoxTree::BoxTree):
+        (WebCore::LayoutIntegration::BoxTree::buildTree):
+
+        Only handle supported content.
+
+        (WebCore::LayoutIntegration::BoxTree::layoutBoxForRenderer const):
+        (WebCore::LayoutIntegration::BoxTree::rendererForLayoutBox const):
+
+        For small content just traverse the vector. Construct lookup maps lazily for larger content.
+
+        * layout/integration/LayoutIntegrationBoxTree.h: Copied from Source/WebCore/layout/layouttree/LayoutContainer.h.
+        (WebCore::LayoutIntegration::BoxTree::rootLayoutBox const):
+        (WebCore::LayoutIntegration::BoxTree::rootLayoutBox):
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::LineLayout::LineLayout):
+        (WebCore::LayoutIntegration::LineLayout::layout):
+        (WebCore::LayoutIntegration::LineLayout::textBoxesFor const):
+        (WebCore::LayoutIntegration::LineLayout::elementBoxFor const):
+        (WebCore::LayoutIntegration::LineLayout::rootLayoutBox const):
+        (WebCore::LayoutIntegration::LineLayout::rootLayoutBox):
+        (WebCore::LayoutIntegration::LineLayout::hitTest):
+        * layout/integration/LayoutIntegrationLineLayout.h:
+        * layout/layouttree/LayoutBox.cpp:
+        (WebCore::Layout::Box::~Box):
+        * layout/layouttree/LayoutBox.h:
+
+        Devirtualize.
+
+        * layout/layouttree/LayoutContainer.cpp:
+        (WebCore::Layout::Container::appendChild):
+        * layout/layouttree/LayoutContainer.h:
+        * layout/layouttree/LayoutTreeBuilder.cpp:
+        (WebCore::Layout::TreeBuilder::createBox):
+        (WebCore::Layout::TreeBuilder::createTextBox):
+        (WebCore::Layout::TreeBuilder::createContainer):
+        (WebCore::Layout::TreeBuilder::createLayoutBox):
+
+        Factor ownership handling to these create functions.
+
+        (WebCore::Layout::TreeBuilder::buildTableStructure):
+        (WebCore::Layout::TreeBuilder::buildSubTree):
+        * layout/layouttree/LayoutTreeBuilder.h:
+        (WebCore::Layout::LayoutTreeContent::addBox):
+        (WebCore::Layout::LayoutTreeContent::addContainer):
+
+        Put Boxes and Containers to different maps for correct destruction.
+
 2020-01-19  Zalan Bujtas  <[email protected]>
 
         [LFC][IFC] Move away from placing individual InlineItems on the line

Modified: trunk/Source/WebCore/Sources.txt (254805 => 254806)


--- trunk/Source/WebCore/Sources.txt	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/Sources.txt	2020-01-19 16:30:27 UTC (rev 254806)
@@ -1455,6 +1455,7 @@
 layout/inlineformatting/InlineTextItem.cpp
 layout/inlineformatting/LineLayoutContext.cpp
 layout/inlineformatting/text/TextUtil.cpp
+layout/integration/LayoutIntegrationBoxTree.cpp
 layout/integration/LayoutIntegrationLineLayout.cpp
 layout/invalidation/InvalidationContext.cpp
 layout/invalidation/InvalidationState.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (254805 => 254806)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-01-19 16:30:27 UTC (rev 254806)
@@ -4814,6 +4814,7 @@
 		E3FA38641D71812D00AA5950 /* PendingScriptClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E3FA38611D716E7600AA5950 /* PendingScriptClient.h */; };
 		E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E401E0A41C3C0B8300F34D10 /* StyleChange.h in Headers */ = {isa = PBXBuildFile; fileRef = E401E0A31C3C0B8300F34D10 /* StyleChange.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E419041F1CC6486B00C35F5D /* FontSelectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E419041E1CC6486B00C35F5D /* FontSelectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E42050172141901B0066EF3B /* ProcessWarming.h in Headers */ = {isa = PBXBuildFile; fileRef = E42050142141901A0066EF3B /* ProcessWarming.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E424A39E1330DF0100CF6DC9 /* LegacyTileGridTile.h in Headers */ = {isa = PBXBuildFile; fileRef = E424A39D1330DF0100CF6DC9 /* LegacyTileGridTile.h */; };
@@ -15188,6 +15189,8 @@
 		E401E0A31C3C0B8300F34D10 /* StyleChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleChange.h; sourceTree = "<group>"; };
 		E401E0A51C3C0CF700F34D10 /* StyleChange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleChange.cpp; sourceTree = "<group>"; };
 		E406F3FB1198307D009D59D6 /* ColorData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ColorData.cpp; path = DerivedSources/WebCore/ColorData.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
+		E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationBoxTree.h; sourceTree = "<group>"; };
+		E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationBoxTree.cpp; sourceTree = "<group>"; };
 		E419041E1CC6486B00C35F5D /* FontSelectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSelectorClient.h; sourceTree = "<group>"; };
 		E41EA038119836DB00710BC5 /* CSSPropertyNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSPropertyNames.cpp; path = DerivedSources/WebCore/CSSPropertyNames.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
 		E41EA0391198374900710BC5 /* CSSValueKeywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSValueKeywords.cpp; path = DerivedSources/WebCore/CSSValueKeywords.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -27306,6 +27309,8 @@
 		E4FB4B1E2395356F003C336A /* integration */ = {
 			isa = PBXGroup;
 			children = (
+				E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */,
+				E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */,
 				E4ABABDE2360893D00FA4345 /* LayoutIntegrationLineLayout.cpp */,
 				E4ABABDB236088FD00FA4345 /* LayoutIntegrationLineLayout.h */,
 			);
@@ -32045,6 +32050,7 @@
 				458FE40A1589DF0B005609E6 /* RenderSearchField.h in Headers */,
 				0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */,
 				AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */,
+				E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */,
 				31955A88160D199200858025 /* RenderSnapshottedPlugIn.h in Headers */,
 				BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */,
 				BC5EB6680E81CB7100B25965 /* RenderStyleConstants.h in Headers */,

Added: trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp (0 => 254806)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.cpp	2020-01-19 16:30:27 UTC (rev 254806)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "config.h"
+#include "LayoutIntegrationBoxTree.h"
+
+#include "RenderBlockFlow.h"
+#include "RenderChildIterator.h"
+
+namespace WebCore {
+namespace LayoutIntegration {
+
+static constexpr size_t smallTreeThreshold = 8;
+
+static RenderStyle rootBoxStyle(const RenderStyle& style)
+{
+    auto clonedStyle = RenderStyle::clone(style);
+    clonedStyle.setDisplay(DisplayType::Block);
+    return clonedStyle;
+}
+
+BoxTree::BoxTree(const RenderBlockFlow& flow)
+    : m_root({ }, rootBoxStyle(flow.style()))
+{
+    if (flow.isAnonymous())
+        m_root.setIsAnonymous();
+
+    buildTree(flow);
+}
+
+void BoxTree::buildTree(const RenderBlockFlow& flow)
+{
+    for (auto& childRenderer : childrenOfType<RenderObject>(flow)) {
+        std::unique_ptr<Layout::Box> childBox;
+        if (is<RenderText>(childRenderer)) {
+            auto& textRenderer = downcast<RenderText>(childRenderer);
+            auto textContent = Layout::TextContext { textRenderer.text(), textRenderer.canUseSimplifiedTextMeasuring() };
+            childBox = makeUnique<Layout::Box>(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(m_root.style(), DisplayType::Inline));
+            childBox->setIsAnonymous();
+        } else if (childRenderer.isLineBreak()) {
+            auto clonedStyle = RenderStyle::clone(childRenderer.style());
+            clonedStyle.setDisplay(DisplayType::Inline);
+            clonedStyle.setFloating(Float::No);
+            childBox = makeUnique<Layout::Box>(Layout::Box::ElementAttributes { Layout::Box::ElementType::HardLineBreak }, WTFMove(clonedStyle));
+        }
+        ASSERT(childBox);
+
+        m_root.appendChild(*childBox);
+        m_boxes.append({ WTFMove(childBox), &childRenderer });
+    }
+}
+
+const Layout::Box* BoxTree::layoutBoxForRenderer(const RenderObject& renderer) const
+{
+    if (m_boxes.size() <= smallTreeThreshold) {
+        auto index = m_boxes.findMatching([&](auto& entry) {
+            return entry.renderer == &renderer;
+        });
+        if (index == notFound)
+            return nullptr;
+        return m_boxes[index].box.get();
+    }
+
+    if (m_rendererToBoxMap.isEmpty()) {
+        for (auto& entry : m_boxes)
+            m_rendererToBoxMap.add(entry.renderer, entry.box.get());
+    }
+    return m_rendererToBoxMap.get(&renderer);
+}
+
+const RenderObject* BoxTree::rendererForLayoutBox(const Layout::Box& box) const
+{
+    if (m_boxes.size() <= smallTreeThreshold) {
+        auto index = m_boxes.findMatching([&](auto& entry) {
+            return entry.box.get() == &box;
+        });
+        if (index == notFound)
+            return nullptr;
+        return m_boxes[index].renderer;
+    }
+
+    if (m_boxToRendererMap.isEmpty()) {
+        for (auto& entry : m_boxes)
+            m_boxToRendererMap.add(entry.box.get(), entry.renderer);
+    }
+    return m_boxToRendererMap.get(&box);
+}
+
+}
+}
+
+#endif
+
+

Copied: trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h (from rev 254805, trunk/Source/WebCore/layout/layouttree/LayoutContainer.h) (0 => 254806)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationBoxTree.h	2020-01-19 16:30:27 UTC (rev 254806)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "LayoutContainer.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class RenderBlockFlow;
+
+namespace LayoutIntegration {
+
+class BoxTree {
+public:
+    BoxTree(const RenderBlockFlow&);
+
+    const Layout::Container& rootLayoutBox() const { return m_root; }
+    Layout::Container& rootLayoutBox() { return m_root; }
+
+    const Layout::Box* layoutBoxForRenderer(const RenderObject&) const;
+    const RenderObject* rendererForLayoutBox(const Layout::Box&) const;
+
+private:
+    void buildTree(const RenderBlockFlow&);
+
+    Layout::Container m_root;
+    struct BoxAndRenderer {
+        std::unique_ptr<const Layout::Box> box;
+        const RenderObject* renderer { nullptr };
+    };
+    Vector<BoxAndRenderer, 1> m_boxes;
+
+    mutable HashMap<const RenderObject*, const Layout::Box*> m_rendererToBoxMap;
+    mutable HashMap<const Layout::Box*, const RenderObject*> m_boxToRendererMap;
+};
+
+}
+}
+
+#endif

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (254805 => 254806)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-01-19 16:30:27 UTC (rev 254806)
@@ -52,8 +52,8 @@
 
 LineLayout::LineLayout(const RenderBlockFlow& flow)
     : m_flow(flow)
+    , m_boxTree(flow)
 {
-    m_treeContent = Layout::TreeBuilder::buildLayoutTreeForIntegration(flow);
 }
 
 LineLayout::~LineLayout() = default;
@@ -96,7 +96,7 @@
 void LineLayout::layout()
 {
     if (!m_layoutState) {
-        m_layoutState.emplace(m_flow.document(), m_treeContent->rootLayoutBox());
+        m_layoutState.emplace(m_flow.document(), m_boxTree.rootLayoutBox());
         m_layoutState->setIsIntegratedRootBoxFirstChild(m_flow.parent()->firstChild() == &m_flow);
     }
 
@@ -176,7 +176,7 @@
     auto* inlineContent = displayInlineContent();
     if (!inlineContent)
         return { };
-    auto* layoutBox = m_treeContent->layoutBoxForRenderer(renderText);
+    auto* layoutBox = m_boxTree.layoutBoxForRenderer(renderText);
     ASSERT(layoutBox);
 
     Optional<size_t> firstIndex;
@@ -201,7 +201,7 @@
     auto* inlineContent = displayInlineContent();
     if (!inlineContent)
         return { };
-    auto* layoutBox = m_treeContent->layoutBoxForRenderer(renderLineBreak);
+    auto* layoutBox = m_boxTree.layoutBoxForRenderer(renderLineBreak);
     ASSERT(layoutBox);
 
     for (size_t i = 0; i < inlineContent->runs.size(); ++i) {
@@ -215,12 +215,12 @@
 
 const Layout::Container& LineLayout::rootLayoutBox() const
 {
-    return m_treeContent->rootLayoutBox();
+    return m_boxTree.rootLayoutBox();
 }
 
 Layout::Container& LineLayout::rootLayoutBox()
 {
-    return m_treeContent->rootLayoutBox();
+    return m_boxTree.rootLayoutBox();
 }
 
 void LineLayout::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -314,7 +314,7 @@
         if (style.visibility() != Visibility::Visible || style.pointerEvents() == PointerEvents::None)
             continue;
 
-        auto& renderer = const_cast<RenderObject&>(*m_treeContent->rendererForLayoutBox(run.layoutBox()));
+        auto& renderer = const_cast<RenderObject&>(*m_boxTree.rendererForLayoutBox(run.layoutBox()));
 
         renderer.updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
         if (result.addNodeToListBasedTestResult(renderer.node(), request, locationInContainer, runRect) == HitTestProgress::Stop)

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h (254805 => 254806)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h	2020-01-19 16:30:27 UTC (rev 254806)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "LayoutIntegrationBoxTree.h"
 #include "LayoutPoint.h"
 #include "LayoutState.h"
 #include "LineLayoutTraversal.h"
@@ -86,7 +87,7 @@
     ShadowData* debugTextShadow();
 
     const RenderBlockFlow& m_flow;
-    std::unique_ptr<Layout::LayoutTreeContent> m_treeContent;
+    BoxTree m_boxTree;
     Optional<Layout::LayoutState> m_layoutState;
     LayoutUnit m_contentLogicalHeight;
 };

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2020-01-19 16:30:27 UTC (rev 254806)
@@ -65,7 +65,8 @@
 
 Box::~Box()
 {
-    removeRareData();
+    if (UNLIKELY(m_hasRareData))
+        removeRareData();
 }
 
 void Box::updateStyle(const RenderStyle& newStyle)

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2020-01-19 16:30:27 UTC (rev 254806)
@@ -71,7 +71,7 @@
 
     Box(Optional<ElementAttributes>, RenderStyle&&);
     Box(TextContext&&, RenderStyle&&);
-    virtual ~Box();
+    ~Box();
 
     bool establishesFormattingContext() const;
     bool establishesBlockFormattingContext() const;

Modified: trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutContainer.cpp	2020-01-19 16:30:27 UTC (rev 254806)
@@ -91,6 +91,19 @@
     m_lastChild = &childBox;
 }
 
+void Container::appendChild(Box& childBox)
+{
+    childBox.setParent(*this);
+
+    if (m_lastChild) {
+        m_lastChild->setNextSibling(childBox);
+        childBox.setPreviousSibling(*m_lastChild);
+    } else
+        m_firstChild = &childBox;
+
+    m_lastChild = &childBox;
 }
+
 }
+}
 #endif

Modified: trunk/Source/WebCore/layout/layouttree/LayoutContainer.h (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutContainer.h	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutContainer.h	2020-01-19 16:30:27 UTC (rev 254806)
@@ -57,6 +57,7 @@
 
     void setFirstChild(Box&);
     void setLastChild(Box&);
+    void appendChild(Box&);
 
 private:
     Box* m_firstChild { nullptr };

Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2020-01-19 16:30:27 UTC (rev 254806)
@@ -132,33 +132,41 @@
     return layoutTreeContent;
 }
 
-std::unique_ptr<Layout::LayoutTreeContent> TreeBuilder::buildLayoutTreeForIntegration(const RenderBlockFlow& renderBlockFlow)
+TreeBuilder::TreeBuilder(LayoutTreeContent& layoutTreeContent)
+    : m_layoutTreeContent(layoutTreeContent)
 {
-    PhaseScope scope(Phase::Type::TreeBuilding);
+}
 
-    auto clonedStyle = RenderStyle::clone(renderBlockFlow.style());
-    clonedStyle.setDisplay(DisplayType::Block);
+void TreeBuilder::buildTree()
+{
+    buildSubTree(m_layoutTreeContent.rootRenderer(), m_layoutTreeContent.rootLayoutBox());
+}
 
-    auto rootLayoutContainer = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::GenericElement }, WTFMove(clonedStyle));
-    if (renderBlockFlow.isAnonymous())
-        rootLayoutContainer->setIsAnonymous();
-
-    auto layoutTreeContent = makeUnique<LayoutTreeContent>(renderBlockFlow, WTFMove(rootLayoutContainer));
-    TreeBuilder(*layoutTreeContent).buildTree();
-    return layoutTreeContent;
+Box& TreeBuilder::createBox(Optional<Box::ElementAttributes> elementAttributes, RenderStyle&& style)
+{
+    auto newBox = makeUnique<Box>(elementAttributes, WTFMove(style));
+    auto& box = *newBox;
+    m_layoutTreeContent.addBox(WTFMove(newBox));
+    return box;
 }
 
-TreeBuilder::TreeBuilder(LayoutTreeContent& layoutTreeContent)
-    : m_layoutTreeContent(layoutTreeContent)
+Box& TreeBuilder::createTextBox(TextContext&& textContent, RenderStyle&& style)
 {
+    auto newBox = makeUnique<Box>(WTFMove(textContent), WTFMove(style));
+    auto& box = *newBox;
+    m_layoutTreeContent.addBox(WTFMove(newBox));
+    return box;
 }
 
-void TreeBuilder::buildTree()
+Container& TreeBuilder::createContainer(Optional<Box::ElementAttributes> elementAttributes, RenderStyle&& style)
 {
-    buildSubTree(m_layoutTreeContent.rootRenderer(), m_layoutTreeContent.rootLayoutBox());
+    auto newContainer = makeUnique<Container>(elementAttributes, WTFMove(style));
+    auto& container = *newContainer;
+    m_layoutTreeContent.addContainer(WTFMove(newContainer));
+    return container;
 }
 
-std::unique_ptr<Box> TreeBuilder::createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer)
+Box* TreeBuilder::createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer)
 {
     auto elementAttributes = [] (const RenderElement& renderer) -> Optional<Box::ElementAttributes> {
         if (renderer.isDocumentElementRenderer())
@@ -178,7 +186,7 @@
         return WTF::nullopt;
     };
 
-    std::unique_ptr<Box> childLayoutBox;
+    Box* childLayoutBox = nullptr;
     if (is<RenderText>(childRenderer)) {
         auto& textRenderer = downcast<RenderText>(childRenderer);
         // RenderText::text() has already applied text-transform and text-security properties.
@@ -185,9 +193,9 @@
         String text = textRenderer.text();
         auto textContent = TextContext { text, canUseSimplifiedTextMeasuring(text, parentContainer.style().fontCascade(), parentContainer.style().collapseWhiteSpace()) };
         if (parentContainer.style().display() == DisplayType::Inline)
-            childLayoutBox = makeUnique<Box>(WTFMove(textContent), RenderStyle::clone(parentContainer.style()));
+            childLayoutBox = &createTextBox(WTFMove(textContent), RenderStyle::clone(parentContainer.style()));
         else
-            childLayoutBox = makeUnique<Box>(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
+            childLayoutBox = &createTextBox(WTFMove(textContent), RenderStyle::createAnonymousStyleWithDisplay(parentContainer.style(), DisplayType::Inline));
         childLayoutBox->setIsAnonymous();
     } else {
         auto& renderer = downcast<RenderElement>(childRenderer);
@@ -198,16 +206,16 @@
         if (is<RenderLineBreak>(renderer)) {
             clonedStyle.setDisplay(DisplayType::Inline);
             clonedStyle.setFloating(Float::No);
-            childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+            childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
         } else if (is<RenderTable>(renderer)) {
             // Construct the principal table wrapper box (and not the table box itself).
-            childLayoutBox = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::TableWrapperBox }, WTFMove(clonedStyle));
+            childLayoutBox = &createContainer(Box::ElementAttributes { Box::ElementType::TableWrapperBox }, WTFMove(clonedStyle));
             childLayoutBox->setIsAnonymous();
         } else if (is<RenderReplaced>(renderer)) {
             if (displayType == DisplayType::Block)
-                childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
             else
-                childLayoutBox = makeUnique<Box>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createBox(elementAttributes(renderer), WTFMove(clonedStyle));
             // FIXME: We don't yet support all replaced elements and this is temporary anyway.
             if (childLayoutBox->replaced())
                 childLayoutBox->replaced()->setIntrinsicSize(downcast<RenderReplaced>(renderer).intrinsicSize());
@@ -223,20 +231,20 @@
                 if (auto offset = accumulatedOffsetForInFlowPositionedContinuation(downcast<RenderBox>(renderer))) {
                     clonedStyle.setTop({ offset->height(), Fixed });
                     clonedStyle.setLeft({ offset->width(), Fixed });
-                    childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                    childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
                 } else
-                    childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                    childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
             } else if (displayType == DisplayType::Inline)
-                childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
             else if (displayType == DisplayType::InlineBlock)
-                childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
             else if (displayType == DisplayType::TableCaption || displayType == DisplayType::TableCell) {
-                childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
             } else if (displayType == DisplayType::TableRowGroup || displayType == DisplayType::TableHeaderGroup || displayType == DisplayType::TableFooterGroup
                 || displayType == DisplayType::TableRow || displayType == DisplayType::TableColumnGroup) {
-                childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
             } else if (displayType == DisplayType::TableColumn) {
-                childLayoutBox = makeUnique<Container>(elementAttributes(renderer), WTFMove(clonedStyle));
+                childLayoutBox = &createContainer(elementAttributes(renderer), WTFMove(clonedStyle));
                 auto& tableColElement = static_cast<HTMLTableColElement&>(*renderer.element());
                 auto columnWidth = tableColElement.width();
                 if (!columnWidth.isEmpty())
@@ -245,7 +253,7 @@
                     childLayoutBox->setColumnSpan(tableColElement.span());
             } else {
                 ASSERT_NOT_IMPLEMENTED_YET();
-                return { };
+                return nullptr;
             }
         }
 
@@ -273,39 +281,34 @@
     auto* tableChild = tableRenderer.firstChild();
     while (is<RenderTableCaption>(tableChild)) {
         auto& captionRenderer = *tableChild;
-        auto captionBox = createLayoutBox(tableWrapperBox, captionRenderer);
+        auto* captionBox = createLayoutBox(tableWrapperBox, captionRenderer);
         appendChild(tableWrapperBox, *captionBox);
         auto& captionContainer = downcast<Container>(*captionBox);
         buildSubTree(downcast<RenderElement>(captionRenderer), captionContainer);
-        m_layoutTreeContent.addBox(WTFMove(captionBox));
         tableChild = tableChild->nextSibling();
     }
 
-    auto tableBox = makeUnique<Container>(Box::ElementAttributes { Box::ElementType::TableBox }, RenderStyle::clone(tableRenderer.style()));
-    appendChild(tableWrapperBox, *tableBox);
+    auto& tableBox = createContainer(Box::ElementAttributes { Box::ElementType::TableBox }, RenderStyle::clone(tableRenderer.style()));
+    appendChild(tableWrapperBox, tableBox);
     auto* sectionRenderer = tableChild;
     while (sectionRenderer) {
-        auto sectionBox = createLayoutBox(*tableBox, *sectionRenderer);
-        appendChild(*tableBox, *sectionBox);
+        auto* sectionBox = createLayoutBox(tableBox, *sectionRenderer);
+        appendChild(tableBox, *sectionBox);
         auto& sectionContainer = downcast<Container>(*sectionBox);
         buildSubTree(downcast<RenderElement>(*sectionRenderer), sectionContainer);
-        m_layoutTreeContent.addBox(WTFMove(sectionBox));
         sectionRenderer = sectionRenderer->nextSibling();
     }
-    m_layoutTreeContent.addBox(WTFMove(tableBox));
 }
 
 void TreeBuilder::buildSubTree(const RenderElement& parentRenderer, Container& parentContainer)
 {
     for (auto& childRenderer : childrenOfType<RenderObject>(parentRenderer)) {
-        auto childLayoutBox = createLayoutBox(parentContainer, childRenderer);
+        auto* childLayoutBox = createLayoutBox(parentContainer, childRenderer);
         appendChild(parentContainer, *childLayoutBox);
         if (childLayoutBox->isTableWrapperBox())
             buildTableStructure(downcast<RenderTable>(childRenderer), downcast<Container>(*childLayoutBox));
         else if (is<Container>(*childLayoutBox))
             buildSubTree(downcast<RenderElement>(childRenderer), downcast<Container>(*childLayoutBox));
-
-        m_layoutTreeContent.addBox(WTFMove(childLayoutBox));
     }
 }
 

Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h (254805 => 254806)


--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h	2020-01-19 16:02:01 UTC (rev 254805)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.h	2020-01-19 16:30:27 UTC (rev 254806)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "LayoutContainer.h"
 #include <wtf/IsoMalloc.h>
 #include <wtf/WeakPtr.h>
 
@@ -41,8 +42,6 @@
 
 namespace Layout {
 
-class Box;
-class Container;
 class LayoutState;
 
 class LayoutTreeContent : public CanMakeWeakPtr<LayoutTreeContent> {
@@ -55,7 +54,12 @@
     Container& rootLayoutBox() { return *m_rootLayoutBox; }
     const RenderBox& rootRenderer() const { return m_rootRenderer; }
 
-    void addBox(std::unique_ptr<Box> box) { m_boxes.add(WTFMove(box)); }
+    void addBox(std::unique_ptr<Box> box)
+    {
+        ASSERT(!box->isContainer());
+        m_boxes.add(WTFMove(box));
+    }
+    void addContainer(std::unique_ptr<Container> container) { m_containers.add(WTFMove(container)); }
 
     Box* layoutBoxForRenderer(const RenderObject& renderer) { return m_renderObjectToLayoutBox.get(&renderer); }
     const Box* layoutBoxForRenderer(const RenderObject& renderer) const { return m_renderObjectToLayoutBox.get(&renderer); }
@@ -68,6 +72,7 @@
     const RenderBox& m_rootRenderer;
     std::unique_ptr<Container> m_rootLayoutBox;
     HashSet<std::unique_ptr<Box>> m_boxes;
+    HashSet<std::unique_ptr<Container>> m_containers;
 
     HashMap<const RenderObject*, Box*> m_renderObjectToLayoutBox;
     HashMap<const Box*, const RenderObject*> m_layoutBoxToRenderObject;
@@ -76,7 +81,6 @@
 class TreeBuilder {
 public:
     static std::unique_ptr<Layout::LayoutTreeContent> buildLayoutTree(const RenderView&);
-    static std::unique_ptr<Layout::LayoutTreeContent> buildLayoutTreeForIntegration(const RenderBlockFlow&);
 
 private:
     TreeBuilder(LayoutTreeContent&);
@@ -84,8 +88,12 @@
     void buildTree();
     void buildSubTree(const RenderElement& parentRenderer, Container& parentContainer);
     void buildTableStructure(const RenderTable& tableRenderer, Container& tableWrapperBox);
-    std::unique_ptr<Box> createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer);
+    Box* createLayoutBox(const Container& parentContainer, const RenderObject& childRenderer);
 
+    Box& createBox(Optional<Box::ElementAttributes>, RenderStyle&&);
+    Box& createTextBox(TextContext&&, RenderStyle&&);
+    Container& createContainer(Optional<Box::ElementAttributes>, RenderStyle&&);
+
     LayoutTreeContent& m_layoutTreeContent;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to