Title: [174761] trunk
Revision
174761
Author
[email protected]
Date
2014-10-15 23:50:30 -0700 (Wed, 15 Oct 2014)

Log Message

ASSERTION  FAILED in WebCore::RenderFlowThread::getRegionRangeForBox
https://bugs.webkit.org/show_bug.cgi?id=135563

Reviewed by David Hyatt.

Source/WebCore:

The new multi-column code doesn't work correctly when the document contains nested fragmentation
contexts. The problem is the current flow thread concept that can store only one RenderFlowThread
at a time and use it during layout.

The stored flow thread is always correct for regions because named flow threads are absolutley positioned
so every child renderer is contained inside them (with the expcetion of fixed positioned elements which are
treated separately).

For multi-column elements this is no longer the case. An absolutely positioned element inside a static
multi-column element will be contained by a block outside the fragmentation context. It can even be
contained by a different multi-column element in the case of nested flow threads.

The patch below explores a solution that's not based on a current flow thread stored globally. The proposed
patch makes every block to store a pointer to its fragmentation context and a flag that states if this pointer
needs to be updated or not. If the renderer is not a block it will get its flow thread from the containing
block. Once the containing flow thread is requested for the block, the pointer is computed and cached until
invalidated:
- when a subtree is removed from a flow thread
- when the position property of an element inside a flow thread changes

The process is recursive and it doesn't affect elements that are not nested inside a flow thread. If a block
changes position from relative to static, any element that was contained by it can only be contained by an
ancestor of the block. This ancestor will still be outside of any flow thread. This ensures that non-fragmentation
code is not affected from a performance perspective.

The patch affects the results of the performance tests:
- the regions layout tests have a decreased performance raging from 2% to 5-6%
- the regions selection tests have an increased performance raging from 1-2% to 10%
- the multicolumn layout tests (now pending review in b137687) have an increased performance
raging from 1.8% to 5%

Tests: fast/multicol/multicol-all-positioned-crash.html
       fast/multicol/multicol-transform-containing-block.html

* rendering/FlowThreadController.cpp:
(WebCore::FlowThreadController::FlowThreadController):
* rendering/FlowThreadController.h:
(WebCore::FlowThreadController::currentRenderFlowThread): Deleted.
(WebCore::FlowThreadController::setCurrentRenderFlowThread): Deleted.
* rendering/LayoutState.h:
(WebCore::LayoutState::currentRenderFlowThread):
(WebCore::LayoutState::setCurrentRenderFlowThread):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlockRareData::RenderBlockRareData):
(WebCore::RenderBlock::styleWillChange):
(WebCore::RenderBlock::styleDidChange):
(WebCore::RenderBlock::collapseAnonymousBoxChild):
(WebCore::RenderBlock::cachedFlowThreadContainingBlock):
(WebCore::RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate):
(WebCore::RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate):
(WebCore::RenderBlock::updateCachedFlowThreadContainingBlock):
(WebCore::RenderBlock::locateFlowThreadContainingBlock):
* rendering/RenderBlock.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::styleWillChange):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::borderBoxRectInRegion):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::layout):
(WebCore::RenderFlowThread::updateAllLayerToRegionMappings):
(WebCore::RenderFlowThread::repaintRectangleInRegions):
(WebCore::CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer): Deleted.
(WebCore::CurrentRenderFlowThreadMaintainer::~CurrentRenderFlowThreadMaintainer): Deleted.
(WebCore::CurrentRenderFlowThreadDisabler::CurrentRenderFlowThreadDisabler): Deleted.
(WebCore::CurrentRenderFlowThreadDisabler::~CurrentRenderFlowThreadDisabler): Deleted.
* rendering/RenderFlowThread.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayer):
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::mapLayerClipRectsToFragmentationLayer):
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::showRegionsInformation):
(WebCore::RenderObject::insertedIntoTree):
(WebCore::RenderObject::removeFromRenderFlowThread):
(WebCore::RenderObject::removeFromRenderFlowThreadIncludingDescendants):
(WebCore::RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants):
(WebCore::RenderObject::currentRenderNamedFlowFragment):
(WebCore::RenderObject::locateFlowThreadContainingBlock):
(WebCore::RenderObject::locateFlowThreadContainingBlockNoCache): Deleted.
(WebCore::RenderObject::removeFromRenderFlowThreadRecursive): Deleted.
* rendering/RenderObject.h:
(WebCore::RenderObject::flowThreadContainingBlock):
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::computeOverflowFromFlowThread):
* rendering/RenderView.cpp:
(WebCore::RenderView::pushLayoutStateForCurrentFlowThread):
(WebCore::RenderView::popLayoutStateForCurrentFlowThread):
* rendering/RenderView.h:

LayoutTests:

A test verifying that positioned elements inside multi-column containers don't
cause assertions or crashes.

* fast/multicol/multicol-all-positioned-crash-expected.txt: Added.
* fast/multicol/multicol-all-positioned-crash.html: Added.
* fast/multicol/multicol-transform-containing-block-expected.txt: Added.
* fast/multicol/multicol-transform-containing-block.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (174760 => 174761)


