Title: [222911] trunk/Source/WebCore
Revision
222911
Author
[email protected]
Date
2017-10-05 07:04:27 -0700 (Thu, 05 Oct 2017)

Log Message

Move multicolumn flow clear to RenderTreeUpdater
https://bugs.webkit.org/show_bug.cgi?id=177898
<rdar://problem/34820157>

Reviewed by Antti Koivisto.

There are 2 cases when we need to clear the the multicolumn flow from its container.

1. When the column renderer is not need anymore due to style change (evacuateAndDestroy).
During the subtree reparenting (moving back the descendants to the original position),
if we still had the multicolumn set on the RenderBlockFlow, RenderBlockFlow::addChild() would
put the children back under the column. -> Move the clear call to the RenderTreeUpdater.

2. When the column is detached from the tree/destroyed (willBeRemoveFromTree).
Since it does not trigger reparenting, we don't need to clear the column immediately.
We call clear to avoid accessing state column renderer. -> Use WeakPtr to
manage lifetime instead.

Covered by existing tests.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::setMultiColumnFlow):
(WebCore::RenderBlockFlow::clearMultiColumnFlow):
* rendering/RenderBlockFlow.h:
* rendering/RenderMultiColumnFlow.cpp:
(WebCore::RenderMultiColumnFlow::evacuateAndDestroy):
(WebCore::RenderMultiColumnFlow::willBeRemovedFromTree):
* style/RenderTreeUpdaterMultiColumn.cpp:
(WebCore::RenderTreeUpdater::MultiColumn::update):
(WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (222910 => 222911)


--- trunk/Source/WebCore/ChangeLog	2017-10-05 14:00:05 UTC (rev 222910)
+++ trunk/Source/WebCore/ChangeLog	2017-10-05 14:04:27 UTC (rev 222911)
@@ -1,3 +1,36 @@
+2017-10-05  Zalan Bujtas  <[email protected]>
+
+        Move multicolumn flow clear to RenderTreeUpdater
+        https://bugs.webkit.org/show_bug.cgi?id=177898
+        <rdar://problem/34820157>
+
+        Reviewed by Antti Koivisto.
+
+        There are 2 cases when we need to clear the the multicolumn flow from its container.
+
+        1. When the column renderer is not need anymore due to style change (evacuateAndDestroy).
+        During the subtree reparenting (moving back the descendants to the original position),
+        if we still had the multicolumn set on the RenderBlockFlow, RenderBlockFlow::addChild() would
+        put the children back under the column. -> Move the clear call to the RenderTreeUpdater.
+         
+        2. When the column is detached from the tree/destroyed (willBeRemoveFromTree).
+        Since it does not trigger reparenting, we don't need to clear the column immediately. 
+        We call clear to avoid accessing state column renderer. -> Use WeakPtr to
+        manage lifetime instead.
+
+        Covered by existing tests.
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::setMultiColumnFlow):
+        (WebCore::RenderBlockFlow::clearMultiColumnFlow):
+        * rendering/RenderBlockFlow.h:
+        * rendering/RenderMultiColumnFlow.cpp:
+        (WebCore::RenderMultiColumnFlow::evacuateAndDestroy):
+        (WebCore::RenderMultiColumnFlow::willBeRemovedFromTree):
+        * style/RenderTreeUpdaterMultiColumn.cpp:
+        (WebCore::RenderTreeUpdater::MultiColumn::update):
+        (WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
+
 2017-10-05  Miguel Gomez  <[email protected]>
 
         [GTK][WPE] GIFImageDecoder never clears decoded frames even when told to do so

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (222910 => 222911)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2017-10-05 14:00:05 UTC (rev 222910)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2017-10-05 14:04:27 UTC (rev 222911)
@@ -3160,14 +3160,19 @@
     RenderBlock::updateLogicalHeight();
 }
 
-void RenderBlockFlow::setMultiColumnFlow(RenderMultiColumnFlow* fragmentedFlow)
+void RenderBlockFlow::setMultiColumnFlow(RenderMultiColumnFlow& fragmentedFlow)
 {
-    if (fragmentedFlow || hasRareBlockFlowData()) {
-        RenderBlockFlowRareData& rareData = ensureRareBlockFlowData();
-        rareData.m_multiColumnFlow = fragmentedFlow;
-    }
+    ASSERT(!hasRareBlockFlowData() || !rareBlockFlowData()->m_multiColumnFlow);
+    ensureRareBlockFlowData().m_multiColumnFlow = makeWeakPtr(fragmentedFlow);
 }
 
