Title: [221379] trunk
Revision
221379
Author
[email protected]
Date
2017-08-30 10:28:10 -0700 (Wed, 30 Aug 2017)

Log Message

RenderMultiColumnFlowThread - Avoid render tree mutation during layout
https://bugs.webkit.org/show_bug.cgi?id=176026
<rdar://problem/33402891>

Reviewed by Zalan Bujtas.

Source/WebCore:

Mutations should be done in RenderTreeUpdater.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::willCreateColumns const):

    Don't create columns for RenderSVGBlock. Before this patch this was avoided because it
    has custom layout() function that doesn't call to setComputedColumnCountAndWidth.
    Same for mathml and ruby.

    Don't create columns for pseudo elements (first-letter mostly).

(WebCore::RenderBlockFlow::setComputedColumnCountAndWidth):

    This now assumes that the multicolumn renderer has been initialized correctly already.

* rendering/RenderBlockFlow.h:
* style/RenderTreeUpdater.cpp:
(WebCore::updateMultiColumnFlowThread):

    Create or delte multicolumn renderer after descendants are known.

(WebCore::RenderTreeUpdater::commit):
(WebCore::RenderTreeUpdater::updateAfterDescendants):

LayoutTests:

* imported/blink/fast/pagination/first-letter-inherit-all-crash-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (221378 => 221379)


--- trunk/LayoutTests/ChangeLog	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/LayoutTests/ChangeLog	2017-08-30 17:28:10 UTC (rev 221379)
@@ -1,3 +1,13 @@
+2017-08-30  Antti Koivisto  <[email protected]>
+
+        RenderMultiColumnFlowThread - Avoid render tree mutation during layout
+        https://bugs.webkit.org/show_bug.cgi?id=176026
+        <rdar://problem/33402891>
+
+        Reviewed by Zalan Bujtas.
+
+        * imported/blink/fast/pagination/first-letter-inherit-all-crash-expected.txt:
+
 2017-08-30  Matt Lewis  <[email protected]>
 
         Creation of missing expectation folders and rebaseline for js/dom/global-constructors-attributes-expected.txt after r221302.

Modified: trunk/LayoutTests/imported/blink/fast/pagination/first-letter-inherit-all-crash-expected.txt (221378 => 221379)


--- trunk/LayoutTests/imported/blink/fast/pagination/first-letter-inherit-all-crash-expected.txt	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/LayoutTests/imported/blink/fast/pagination/first-letter-inherit-all-crash-expected.txt	2017-08-30 17:28:10 UTC (rev 221379)
@@ -2,4 +2,4 @@
 
 PASS if no crash or assertion failure.
 
-
+x

Modified: trunk/Source/WebCore/ChangeLog (221378 => 221379)


--- trunk/Source/WebCore/ChangeLog	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/Source/WebCore/ChangeLog	2017-08-30 17:28:10 UTC (rev 221379)
@@ -1,3 +1,35 @@
+2017-08-30  Antti Koivisto  <[email protected]>
+
+        RenderMultiColumnFlowThread - Avoid render tree mutation during layout
+        https://bugs.webkit.org/show_bug.cgi?id=176026
+        <rdar://problem/33402891>
+
+        Reviewed by Zalan Bujtas.
+
+        Mutations should be done in RenderTreeUpdater.
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::willCreateColumns const):
+
+            Don't create columns for RenderSVGBlock. Before this patch this was avoided because it
+            has custom layout() function that doesn't call to setComputedColumnCountAndWidth.
+            Same for mathml and ruby.
+
+            Don't create columns for pseudo elements (first-letter mostly).
+
+        (WebCore::RenderBlockFlow::setComputedColumnCountAndWidth):
+
+            This now assumes that the multicolumn renderer has been initialized correctly already.
+
+        * rendering/RenderBlockFlow.h:
+        * style/RenderTreeUpdater.cpp:
+        (WebCore::updateMultiColumnFlowThread):
+
+            Create or delte multicolumn renderer after descendants are known.
+
+        (WebCore::RenderTreeUpdater::commit):
+        (WebCore::RenderTreeUpdater::updateAfterDescendants):
+
 2017-08-30  Said Abou-Hallawa  <[email protected]>
 
         The SVG fragment identifier is not respected if it is a part of an HTTP URL

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (221378 => 221379)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2017-08-30 17:28:10 UTC (rev 221379)
@@ -456,10 +456,15 @@
     // The following types are not supposed to create multicol context.
     if (isFileUploadControl() || isTextControl() || isListBox())
         return false;