--- trunk/LayoutTests/ChangeLog	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/LayoutTests/ChangeLog	2014-10-16 06:50:30 UTC (rev 174761)
@@ -1,3 +1,18 @@
+2014-10-15  Andrei Bucur  <[email protected]>
+
+        ASSERTION  FAILED in WebCore::RenderFlowThread::getRegionRangeForBox
+        https://bugs.webkit.org/show_bug.cgi?id=135563
+
+        Reviewed by David Hyatt.
+
+        A test verifying that positioned elements inside multi-column containers don't
+        cause assertions or crashes.
+
+        * fast/multicol/multicol-all-positioned-crash-expected.txt: Added.
+        * fast/multicol/multicol-all-positioned-crash.html: Added.
+        * fast/multicol/multicol-transform-containing-block-expected.txt: Added.
+        * fast/multicol/multicol-transform-containing-block.html: Added.
+
 2014-10-15  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r174753.

Added: trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash-expected.txt (0 => 174761)


--- trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash-expected.txt	2014-10-16 06:50:30 UTC (rev 174761)
@@ -0,0 +1 @@
+Test for the bug 135563. It should not crash or assert.

Added: trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash.html (0 => 174761)


--- trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-all-positioned-crash.html	2014-10-16 06:50:30 UTC (rev 174761)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<style>
+* {
+    -webkit-columns: 2;
+    position: absolute;
+}
+</style>
+</head>
+<body>
+Test for <a href="" bug 135563</a>. It should not crash or assert.
+<script>
+if (window.testRunner)
+    window.testRunner.dumpAsText();
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/multicol/multicol-transform-containing-block-expected.txt (0 => 174761)


--- trunk/LayoutTests/fast/multicol/multicol-transform-containing-block-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-transform-containing-block-expected.txt	2014-10-16 06:50:30 UTC (rev 174761)
@@ -0,0 +1 @@
+Test for b135563. It should not crash or assert.

Added: trunk/LayoutTests/fast/multicol/multicol-transform-containing-block.html (0 => 174761)


--- trunk/LayoutTests/fast/multicol/multicol-transform-containing-block.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/multicol-transform-containing-block.html	2014-10-16 06:50:30 UTC (rev 174761)
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<style>
+    #pos {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+    }
+
+    .multicol {
+        -webkit-column-count: 2;
+        height: 300px;
+    }
+
+    #transformed {
+        background: red;
+        width: 10px;
+        height: 10px;
+    }
+
+    .update {
+        -webkit-transform: rotate(-10deg);
+    }
+
+    .parent {
+        height: 400px;
+    }
+
+    .container {
+        padding: 50px;
+        margin: 20px;
+    }
+</style>
+<body>
+<div class="multicol parent">
+    <div id="change" class="container">
+        <div class="multicol">
+            <div>Static</div>
+            <div>Static</div>
+            <div>Static</div>
+            <div id="pos">Positioned</div>
+            <div>Static</div>
+            <div>Static</div>
+        </div>
+    </div>
+</div>
+<script type="text/_javascript_">
+    if (window.testRunner)
+        window.testRunner.dumpAsText();
+
+    document.body.offsetTop;
+    document.getElementById("change").className += " update";
+    document.body.offsetTop;
+    document.body.innerHTML = "Test for b135563. It should not crash or assert.";
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (174760 => 174761)