+void RenderBlockFlow::clearMultiColumnFlow()
+{
+    ASSERT(hasRareBlockFlowData());
+    ASSERT(rareBlockFlowData()->m_multiColumnFlow);
+    rareBlockFlowData()->m_multiColumnFlow.clear();
+}
+
 static bool shouldCheckLines(const RenderBlockFlow& blockFlow)
 {
     return !blockFlow.isFloatingOrOutOfFlowPositioned() && blockFlow.style().height().isAuto();

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (222910 => 222911)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2017-10-05 14:00:05 UTC (rev 222910)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2017-10-05 14:04:27 UTC (rev 222911)
@@ -118,7 +118,6 @@
         RenderBlockFlowRareData(const RenderBlockFlow& block)
             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
             , m_lineBreakToAvoidWidow(-1)
-            , m_multiColumnFlow(nullptr)
             , m_discardMarginBefore(false)
             , m_discardMarginAfter(false)
             , m_didBreakAtLineToAvoidWidow(false)
@@ -150,7 +149,7 @@
         int m_lineBreakToAvoidWidow;
         std::unique_ptr<RootInlineBox> m_lineGridBox;
 
-        RenderMultiColumnFlow* m_multiColumnFlow;
+        WeakPtr<RenderMultiColumnFlow> m_multiColumnFlow;
         
         bool m_discardMarginBefore : 1;
         bool m_discardMarginAfter : 1;
@@ -271,8 +270,9 @@
     }
     void layoutLineGridBox();
 
-    RenderMultiColumnFlow* multiColumnFlow() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_multiColumnFlow : nullptr; }
-    void setMultiColumnFlow(RenderMultiColumnFlow*);
+    RenderMultiColumnFlow* multiColumnFlow() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_multiColumnFlow.get() : nullptr; }
+    void setMultiColumnFlow(RenderMultiColumnFlow&);
+    void clearMultiColumnFlow();
     bool willCreateColumns(std::optional<unsigned> desiredColumnCount = std::nullopt) const;
     virtual bool requiresColumns(int) const;
 

Modified: trunk/Source/WebCore/rendering/RenderMultiColumnFlow.cpp (222910 => 222911)


--- trunk/Source/WebCore/rendering/RenderMultiColumnFlow.cpp	2017-10-05 14:00:05 UTC (rev 222910)
+++ trunk/Source/WebCore/rendering/RenderMultiColumnFlow.cpp	2017-10-05 14:04:27 UTC (rev 222911)
@@ -165,13 +165,7 @@
     RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
     // Delete the line box tree.
     deleteLines();
-    
-    // First promote all children of the flow thread. Before we move them to the flow thread's
-    // container, we need to unregister the flow thread, so that they aren't just re-added again to
-    // the flow thread that we're trying to empty.
-    multicolContainer->setMultiColumnFlow(nullptr);
     moveAllChildrenTo(multicolContainer, true);
-
     // Move spanners back to their original DOM position in the tree, and destroy the placeholders.
     SpannerMap::iterator it;
     while ((it = m_spannerMap.begin()) != m_spannerMap.end()) {
@@ -212,7 +206,6 @@
     // further up on the call stack.
     for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet())
         columnSet->detachFragment();
-    multiColumnBlockFlow()->setMultiColumnFlow(nullptr);
     RenderFragmentedFlow::willBeRemovedFromTree();
 }
 

Modified: trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp (222910 => 222911)


--- trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp	2017-10-05 14:00:05 UTC (rev 222910)
+++ trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp	2017-10-05 14:04:27 UTC (rev 222911)
@@ -35,6 +35,7 @@
     auto* multiColumnFlow = flow.multiColumnFlow();
     if (!needsFragmentedFlow) {
         if (multiColumnFlow) {
+            flow.clearMultiColumnFlow();
             multiColumnFlow->evacuateAndDestroy();
             ASSERT(!flow.multiColumnFlow());
         }
@@ -53,7 +54,7 @@
     auto& fragmentedFlow = *newFragmentedFlow;
     flow.RenderBlock::addChild(WTFMove(newFragmentedFlow));
     fragmentedFlow.populate(); // Called after the flow thread is inserted so that we are reachable by the flow thread.
-    flow.setMultiColumnFlow(&fragmentedFlow);
+    flow.setMultiColumnFlow(fragmentedFlow);
 }
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to