Cache line layout path
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Oct 2013 02:33:11 +0000 (02:33 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Oct 2013 02:33:11 +0000 (02:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123298

Reviewed by Sam Weinig.

Determining the path can be non-trivial. Avoid computing it repeatedly on relayouts.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::RenderBlock):
(WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
(WebCore::RenderBlock::invalidateLineLayoutPath):
(WebCore::RenderBlock::removeChild):

    Invalidate the path when children change.

* rendering/RenderBlock.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::layoutInlineChildren):
(WebCore::RenderBlockFlow::styleDidChange):

    Invalidate the path when style changes.

(WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
(WebCore::RenderBlockFlow::ensureLineBoxes):
* rendering/RenderText.cpp:
(WebCore::RenderText::setText):

    Invalidate the path when text changes.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@157985 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderText.cpp

index 02eb0ab..d82ea4b 100644 (file)
@@ -1,3 +1,34 @@
+2013-10-24  Antti Koivisto  <antti@apple.com>
+
+        Cache line layout path
+        https://bugs.webkit.org/show_bug.cgi?id=123298
+
+        Reviewed by Sam Weinig.
+        
+        Determining the path can be non-trivial. Avoid computing it repeatedly on relayouts.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::RenderBlock):
+        (WebCore::RenderBlock::addChildIgnoringAnonymousColumnBlocks):
+        (WebCore::RenderBlock::invalidateLineLayoutPath):
+        (WebCore::RenderBlock::removeChild):
+        
+            Invalidate the path when children change.
+
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::layoutInlineChildren):
+        (WebCore::RenderBlockFlow::styleDidChange):
+        
+            Invalidate the path when style changes.
+
+        (WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
+        (WebCore::RenderBlockFlow::ensureLineBoxes):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::setText):
+        
+            Invalidate the path when text changes.
+
 2013-10-24  Mark Rowe  <mrowe@apple.com>
 
         <rdar://problem/15312643> Prepare for the mysterious future.
index 5922766..50a006f 100644 (file)
@@ -152,7 +152,7 @@ RenderBlock::RenderBlock(Element& element, unsigned baseTypeFlags)
     , m_beingDestroyed(false)
     , m_hasMarkupTruncation(false)
     , m_hasBorderOrPaddingLogicalWidthChanged(false)
-    , m_forceLineBoxLayout(false)
+    , m_lineLayoutPath(UndeterminedPath)
 #if ENABLE(IOS_TEXT_AUTOSIZING)
     , m_widthForTextAutosizing(-1)
     , m_lineCountForTextAutosizing(NOT_SET)
@@ -168,7 +168,7 @@ RenderBlock::RenderBlock(Document& document, unsigned baseTypeFlags)
     , m_beingDestroyed(false)
     , m_hasMarkupTruncation(false)
     , m_hasBorderOrPaddingLogicalWidthChanged(false)
-    , m_forceLineBoxLayout(false)
+    , m_lineLayoutPath(UndeterminedPath)
 #if ENABLE(IOS_TEXT_AUTOSIZING)
     , m_widthForTextAutosizing(-1)
     , m_lineCountForTextAutosizing(NOT_SET)
@@ -822,6 +822,8 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
         }
     }
 
+    invalidateLineLayoutPath();
+
     RenderBox::addChild(newChild, beforeChild);
  
     // Handle placement of run-ins.
@@ -894,6 +896,13 @@ void RenderBlock::deleteLines()
         cache->recomputeIsIgnored(this);
 }
 
+void RenderBlock::invalidateLineLayoutPath()
+{
+    if (m_lineLayoutPath == ForceLineBoxesPath)
+        return;
+    m_lineLayoutPath = UndeterminedPath;
+}
+
 void RenderBlock::makeChildrenNonInline(RenderObject* insertionPoint)
 {    
     // makeChildrenNonInline takes a block whose children are *all* inline and it
@@ -1115,6 +1124,8 @@ void RenderBlock::removeChild(RenderObject& oldChild)
         }
     }
 
+    invalidateLineLayoutPath();
+
     RenderBox::removeChild(oldChild);
 
     RenderObject* child = prev ? prev : next;
index 2e1f947..ecacb04 100644 (file)
@@ -117,6 +117,8 @@ public:
 
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
 
+    void invalidateLineLayoutPath();
+
     void insertPositionedObject(RenderBox&);
     static void removePositionedObject(RenderBox&);
     void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
@@ -751,13 +753,14 @@ public:
 protected:
     OwnPtr<RenderBlockRareData> m_rareData;
 
-    mutable signed m_lineHeight : 26;
+    mutable signed m_lineHeight : 25;
     unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
     unsigned m_hasMarginAfterQuirk : 1;
     unsigned m_beingDestroyed : 1;
     unsigned m_hasMarkupTruncation : 1;
     unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
-    unsigned m_forceLineBoxLayout : 1;
+    enum LineLayoutPath { UndeterminedPath, SimpleLinesPath, LineBoxesPath, ForceLineBoxesPath };
+    unsigned m_lineLayoutPath : 2;
 
 #if ENABLE(IOS_TEXT_AUTOSIZING)
     int m_widthForTextAutosizing;
index 34058cd..b4fe9bd 100644 (file)
@@ -522,8 +522,10 @@ void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& max
 
 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
 {
-    bool canUseSimpleLineLayout = !m_forceLineBoxLayout && SimpleLineLayout::canUseFor(*this);
-    if (canUseSimpleLineLayout) {
+    if (m_lineLayoutPath == UndeterminedPath)
+        m_lineLayoutPath = SimpleLineLayout::canUseFor(*this) ? SimpleLinesPath : LineBoxesPath;
+
+    if (m_lineLayoutPath == SimpleLinesPath) {
         deleteLineBoxesBeforeSimpleLineLayout();
         layoutSimpleLines(repaintLogicalTop, repaintLogicalBottom);
         return;
@@ -1627,6 +1629,9 @@ void RenderBlockFlow::styleDidChange(StyleDifference diff, const RenderStyle* ol
 
     if (renderNamedFlowFragment())
         renderNamedFlowFragment()->setStyleForNamedFlowFragment(style());
+
+    if (diff >= StyleDifferenceRepaint)
+        invalidateLineLayoutPath();
 }
 
 void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
@@ -3020,14 +3025,14 @@ void RenderBlockFlow::layoutSimpleLines(LayoutUnit& repaintLogicalTop, LayoutUni
 
 void RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout()
 {
-    ASSERT(!m_forceLineBoxLayout);
+    ASSERT(m_lineLayoutPath == SimpleLinesPath);
     lineBoxes().deleteLineBoxes(renderArena());
     toRenderText(firstChild())->deleteLineBoxesBeforeSimpleLineLayout();
 }
 
 void RenderBlockFlow::ensureLineBoxes()
 {
-    m_forceLineBoxLayout = true;
+    m_lineLayoutPath = ForceLineBoxesPath;
 
     if (!m_simpleLines)
         return;
index ebea1e4..aeef662 100644 (file)
@@ -1010,6 +1010,9 @@ void RenderText::setText(const String& text, bool force)
     setTextInternal(text);
     setNeedsLayoutAndPrefWidthsRecalc();
     m_knownToHaveNoOverflowAndNoFallbackFonts = false;
+
+    if (parent()->isRenderBlockFlow())
+        toRenderBlockFlow(parent())->invalidateLineLayoutPath();
     
     if (AXObjectCache* cache = document().existingAXObjectCache())
         cache->textChanged(this);