--- trunk/Source/WebCore/ChangeLog	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/ChangeLog	2014-10-16 06:50:30 UTC (rev 174761)
@@ -1,3 +1,100 @@
+2014-10-15  Andrei Bucur  <[email protected]>
+
+        ASSERTION  FAILED in WebCore::RenderFlowThread::getRegionRangeForBox
+        https://bugs.webkit.org/show_bug.cgi?id=135563
+
+        Reviewed by David Hyatt.
+
+        The new multi-column code doesn't work correctly when the document contains nested fragmentation
+        contexts. The problem is the current flow thread concept that can store only one RenderFlowThread
+        at a time and use it during layout.
+
+        The stored flow thread is always correct for regions because named flow threads are absolutley positioned
+        so every child renderer is contained inside them (with the expcetion of fixed positioned elements which are
+        treated separately).
+
+        For multi-column elements this is no longer the case. An absolutely positioned element inside a static
+        multi-column element will be contained by a block outside the fragmentation context. It can even be
+        contained by a different multi-column element in the case of nested flow threads.
+
+        The patch below explores a solution that's not based on a current flow thread stored globally. The proposed
+        patch makes every block to store a pointer to its fragmentation context and a flag that states if this pointer
+        needs to be updated or not. If the renderer is not a block it will get its flow thread from the containing
+        block. Once the containing flow thread is requested for the block, the pointer is computed and cached until
+        invalidated:
+        - when a subtree is removed from a flow thread
+        - when the position property of an element inside a flow thread changes
+
+        The process is recursive and it doesn't affect elements that are not nested inside a flow thread. If a block
+        changes position from relative to static, any element that was contained by it can only be contained by an
+        ancestor of the block. This ancestor will still be outside of any flow thread. This ensures that non-fragmentation
+        code is not affected from a performance perspective.
+
+        The patch affects the results of the performance tests:
+        - the regions layout tests have a decreased performance raging from 2% to 5-6%
+        - the regions selection tests have an increased performance raging from 1-2% to 10%
+        - the multicolumn layout tests (now pending review in b137687) have an increased performance
+        raging from 1.8% to 5%
+
+        Tests: fast/multicol/multicol-all-positioned-crash.html
+               fast/multicol/multicol-transform-containing-block.html
+
+        * rendering/FlowThreadController.cpp:
+        (WebCore::FlowThreadController::FlowThreadController):
+        * rendering/FlowThreadController.h:
+        (WebCore::FlowThreadController::currentRenderFlowThread): Deleted.
+        (WebCore::FlowThreadController::setCurrentRenderFlowThread): Deleted.
+        * rendering/LayoutState.h:
+        (WebCore::LayoutState::currentRenderFlowThread):
+        (WebCore::LayoutState::setCurrentRenderFlowThread):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlockRareData::RenderBlockRareData):
+        (WebCore::RenderBlock::styleWillChange):
+        (WebCore::RenderBlock::styleDidChange):
+        (WebCore::RenderBlock::collapseAnonymousBoxChild):
+        (WebCore::RenderBlock::cachedFlowThreadContainingBlock):
+        (WebCore::RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate):
+        (WebCore::RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate):
+        (WebCore::RenderBlock::updateCachedFlowThreadContainingBlock):
+        (WebCore::RenderBlock::locateFlowThreadContainingBlock):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::styleWillChange):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::borderBoxRectInRegion):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::layout):
+        (WebCore::RenderFlowThread::updateAllLayerToRegionMappings):
+        (WebCore::RenderFlowThread::repaintRectangleInRegions):
+        (WebCore::CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer): Deleted.
+        (WebCore::CurrentRenderFlowThreadMaintainer::~CurrentRenderFlowThreadMaintainer): Deleted.
+        (WebCore::CurrentRenderFlowThreadDisabler::CurrentRenderFlowThreadDisabler): Deleted.
+        (WebCore::CurrentRenderFlowThreadDisabler::~CurrentRenderFlowThreadDisabler): Deleted.
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayer):
+        (WebCore::RenderLayer::hitTestLayer):
+        (WebCore::RenderLayer::mapLayerClipRectsToFragmentationLayer):
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::showRegionsInformation):
+        (WebCore::RenderObject::insertedIntoTree):
+        (WebCore::RenderObject::removeFromRenderFlowThread):
+        (WebCore::RenderObject::removeFromRenderFlowThreadIncludingDescendants):
+        (WebCore::RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants):
+        (WebCore::RenderObject::currentRenderNamedFlowFragment):
+        (WebCore::RenderObject::locateFlowThreadContainingBlock):
+        (WebCore::RenderObject::locateFlowThreadContainingBlockNoCache): Deleted.
+        (WebCore::RenderObject::removeFromRenderFlowThreadRecursive): Deleted.
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::flowThreadContainingBlock):
+        * rendering/RenderRegion.cpp:
+        (WebCore::RenderRegion::computeOverflowFromFlowThread):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::pushLayoutStateForCurrentFlowThread):
+        (WebCore::RenderView::popLayoutStateForCurrentFlowThread):
+        * rendering/RenderView.h:
+
 2014-10-15  Chris Dumez  <[email protected]>
 
         Use is<>() / downcast<>() for list-related render objects

Modified: trunk/Source/WebCore/rendering/FlowThreadController.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/FlowThreadController.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/FlowThreadController.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -42,7 +42,6 @@
 
 FlowThreadController::FlowThreadController(RenderView* view)
     : m_view(view)
-    , m_currentRenderFlowThread(0)
     , m_isRenderNamedFlowThreadOrderDirty(false)
     , m_flowThreadsWithAutoLogicalHeightRegions(0)
 {

Modified: trunk/Source/WebCore/rendering/FlowThreadController.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/FlowThreadController.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/FlowThreadController.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -48,9 +48,6 @@
     explicit FlowThreadController(RenderView*);
     ~FlowThreadController();
 
-    RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }
-    void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }
-
     bool isRenderNamedFlowThreadOrderDirty() const { return m_isRenderNamedFlowThreadOrderDirty; }
     void setIsRenderNamedFlowThreadOrderDirty(bool dirty)
     {
@@ -96,7 +93,6 @@
 
 private:
     RenderView* m_view;
-    RenderFlowThread* m_currentRenderFlowThread;
     bool m_isRenderNamedFlowThreadOrderDirty;
     unsigned m_flowThreadsWithAutoLogicalHeightRegions;
     std::unique_ptr<RenderNamedFlowThreadList> m_renderNamedFlowThreadList;

Modified: trunk/Source/WebCore/rendering/LayoutState.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/LayoutState.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/LayoutState.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -83,6 +83,10 @@
     void setLineGridPaginationOrigin(const LayoutSize& origin) { m_lineGridPaginationOrigin = origin; }
     
     bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
+
+    RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }
+    void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }
+
 private:
     void propagateLineGridInfo(RenderBox*);
     void establishLineGrid(RenderBlockFlow*);
@@ -122,6 +126,8 @@
     LayoutSize m_lineGridOffset;
     LayoutSize m_lineGridPaginationOrigin;
 
+    RenderFlowThread* m_currentRenderFlowThread { nullptr };
+
 #ifndef NDEBUG
     RenderObject* m_renderer;
 #endif

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -68,7 +68,9 @@
 #include "ShadowRoot.h"
 #include "TextBreakIterator.h"
 #include "TransformState.h"
+
 #include <wtf/NeverDestroyed.h>
+#include <wtf/Optional.h>
 #include <wtf/StackStats.h>
 #include <wtf/TemporaryChange.h>
 
@@ -94,7 +96,7 @@
 
 static TrackedContainerMap* gPositionedContainerMap = 0;
 static TrackedContainerMap* gPercentHeightContainerMap = 0;