+    if (isRenderSVGBlock() || isRenderMathMLBlock() || isRubyRun())
+        return false;
 
     if (!firstChild())
         return false;
 
+    if (style().styleType() != NOPSEUDO)
+        return false;
+
     // If overflow-y is set to paged-x or paged-y on the body or html element, we'll handle the paginating in the RenderView instead.
     if ((style().overflowY() == OPAGEDX || style().overflowY() == OPAGEDY) && !(isDocumentElementRenderer() || isBody()))
         return true;
@@ -4012,17 +4017,12 @@
 
 void RenderBlockFlow::setComputedColumnCountAndWidth(int count, LayoutUnit width)
 {
-    bool destroyColumns = !requiresColumns(count);
-    if (destroyColumns) {
-        if (multiColumnFlowThread())
-            destroyMultiColumnFlowThread();
-    } else {
-        if (!multiColumnFlowThread())
-            createMultiColumnFlowThread();
-        multiColumnFlowThread()->setColumnCountAndWidth(count, width);
-        multiColumnFlowThread()->setProgressionIsInline(style().hasInlineColumnAxis());
-        multiColumnFlowThread()->setProgressionIsReversed(style().columnProgression() == ReverseColumnProgression);
-    }
+    ASSERT(!!multiColumnFlowThread() == requiresColumns(count));
+    if (!multiColumnFlowThread())
+        return;
+    multiColumnFlowThread()->setColumnCountAndWidth(count, width);
+    multiColumnFlowThread()->setProgressionIsInline(style().hasInlineColumnAxis());
+    multiColumnFlowThread()->setProgressionIsReversed(style().columnProgression() == ReverseColumnProgression);
 }
 
 void RenderBlockFlow::updateColumnProgressionFromStyle(RenderStyle& style)

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (221378 => 221379)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.h	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h	2017-08-30 17:28:10 UTC (rev 221379)
@@ -283,7 +283,8 @@
     RenderMultiColumnFlowThread* multiColumnFlowThread() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_multiColumnFlowThread : nullptr; }
     void setMultiColumnFlowThread(RenderMultiColumnFlowThread*);
     bool willCreateColumns(std::optional<unsigned> desiredColumnCount = std::nullopt) const;
-    
+    virtual bool requiresColumns(int) const;
+
     bool containsFloats() const override { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
     bool containsFloat(RenderBox&) const;
 
@@ -469,8 +470,7 @@
     void addFloatsToNewParent(RenderBlockFlow& toBlockFlow) const;
     
     virtual void computeColumnCountAndWidth();
-    virtual bool requiresColumns(int) const;
-    
+
     virtual void cachePriorCharactersIfNeeded(const LazyLineBreakIterator&) {};
     
 protected:

Modified: trunk/Source/WebCore/style/RenderTreeUpdater.cpp (221378 => 221379)


--- trunk/Source/WebCore/style/RenderTreeUpdater.cpp	2017-08-30 17:25:48 UTC (rev 221378)
+++ trunk/Source/WebCore/style/RenderTreeUpdater.cpp	2017-08-30 17:28:10 UTC (rev 221379)
@@ -117,6 +117,18 @@
     return renderingRoots;
 }
 
+static void updateMultiColumnFlowThread(RenderBlockFlow& flow)
+{
+    bool needsFlowThread = flow.requiresColumns(flow.style().columnCount());
+    if (!needsFlowThread) {
+        if (flow.multiColumnFlowThread())
+            flow.destroyMultiColumnFlowThread();
+        return;
+    }
+    if (!flow.multiColumnFlowThread())
+        flow.createMultiColumnFlowThread();
+}
+
 void RenderTreeUpdater::commit(std::unique_ptr<const Style::Update> styleUpdate)
 {
     ASSERT(&m_document == &styleUpdate->document());
@@ -135,6 +147,8 @@
 
     generatedContent().updateRemainingQuotes();
 
+    updateMultiColumnFlowThread(renderView());
+
     m_styleUpdate = nullptr;
 }
 
@@ -263,6 +277,8 @@
         FirstLetter::update(downcast<RenderBlock>(*renderer));
     if (is<RenderListItem>(*renderer))
         ListItem::updateMarker(downcast<RenderListItem>(*renderer));
+    if (is<RenderBlockFlow>(*renderer))
+        updateMultiColumnFlowThread(downcast<RenderBlockFlow>(*renderer));
 
     if (element.hasCustomStyleResolveCallbacks() && styleChange == Style::Detach)
         element.didAttachRenderers();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to