Changeset 220858 in webkit


Ignore:
Timestamp:
Aug 17, 2017 8:19:38 AM (7 years ago)
Author:
Antti Koivisto
Message:

RenderListItem - Avoid render tree mutation during layout
https://bugs.webkit.org/show_bug.cgi?id=175666

Reviewed by Andreas Kling.

Source/WebCore:

Mutations should be done by RenderTreeUpdater only.

  • rendering/RenderListItem.cpp:

(WebCore::RenderListItem::updateMarkerRenderer):

This is now called by RenderTreeUpdater only.
Remove code dealing with this being called at layout time.
Merged marker construction code from styleDidChange here and renamed for clarity.

(WebCore::RenderListItem::layout):
(WebCore::RenderListItem::computePreferredLogicalWidths):

Remove mutating calls.

(WebCore::RenderListItem::styleDidChange): Deleted.
(WebCore::RenderListItem::insertOrMoveMarkerRendererIfNeeded): Deleted.

  • rendering/RenderListItem.h:
  • rendering/TextAutoSizing.cpp:

(WebCore::TextAutoSizingValue::adjustTextNodeSizes):

Call updateMarkerRenderer.

  • style/RenderTreeUpdater.cpp:

(WebCore::RenderTreeUpdater::popParent):
(WebCore::RenderTreeUpdater::updateBeforeOrAfterPseudoElement):

Call updateMarkerRenderer.

LayoutTests:

Changes in render tree dumps that don't affect rendering.

  • platform/ios/fast/doctypes/002-expected.txt:
  • platform/ios/fast/lists/marker-before-empty-inline-expected.txt:
  • platform/mac/css2.1/t0805-c5520-brdr-b-01-e-expected.txt:
  • platform/mac/fast/doctypes/002-expected.txt:
  • platform/mac/fast/lists/marker-before-empty-inline-expected.txt:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r220853 r220858  
     12017-08-17  Antti Koivisto  <antti@apple.com>
     2
     3        RenderListItem - Avoid render tree mutation during layout
     4        https://bugs.webkit.org/show_bug.cgi?id=175666
     5
     6        Reviewed by Andreas Kling.
     7
     8        Changes in render tree dumps that don't affect rendering.
     9
     10        * platform/ios/fast/doctypes/002-expected.txt:
     11        * platform/ios/fast/lists/marker-before-empty-inline-expected.txt:
     12        * platform/mac/css2.1/t0805-c5520-brdr-b-01-e-expected.txt:
     13        * platform/mac/fast/doctypes/002-expected.txt:
     14        * platform/mac/fast/lists/marker-before-empty-inline-expected.txt:
     15
    1162017-08-17  Ms2ger  <Ms2ger@gmail.com>
    217
  • trunk/LayoutTests/platform/ios/fast/doctypes/002-expected.txt

    r179104 r220858  
    1313          RenderBlock {UL} at (0,0) size 744x20
    1414            RenderListItem {LI} at (40,0) size 704x20
     15              RenderListMarker at (-18,0) size 7x19: white bullet
    1516              RenderListMarker at (-58,0) size 7x19: bullet
    16               RenderListMarker at (-18,0) size 7x19: white bullet
    1717              RenderText {#text} at (0,0) size 256x19
    1818                text run at (0,0) width 256: "Both bullets should be on the same line."
  • trunk/LayoutTests/platform/ios/fast/lists/marker-before-empty-inline-expected.txt

    r179104 r220858  
    8080            RenderBlock {UL} at (0,0) size 744x20
    8181              RenderListItem {LI} at (40,0) size 704x20
     82                RenderListMarker at (-18,0) size 7x19: white bullet
    8283                RenderListMarker at (-58,0) size 7x19: bullet
    83                 RenderListMarker at (-18,0) size 7x19: white bullet
    8484                RenderText {#text} at (0,0) size 29x19
    8585                  text run at (0,0) width 29: "item"
     
    9292            RenderBlock {UL} at (0,0) size 744x20
    9393              RenderListItem {LI} at (40,0) size 704x20
     94                RenderListMarker at (-18,0) size 7x19: white bullet
    9495                RenderListMarker at (-58,0) size 7x19: bullet
    95                 RenderListMarker at (-18,0) size 7x19: white bullet
    9696                RenderText {#text} at (0,0) size 29x19
    9797                  text run at (0,0) width 29: "item"
  • trunk/LayoutTests/platform/mac/css2.1/t0805-c5520-brdr-b-01-e-expected.txt

    r191623 r220858  
    3737          RenderBlock {UL} at (0,0) size 744x54
    3838            RenderListItem {LI} at (40,0) size 704x18
     39              RenderListMarker at (-17,0) size 7x18: white bullet
    3940              RenderListMarker at (-57,0) size 7x18: bullet
    40               RenderListMarker at (-17,0) size 7x18: white bullet
    4141              RenderText {#text} at (0,0) size 77x18
    4242                text run at (0,0) width 77: "dummy text"
  • trunk/LayoutTests/platform/mac/fast/doctypes/002-expected.txt

    r177774 r220858  
    1313          RenderBlock {UL} at (0,0) size 744x18
    1414            RenderListItem {LI} at (40,0) size 704x18
     15              RenderListMarker at (-17,0) size 7x18: white bullet
    1516              RenderListMarker at (-57,0) size 7x18: bullet
    16               RenderListMarker at (-17,0) size 7x18: white bullet
    1717              RenderText {#text} at (0,0) size 256x18
    1818                text run at (0,0) width 256: "Both bullets should be on the same line."
  • trunk/LayoutTests/platform/mac/fast/lists/marker-before-empty-inline-expected.txt

    r177774 r220858  
    8080            RenderBlock {UL} at (0,0) size 744x18
    8181              RenderListItem {LI} at (40,0) size 704x18
     82                RenderListMarker at (-17,0) size 7x18: white bullet
    8283                RenderListMarker at (-57,0) size 7x18: bullet
    83                 RenderListMarker at (-17,0) size 7x18: white bullet
    8484                RenderText {#text} at (0,0) size 29x18
    8585                  text run at (0,0) width 29: "item"
     
    9292            RenderBlock {UL} at (0,0) size 744x18
    9393              RenderListItem {LI} at (40,0) size 704x18
     94                RenderListMarker at (-17,0) size 7x18: white bullet
    9495                RenderListMarker at (-57,0) size 7x18: bullet
    95                 RenderListMarker at (-17,0) size 7x18: white bullet
    9696                RenderText {#text} at (0,0) size 29x18
    9797                  text run at (0,0) width 29: "item"
  • trunk/Source/WebCore/ChangeLog

    r220857 r220858  
     12017-08-17  Antti Koivisto  <antti@apple.com>
     2
     3        RenderListItem - Avoid render tree mutation during layout
     4        https://bugs.webkit.org/show_bug.cgi?id=175666
     5
     6        Reviewed by Andreas Kling.
     7
     8        Mutations should be done by RenderTreeUpdater only.
     9
     10        * rendering/RenderListItem.cpp:
     11        (WebCore::RenderListItem::updateMarkerRenderer):
     12
     13            This is now called by RenderTreeUpdater only.
     14            Remove code dealing with this being called at layout time.
     15            Merged marker construction code from styleDidChange here and renamed for clarity.
     16
     17        (WebCore::RenderListItem::layout):
     18        (WebCore::RenderListItem::computePreferredLogicalWidths):
     19
     20            Remove mutating calls.
     21
     22        (WebCore::RenderListItem::styleDidChange): Deleted.
     23        (WebCore::RenderListItem::insertOrMoveMarkerRendererIfNeeded): Deleted.
     24        * rendering/RenderListItem.h:
     25        * rendering/TextAutoSizing.cpp:
     26        (WebCore::TextAutoSizingValue::adjustTextNodeSizes):
     27
     28            Call updateMarkerRenderer.
     29
     30        * style/RenderTreeUpdater.cpp:
     31        (WebCore::RenderTreeUpdater::popParent):
     32        (WebCore::RenderTreeUpdater::updateBeforeOrAfterPseudoElement):
     33
     34            Call updateMarkerRenderer.
     35
    1362017-08-17  Don Olmstead  <don.olmstead@sony.com>
    237
  • trunk/Source/WebCore/rendering/RenderListItem.cpp

    r220207 r220858  
    9797}
    9898
    99 void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    100 {
    101     RenderBlockFlow::styleDidChange(diff, oldStyle);
    102 
    103     if (style().listStyleType() == NoneListStyle && (!style().listStyleImage() || style().listStyleImage()->errorOccurred())) {
    104         if (m_marker) {
    105             m_marker->destroy();
    106             ASSERT(!m_marker);
    107         }
    108         return;
    109     }
    110 
    111     auto newStyle = computeMarkerStyle();
    112     if (m_marker)
    113         m_marker->setStyle(WTFMove(newStyle));
    114     else {
    115         m_marker = createRenderer<RenderListMarker>(*this, WTFMove(newStyle)).leakPtr();
    116         m_marker->initializeStyle();
    117     }
    118 }
    119 
    12099void RenderListItem::insertedIntoTree()
    121100{
     
    294273}
    295274
    296 void RenderListItem::insertOrMoveMarkerRendererIfNeeded()
    297 {
    298     // Sanity check the location of our marker.
    299     if (!m_marker)
    300         return;
    301 
    302     // FIXME: Do not even try to reposition the marker when we are not in layout
    303     // until after we fixed webkit.org/b/163789.
    304     if (!view().frameView().isInRenderTreeLayout())
    305         return;
     275void RenderListItem::updateMarkerRenderer()
     276{
     277    ASSERT_WITH_SECURITY_IMPLICATION(!view().layoutState());
     278
     279    if (style().listStyleType() == NoneListStyle && (!style().listStyleImage() || style().listStyleImage()->errorOccurred())) {
     280        if (m_marker) {
     281            m_marker->destroy();
     282            ASSERT(!m_marker);
     283        }
     284        return;
     285    }
     286
     287    auto newStyle = computeMarkerStyle();
     288    if (m_marker)
     289        m_marker->setStyle(WTFMove(newStyle));
     290    else {
     291        m_marker = createRenderer<RenderListMarker>(*this, WTFMove(newStyle)).leakPtr();
     292        m_marker->initializeStyle();
     293    }
    306294
    307295    RenderElement* currentParent = m_marker->parent();
     
    321309
    322310    if (newParent != currentParent) {
    323         // Removing and adding the marker can trigger repainting in
    324         // containers other than ourselves, so we need to disable LayoutState.
    325         LayoutStateDisabler layoutStateDisabler(view());
    326         // Mark the parent dirty so that when the marker gets inserted into the tree
    327         // and dirties ancestors, it stops at the parent.
    328         newParent->setChildNeedsLayout(MarkOnlyThis);
    329         m_marker->setNeedsLayout(MarkOnlyThis);
    330 
    331311        m_marker->removeFromParent();
    332312        newParent->addChild(m_marker, firstNonMarkerChild(*newParent));
    333         m_marker->updateMarginsAndContent();
    334313        // If current parent is an anonymous block that has lost all its children, destroy it.
    335314        if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !downcast<RenderBlock>(*currentParent).continuation())
    336315            currentParent->destroy();
    337316    }
    338 
    339317}
    340318
     
    342320{
    343321    StackStats::LayoutCheckPoint layoutCheckPoint;
    344     ASSERT(needsLayout());
    345 
    346     insertOrMoveMarkerRendererIfNeeded();
     322    ASSERT(needsLayout());
     323
    347324#if !ASSERT_DISABLED
    348325    SetForScope<bool> inListItemLayout(m_inLayout, true);
     
    359336void RenderListItem::computePreferredLogicalWidths()
    360337{
    361 #ifndef NDEBUG
    362     // FIXME: We shouldn't be modifying the tree in computePreferredLogicalWidths.
    363     // Instead, we should insert the marker soon after the tree construction.
    364     // This is similar case to RenderCounter::computePreferredLogicalWidths()
    365     // See https://bugs.webkit.org/show_bug.cgi?id=104829
    366     SetLayoutNeededForbiddenScope layoutForbiddenScope(this, false);
    367 #endif
    368     insertOrMoveMarkerRendererIfNeeded();
     338    // FIXME: RenderListMarker::updateMargins() mutates margin style which affects preferred widths.
     339    if (m_marker && m_marker->preferredLogicalWidthsDirty())
     340        m_marker->updateMarginsAndContent();
     341
    369342    RenderBlockFlow::computePreferredLogicalWidths();
    370343}
  • trunk/Source/WebCore/rendering/RenderListItem.h

    r220207 r220858  
    5757    void didDestroyListMarker() { m_marker = nullptr; }
    5858
     59    void updateMarkerRenderer();
     60
    5961#if !ASSERT_DISABLED
    6062    bool inLayout() const { return m_inLayout; }
     
    7779    void positionListMarker();
    7880
    79     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
    80 
    8181    void addOverflowFromChildren() override;
    8282    void computePreferredLogicalWidths() override;
    8383
    84     void insertOrMoveMarkerRendererIfNeeded();
    8584    inline int calcValue() const;
    8685    void updateValueNow() const;
  • trunk/Source/WebCore/rendering/TextAutoSizing.cpp

    r220795 r220858  
    3434#include "Logging.h"
    3535#include "RenderBlock.h"
     36#include "RenderListItem.h"
    3637#include "RenderListMarker.h"
    3738#include "RenderText.h"
     
    157158        newParentStyle.fontCascade().update(&node->document().fontSelector());
    158159        parentRenderer->setStyle(WTFMove(newParentStyle));
     160
     161        if (is<RenderListItem>(*parentRenderer))
     162            downcast<RenderListItem>(*parentRenderer).updateMarkerRenderer();
    159163    }
    160164
  • trunk/Source/WebCore/style/RenderTreeUpdater.cpp

    r220795 r220858  
    4040#include "RenderDescendantIterator.h"
    4141#include "RenderFullScreen.h"
     42#include "RenderListItem.h"
    4243#include "RenderNamedFlowThread.h"
    4344#include "RenderQuote.h"
     
    234235        updateBeforeOrAfterPseudoElement(*parent.element, AFTER);
    235236
    236         auto* renderer = parent.element->renderer();
    237         if (is<RenderBlock>(renderer))
    238             FirstLetter::update(downcast<RenderBlock>(*renderer));
    239 
    240         if (parent.element->hasCustomStyleResolveCallbacks() && parent.styleChange == Style::Detach && renderer)
    241             parent.element->didAttachRenderers();
     237        if (auto* renderer = parent.element->renderer()) {
     238            if (is<RenderBlock>(*renderer))
     239                FirstLetter::update(downcast<RenderBlock>(*renderer));
     240            if (is<RenderListItem>(*renderer))
     241                downcast<RenderListItem>(*renderer).updateMarkerRenderer();
     242
     243            if (parent.element->hasCustomStyleResolveCallbacks() && parent.styleChange == Style::Detach)
     244                parent.element->didAttachRenderers();
     245        }
    242246    }
    243247    m_parentStack.removeLast();
     
    567571            updateQuotesUpTo(&child);
    568572    }
     573    if (is<RenderListItem>(*pseudoRenderer))
     574        downcast<RenderListItem>(*pseudoRenderer).updateMarkerRenderer();
    569575}
    570576
Note: See TracChangeset for help on using the changeset viewer.