-    
+
 typedef HashMap<RenderBlock*, std::unique_ptr<ListHashSet<RenderInline*>>> ContinuationOutlineTableMap;
 
 struct UpdateScrollInfoAfterLayoutTransaction {
@@ -121,14 +123,17 @@
 struct RenderBlockRareData {
     WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
 public:
-    RenderBlockRareData() 
+    RenderBlockRareData()
         : m_paginationStrut(0)
         , m_pageLogicalOffset(0)
-    { 
+        , m_flowThreadContainingBlock(Nullopt)
+    {
     }
 
     LayoutUnit m_paginationStrut;
     LayoutUnit m_pageLogicalOffset;
+
+    Optional<RenderFlowThread*> m_flowThreadContainingBlock;
 };
 
 typedef HashMap<const RenderBlock*, std::unique_ptr<RenderBlockRareData>> RenderBlockRareDataMap;
@@ -266,7 +271,7 @@
     const RenderStyle* oldStyle = hasInitializedStyle() ? &style() : nullptr;
 
     setReplaced(newStyle.isDisplayInlineType());
-    
+
     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle.position()) {
         if (newStyle.position() == StaticPosition)
             // Clear our positioned objects list. Our absolutely positioned descendants will be
@@ -283,7 +288,7 @@
                 }
                 containingBlock = containingBlock->parent();
             }
-            
+
             if (is<RenderBlock>(*containingBlock))
                 downcast<RenderBlock>(*containingBlock).removePositionedObjects(this, NewContainingBlock);
         }
@@ -308,10 +313,20 @@
 
 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
-    RenderBox::styleDidChange(diff, oldStyle);
-    
     RenderStyle& newStyle = style();
 
+    bool hadTransform = hasTransform();
+    bool flowThreadContainingBlockInvalidated = false;
+    if (oldStyle && oldStyle->position() != newStyle.position()) {
+        invalidateFlowThreadContainingBlockIncludingDescendants();
+        flowThreadContainingBlockInvalidated = true;
+    }
+
+    RenderBox::styleDidChange(diff, oldStyle);
+
+    if (hadTransform != hasTransform() && !flowThreadContainingBlockInvalidated)
+        invalidateFlowThreadContainingBlockIncludingDescendants();
+
     if (!isAnonymousBlock()) {
         // Ensure that all of our continuation blocks pick up the new style.
         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
@@ -324,7 +339,7 @@
 
     propagateStyleToAnonymousChildren(PropagateToBlockChildrenOnly);
     m_lineHeight = -1;
-    
+
     // It's possible for our border/padding to change, but for the overall logical width of the block to
     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, &newStyle);
@@ -690,7 +705,6 @@
     RenderObject* nextSibling = child->nextSibling();
 
     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
-    CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
         toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
 
@@ -3254,6 +3268,50 @@
     createFirstLetterRenderer(firstLetterContainer, downcast<RenderText>(firstLetterObj));
 }
 
+RenderFlowThread* RenderBlock::cachedFlowThreadContainingBlock() const
+{
+    RenderBlockRareData* rareData = getRareData(this);
+
+    if (!rareData || !rareData->m_flowThreadContainingBlock)
+        return nullptr;
+
+    return rareData->m_flowThreadContainingBlock.value();
+}
+
+bool RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate() const
+{
+    RenderBlockRareData* rareData = getRareData(this);
+
+    if (!rareData || !rareData->m_flowThreadContainingBlock)
+        return true;
+
+    return false;
+}
+
+void RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate()
+{
+    RenderBlockRareData& rareData = ensureRareData(this);
+    rareData.m_flowThreadContainingBlock = Nullopt;
+}
+
+RenderFlowThread* RenderBlock::updateCachedFlowThreadContainingBlock(RenderFlowThread* flowThread) const
+{
+    RenderBlockRareData& rareData = ensureRareData(this);
+    rareData.m_flowThreadContainingBlock = flowThread;
+
+    return flowThread;
+}
+
+RenderFlowThread* RenderBlock::locateFlowThreadContainingBlock() const
+{
+    RenderBlockRareData* rareData = getRareData(this);
+    if (!rareData || !rareData->m_flowThreadContainingBlock)
+        return updateCachedFlowThreadContainingBlock(RenderBox::locateFlowThreadContainingBlock());
+
+    ASSERT(rareData->m_flowThreadContainingBlock.value() == RenderBox::locateFlowThreadContainingBlock());
+    return rareData->m_flowThreadContainingBlock.value();
+}
+
 LayoutUnit RenderBlock::paginationStrut() const
 {
     RenderBlockRareData* rareData = getRareData(this);

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -312,7 +312,12 @@
     virtual bool canHaveChildren() const override { return true; }
     virtual bool canCollapseAnonymousBlockChild() const { return true; }
 
+    RenderFlowThread* cachedFlowThreadContainingBlock() const;
+    void setCachedFlowThreadContainingBlockNeedsUpdate();
+    virtual bool cachedFlowThreadContainingBlockNeedsUpdate() const;
+
 protected:
+    virtual RenderFlowThread* locateFlowThreadContainingBlock() const override;
     virtual void willBeDestroyed() override;
 
     virtual void layout() override;
@@ -449,7 +454,7 @@
 
     virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const override final;
     virtual const RenderStyle& outlineStyleForRepaint() const override final;
-    
+
     virtual RenderElement* hoverAncestor() const override final;
     virtual void updateDragState(bool dragOn) override final;
     virtual void childBecameNonInline(RenderObject* child) override final;
@@ -489,6 +494,8 @@
     RenderPtr<RenderBlock> clone() const;
     RenderBlock* continuationBefore(RenderObject* beforeChild);
 
+    RenderFlowThread* updateCachedFlowThreadContainingBlock(RenderFlowThread*) const;
+
 private:
     bool hasRareData() const;
     

Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -1985,18 +1985,10 @@
     if (oldStyle) {
         EPosition oldPosition = oldStyle->position();
         EPosition newPosition = newStyle.position();
-        
+
         if (parent() && diff == StyleDifferenceLayout && oldPosition != newPosition) {
             if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle.hasOutOfFlowPosition())
                 markAllDescendantsWithFloatsForLayout();
-
-            // If this block is inside a multicol and is moving from in-flow positioning to out-of-flow positioning,
-            // remove its info (such as lines-to-region mapping) from the flowthread because it won't be able to do it later.
-            // The flowthread will no longer be in its containing block chain and, as such, flowThreadContainingBlock will return null.
-            if (RenderFlowThread* flowThread = flowThreadContainingBlock(SkipFlowThreadCache)) {
-                if (flowThread->isRenderMultiColumnFlowThread() && !isOutOfFlowPositioned() && (newPosition == AbsolutePosition || newPosition == FixedPosition))
-                    flowThread->removeFlowChildInfo(this);
-            }
         }
     }
 

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -196,7 +196,7 @@
         // FIXME: In a perfect world this condition should never happen.
         return borderBoxRect();
     }
-    
+
     ASSERT(flowThread->regionInRange(region, startRegion, endRegion));
 
     // Compute the logical width and placement in this region.
@@ -207,21 +207,26 @@
     // We have cached insets.
     LayoutUnit logicalWidth = boxInfo->logicalWidth();
     LayoutUnit logicalLeft = boxInfo->logicalLeft();
-        
+
     // Now apply the parent inset since it is cumulative whenever anything in the containing block chain shifts.
     // FIXME: Doesn't work right with perpendicular writing modes.
     const RenderBlock* currentBox = containingBlock();
-    RenderBoxRegionInfo* currentBoxInfo = currentBox->renderBoxRegionInfo(region);
+    RenderBoxRegionInfo* currentBoxInfo = isRenderFlowThread() ? nullptr : currentBox->renderBoxRegionInfo(region);
     while (currentBoxInfo && currentBoxInfo->isShifted()) {
         if (currentBox->style().direction() == LTR)
             logicalLeft += currentBoxInfo->logicalLeft();
         else
             logicalLeft -= (currentBox->logicalWidth() - currentBoxInfo->logicalWidth()) - currentBoxInfo->logicalLeft();
+
+        // Once we reach the fragmentation container we should stop.
+        if (currentBox->isRenderFlowThread())
+            break;
+
         currentBox = currentBox->containingBlock();
         region = currentBox->clampToStartAndEndRegions(region);
         currentBoxInfo = currentBox->renderBoxRegionInfo(region);
     }
-    
+
     if (cacheFlag == DoNotCacheRenderBoxRegionInfo)
         delete boxInfo;
 

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -197,7 +197,6 @@
 
     validateRegions();
 
-    CurrentRenderFlowThreadMaintainer currentFlowThreadSetter(this);
     RenderBlockFlow::layout();
 
     m_pageLogicalSizeChanged = false;
@@ -288,10 +287,6 @@
     if (!collectsGraphicsLayersUnderRegions())
         return false;
 
-    // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.
-    // Let each region figure out the proper enclosing flow thread.
-    CurrentRenderFlowThreadDisabler disabler(&view());
-
     // If the RenderFlowThread had a z-index layer update, then we need to update the composited layers too.
     bool needsLayerUpdate = layer()->isDirtyRenderFlowThread() || m_layersToRegionMappingsDirty || !m_layerToRegionMap.get();
     layer()->updateLayerListsIfNeeded();
@@ -388,10 +383,6 @@
 
     LayoutStateDisabler layoutStateDisabler(&view()); // We can't use layout state to repaint, since the regions are somewhere else.
 
-    // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.
-    // Let each region figure out the proper enclosing flow thread.
-    CurrentRenderFlowThreadDisabler disabler(&view());
-    
     for (auto& region : m_regionList)
         region->repaintFlowThreadContent(repaintRect);
 }
@@ -1522,42 +1513,5 @@
     return *m_lineToRegionMap.get();
 }
 
-CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowThread* renderFlowThread)
-    : m_renderFlowThread(renderFlowThread)
-    , m_previousRenderFlowThread(0)
-{
-    if (!m_renderFlowThread)
-        return;
-    FlowThreadController& controller = m_renderFlowThread->view().flowThreadController();
-    m_previousRenderFlowThread = controller.currentRenderFlowThread();
-    // Remove the assert so we can use this to change the flow thread context.
-    // ASSERT(!m_previousRenderFlowThread || !renderFlowThread->isRenderNamedFlowThread());
-    controller.setCurrentRenderFlowThread(m_renderFlowThread);
-}
 
-CurrentRenderFlowThreadMaintainer::~CurrentRenderFlowThreadMaintainer()
-{
-    if (!m_renderFlowThread)
-        return;
-    FlowThreadController& controller = m_renderFlowThread->view().flowThreadController();
-    ASSERT(controller.currentRenderFlowThread() == m_renderFlowThread);
-    controller.setCurrentRenderFlowThread(m_previousRenderFlowThread);
-}
-
-CurrentRenderFlowThreadDisabler::CurrentRenderFlowThreadDisabler(RenderView* view)
-    : m_view(view)
-    , m_renderFlowThread(0)
-{
-    m_renderFlowThread = m_view->flowThreadController().currentRenderFlowThread();
-    if (m_renderFlowThread)
-        view->flowThreadController().setCurrentRenderFlowThread(0);
-}
-
-CurrentRenderFlowThreadDisabler::~CurrentRenderFlowThreadDisabler()
-{
-    if (m_renderFlowThread)
-        m_view->flowThreadController().setCurrentRenderFlowThread(m_renderFlowThread);
-}
-
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderFlowThread.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -231,6 +231,8 @@
 
     ContainingRegionMap& containingRegionMap();
 
+    virtual bool cachedFlowThreadContainingBlockNeedsUpdate() const override { return false; }
+
     // FIXME: Eventually as column and region flow threads start nesting, this may end up changing.
     virtual bool shouldCheckColumnBreaks() const { return false; }
 
@@ -244,6 +246,8 @@
 protected:
     RenderFlowThread(Document&, PassRef<RenderStyle>);
 
+    virtual RenderFlowThread* locateFlowThreadContainingBlock() const override { return const_cast<RenderFlowThread*>(this); }
+
     virtual const char* renderName() const = 0;
 
     // Overridden by columns/pages to set up an initial logical width of the page width even when
@@ -374,26 +378,6 @@
 
 RENDER_OBJECT_TYPE_CASTS(RenderFlowThread, isRenderFlowThread())
 
-class CurrentRenderFlowThreadMaintainer {
-    WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadMaintainer);
-public:
-    CurrentRenderFlowThreadMaintainer(RenderFlowThread*);
-    ~CurrentRenderFlowThreadMaintainer();
-private:
-    RenderFlowThread* m_renderFlowThread;
-    RenderFlowThread* m_previousRenderFlowThread;
-};
-
-class CurrentRenderFlowThreadDisabler {
-    WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadDisabler);
-public:
-    CurrentRenderFlowThreadDisabler(RenderView*);
-    ~CurrentRenderFlowThreadDisabler();
-private:
-    RenderView* m_view;
-    RenderFlowThread* m_renderFlowThread;
-};
-
 // This structure is used by PODIntervalTree for debugging.
 #ifndef NDEBUG
 template <> struct ValueToString<RenderRegion*> {

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -3771,12 +3771,6 @@
 
     // Don't paint the layer if the renderer doesn't belong to this region.
     // This is true as long as we clamp the range of a box to its containing block range.
-
-    // Disable named flow region information for in flow threads such as multi-col.
-    std::unique_ptr<CurrentRenderFlowThreadDisabler> flowThreadDisabler;
-    if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers))
-        flowThreadDisabler = std::make_unique<CurrentRenderFlowThreadDisabler>(&renderer().view());
-
     RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
     if (namedFlowFragment) {
         ASSERT(namedFlowFragment->isValid());
@@ -4821,11 +4815,6 @@
     if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
         return 0;
 
-    // Disable named flow region information for in flow threads such as multi-col.
-    std::unique_ptr<CurrentRenderFlowThreadDisabler> flowThreadDisabler;
-    if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers))
-        flowThreadDisabler = std::make_unique<CurrentRenderFlowThreadDisabler>(&renderer().view());
-
     RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
 
     // Prevent hitting the fixed layers inside the flow thread when hitting through regions.
@@ -5232,8 +5221,7 @@
         return false;
 
     ASSERT(namedFlowFragment->parent() && namedFlowFragment->parent()->isRenderNamedFlowFragmentContainer());
-    
-    CurrentRenderFlowThreadDisabler flowThreadDisabler(&renderer().view());
+
     ClipRectsContext targetClipRectsContext(&namedFlowFragment->fragmentContainerLayer(), TemporaryClipRects);
     namedFlowFragment->fragmentContainerLayer().calculateClipRects(targetClipRectsContext, clipRects);
 
@@ -6710,7 +6698,6 @@
 void RenderLayer::paintNamedFlowThreadInsideRegion(GraphicsContext* context, RenderNamedFlowFragment* region, LayoutRect paintDirtyRect, LayoutPoint paintOffset, PaintBehavior paintBehavior, PaintLayerFlags paintFlags)
 {
     LayoutRect regionContentBox = toRenderBox(region->layerOwner()).contentBoxRect();
-    CurrentRenderFlowThreadMaintainer flowThreadMaintainer(toRenderFlowThread(&renderer()));
     CurrentRenderRegionMaintainer regionMaintainer(*region);
     region->setRegionObjectsRegionStyle();
 
@@ -6817,7 +6804,6 @@
         hitTestRectInFlowThread.move(hitTestOffset);
         hitTestRectInFlowThread.expand(LayoutSize(fabs((double)hitTestOffset.width()), fabs((double)hitTestOffset.height())));
 
-        CurrentRenderFlowThreadMaintainer flowThreadMaintainer(flowThread);
         CurrentRenderRegionMaintainer regionMaintainer(region);
 
         HitTestResult tempResult(result.hitTestLocation());

Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderObject.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -522,38 +522,6 @@
     return false;
 }
 
-RenderFlowThread* RenderObject::locateFlowThreadContainingBlockNoCache() const
-{
-    ASSERT(flowThreadState() != NotInsideFlowThread);
-
-    RenderObject* curr = const_cast<RenderObject*>(this);
-    while (curr) {
-        if (curr->isRenderFlowThread())
-            return toRenderFlowThread(curr);
-        curr = curr->containingBlock();
-    }
-    return 0;
-}
-
-RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
-{
-    ASSERT(flowThreadState() != NotInsideFlowThread);
-
-    // See if we have the thread cached because we're in the middle of layout.
-    RenderFlowThread* flowThread = view().flowThreadController().currentRenderFlowThread();
-    if (flowThread && (flowThreadState() == flowThread->flowThreadState())) {
-        // Make sure the slow path would return the same result as our cache.
-        // FIXME: For the moment, only apply this assertion to regions, as multicol
-        // still has some issues and triggers this assert.
-        // Created https://bugs.webkit.org/show_bug.cgi?id=132946 for this issue.
-        ASSERT(!flowThread->isRenderNamedFlowThread() || flowThread == locateFlowThreadContainingBlockNoCache());
-        return flowThread;
-    }
-    
-    // Not in the middle of layout so have to find the thread the slow way.
-    return locateFlowThreadContainingBlockNoCache();
-}
-
 RenderBlock* RenderObject::firstLineBlock() const
 {
     return 0;
@@ -1438,8 +1406,6 @@
 
 void RenderObject::showRegionsInformation() const
 {
-    CurrentRenderFlowThreadDisabler flowThreadDisabler(&view());
-
     if (RenderFlowThread* flowThread = flowThreadContainingBlock()) {
         const RenderBox* box = isBox() ? toRenderBox(this) : nullptr;
         if (box) {
@@ -2048,17 +2014,9 @@
 
     if (!isFloating() && parent()->childrenInline())
         parent()->dirtyLinesFromChangedChild(*this);
-    
-    // We have to unset the current layout RenderFlowThread here, since insertedIntoTree() can happen in
-    // the middle of layout but for objects inside a nested flow thread that is still being populated. This
-    // will cause an accurate crawl to happen in order to ensure that the right flow thread is notified.
-    RenderFlowThread* previousThread = view().flowThreadController().currentRenderFlowThread();
-    view().flowThreadController().setCurrentRenderFlowThread(nullptr);
-    if (parent()->isRenderFlowThread())
-        toRenderFlowThread(parent())->flowThreadDescendantInserted(this);
-    else if (RenderFlowThread* flowThread = parent()->flowThreadContainingBlock())
+
+    if (RenderFlowThread* flowThread = flowThreadContainingBlock())
         flowThread->flowThreadDescendantInserted(this);
-    view().flowThreadController().setCurrentRenderFlowThread(previousThread);
 }
 
 void RenderObject::willBeRemovedFromTree()
@@ -2075,27 +2033,56 @@
 {
     if (flowThreadState() == NotInsideFlowThread)
         return;
-    
+
     // Sometimes we remove the element from the flow, but it's not destroyed at that time.
-    // It's only until later when we actually destroy it and remove all the children from it. 
+    // It's only until later when we actually destroy it and remove all the children from it.
     // Currently, that happens for firstLetter elements and list markers.
     // Pass in the flow thread so that we don't have to look it up for all the children.
-    removeFromRenderFlowThreadRecursive(flowThreadContainingBlock());
+    removeFromRenderFlowThreadIncludingDescendants(true);
 }
 
-void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderFlowThread)
+void RenderObject::removeFromRenderFlowThreadIncludingDescendants(bool shouldUpdateState)
 {
+    // Once we reach another flow thread we don't need to update the flow thread state
+    // but we have to continue cleanup the flow thread info.
+    if (isRenderFlowThread())
+        shouldUpdateState = false;
+
     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
-        child->removeFromRenderFlowThreadRecursive(renderFlowThread);
+        child->removeFromRenderFlowThreadIncludingDescendants(shouldUpdateState);
 
-    RenderFlowThread* localFlowThread = renderFlowThread;
-    if (flowThreadState() == InsideInFlowThread)
-        localFlowThread = flowThreadContainingBlock(); // We have to ask. We can't just assume we are in the same flow thread.
-    if (localFlowThread)
-        localFlowThread->removeFlowChildInfo(this);
-    setFlowThreadState(NotInsideFlowThread);
+    // We have to ask for our containing flow thread as it may be above the removed sub-tree.
+    RenderFlowThread* flowThreadContainingBlock = this->flowThreadContainingBlock();
+    if (flowThreadContainingBlock)
+        flowThreadContainingBlock->removeFlowChildInfo(this);
+    if (is<RenderBlock>(*this))
+        downcast<RenderBlock>(*this).setCachedFlowThreadContainingBlockNeedsUpdate();
+    if (shouldUpdateState)
+        setFlowThreadState(NotInsideFlowThread);
 }
 
+void RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants(RenderFlowThread* flowThread)
+{
+    if (flowThreadState() == NotInsideFlowThread)
+        return;
+
+    if (is<RenderBlock>(*this)) {
+        RenderBlock& block = downcast<RenderBlock>(*this);
+
+        if (block.cachedFlowThreadContainingBlockNeedsUpdate())
+            return;
+
+        flowThread = block.cachedFlowThreadContainingBlock();
+        block.setCachedFlowThreadContainingBlockNeedsUpdate();
+    }
+
+    if (flowThread)
+        flowThread->removeFlowChildInfo(this);
+
+    for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
+        child->invalidateFlowThreadContainingBlockIncludingDescendants(flowThread);
+}
+
 void RenderObject::destroyAndCleanupAnonymousWrappers()
 {
     // If the tree is destroyed, there is no need for a clean-up phase.
@@ -2597,24 +2584,24 @@
 
 RenderNamedFlowFragment* RenderObject::currentRenderNamedFlowFragment() const
 {
-    if (flowThreadState() == NotInsideFlowThread)
+    RenderFlowThread* flowThread = flowThreadContainingBlock();
+    if (!flowThread || !flowThread->isRenderNamedFlowThread())
         return nullptr;
 
-    RenderFlowThread* flowThread = view().flowThreadController().currentRenderFlowThread();
-    if (!flowThread)
-        return nullptr;
-
-    ASSERT(flowThread == flowThreadContainingBlock());
-
     // FIXME: Once regions are fully integrated with the compositing system we should uncomment this assert.
     // This assert needs to be disabled because it's possible to ask for the ancestor clipping rectangle of
     // a layer without knowing the containing region in advance.
     // ASSERT(flowThread->currentRegion() && flowThread->currentRegion()->isRenderNamedFlowFragment());
 
-    RenderNamedFlowFragment* namedFlowFragment = toRenderNamedFlowFragment(flowThread->currentRegion());
-    return namedFlowFragment;
+    return toRenderNamedFlowFragment(flowThread->currentRegion());
 }
 
+RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
+{
+    RenderBlock* containingBlock = this->containingBlock();
+    return containingBlock ? containingBlock->flowThreadContainingBlock() : nullptr;
+}
+
 } // namespace WebCore
 
 #ifndef NDEBUG

Modified: trunk/Source/WebCore/rendering/RenderObject.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderObject.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderObject.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -212,18 +212,14 @@
 
     bool fixedPositionedWithNamedFlowContainingBlock() const;
 
-    enum ShouldUseFlowThreadCache {
-        UseFlowThreadCache,
-        SkipFlowThreadCache
-    };
-
     // Function to return our enclosing flow thread if we are contained inside one. This
     // function follows the containing block chain.
-    RenderFlowThread* flowThreadContainingBlock(ShouldUseFlowThreadCache useCache = UseFlowThreadCache) const
+    RenderFlowThread* flowThreadContainingBlock() const
     {
         if (flowThreadState() == NotInsideFlowThread)
-            return 0;
-        return (useCache == SkipFlowThreadCache) ? locateFlowThreadContainingBlockNoCache() : locateFlowThreadContainingBlock();
+            return nullptr;
+
+        return locateFlowThreadContainingBlock();
     }
 
     RenderNamedFlowFragment* currentRenderNamedFlowFragment() const;
@@ -892,12 +888,12 @@
     void setPosChildNeedsLayoutBit(bool b) { m_bitfields.setPosChildNeedsLayout(b); }
     void setNeedsSimplifiedNormalFlowLayoutBit(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); }
 
+    virtual RenderFlowThread* locateFlowThreadContainingBlock() const;
+    void invalidateFlowThreadContainingBlockIncludingDescendants(RenderFlowThread* = nullptr);
+
 private:
-    RenderFlowThread* locateFlowThreadContainingBlock() const;
-    RenderFlowThread* locateFlowThreadContainingBlockNoCache() const;
-    
     void removeFromRenderFlowThread();
-    void removeFromRenderFlowThreadRecursive(RenderFlowThread*);
+    void removeFromRenderFlowThreadIncludingDescendants(bool);
 
     Color selectionColor(int colorProperty) const;
     PassRefPtr<RenderStyle> selectionPseudoStyle() const;

Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderRegion.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -218,15 +218,8 @@
 void RenderRegion::computeOverflowFromFlowThread()
 {
     ASSERT(isValid());
-    
-    LayoutRect layoutRect;
-    {
-        // When getting the overflow from the flow thread we need to temporarly reset the current flow thread because
-        // we're changing flows.
-        CurrentRenderFlowThreadMaintainer flowThreadMaintainer(m_flowThread);
-        layoutRect = layoutOverflowRectForBox(m_flowThread);
-    }
 
+    LayoutRect layoutRect = layoutOverflowRectForBox(m_flowThread);
     layoutRect.setLocation(contentBoxRect().location() + (layoutRect.location() - m_flowThreadPortionRect.location()));
 
     // FIXME: Correctly adjust the layout overflow for writing modes.

Modified: trunk/Source/WebCore/rendering/RenderView.cpp (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderView.cpp	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderView.cpp	2014-10-16 06:50:30 UTC (rev 174761)
@@ -1311,10 +1311,12 @@
     if (!m_flowThreadController)
         return;
 
-    RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
+    RenderFlowThread* currentFlowThread = object.flowThreadContainingBlock();
     if (!currentFlowThread)
         return;
 
+    m_layoutState->setCurrentRenderFlowThread(currentFlowThread);
+
     currentFlowThread->pushFlowThreadLayoutState(object);
 }
 
@@ -1323,7 +1325,7 @@
     if (!m_flowThreadController)
         return;
 
-    RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
+    RenderFlowThread* currentFlowThread = m_layoutState->currentRenderFlowThread();
     if (!currentFlowThread)
         return;
 

Modified: trunk/Source/WebCore/rendering/RenderView.h (174760 => 174761)


--- trunk/Source/WebCore/rendering/RenderView.h	2014-10-16 06:45:53 UTC (rev 174760)
+++ trunk/Source/WebCore/rendering/RenderView.h	2014-10-16 06:50:30 UTC (rev 174761)
@@ -295,7 +295,7 @@
 
     void pushLayoutStateForCurrentFlowThread(const RenderObject&);
     void popLayoutStateForCurrentFlowThread();
-    
+
     friend class LayoutStateMaintainer;
     friend class LayoutStateDisabler;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to