Changeset 174761 in webkit
- Timestamp:
- Oct 15, 2014 11:50:30 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r174755 r174761 1 2014-10-15 Andrei Bucur <abucur@adobe.com> 2 3 ASSERTION FAILED in WebCore::RenderFlowThread::getRegionRangeForBox 4 https://bugs.webkit.org/show_bug.cgi?id=135563 5 6 Reviewed by David Hyatt. 7 8 A test verifying that positioned elements inside multi-column containers don't 9 cause assertions or crashes. 10 11 * fast/multicol/multicol-all-positioned-crash-expected.txt: Added. 12 * fast/multicol/multicol-all-positioned-crash.html: Added. 13 * fast/multicol/multicol-transform-containing-block-expected.txt: Added. 14 * fast/multicol/multicol-transform-containing-block.html: Added. 15 1 16 2014-10-15 Commit Queue <commit-queue@webkit.org> 2 17 -
trunk/Source/WebCore/ChangeLog
r174759 r174761 1 2014-10-15 Andrei Bucur <abucur@adobe.com> 2 3 ASSERTION FAILED in WebCore::RenderFlowThread::getRegionRangeForBox 4 https://bugs.webkit.org/show_bug.cgi?id=135563 5 6 Reviewed by David Hyatt. 7 8 The new multi-column code doesn't work correctly when the document contains nested fragmentation 9 contexts. The problem is the current flow thread concept that can store only one RenderFlowThread 10 at a time and use it during layout. 11 12 The stored flow thread is always correct for regions because named flow threads are absolutley positioned 13 so every child renderer is contained inside them (with the expcetion of fixed positioned elements which are 14 treated separately). 15 16 For multi-column elements this is no longer the case. An absolutely positioned element inside a static 17 multi-column element will be contained by a block outside the fragmentation context. It can even be 18 contained by a different multi-column element in the case of nested flow threads. 19 20 The patch below explores a solution that's not based on a current flow thread stored globally. The proposed 21 patch makes every block to store a pointer to its fragmentation context and a flag that states if this pointer 22 needs to be updated or not. If the renderer is not a block it will get its flow thread from the containing 23 block. Once the containing flow thread is requested for the block, the pointer is computed and cached until 24 invalidated: 25 - when a subtree is removed from a flow thread 26 - when the position property of an element inside a flow thread changes 27 28 The process is recursive and it doesn't affect elements that are not nested inside a flow thread. If a block 29 changes position from relative to static, any element that was contained by it can only be contained by an 30 ancestor of the block. This ancestor will still be outside of any flow thread. This ensures that non-fragmentation 31 code is not affected from a performance perspective. 32 33 The patch affects the results of the performance tests: 34 - the regions layout tests have a decreased performance raging from 2% to 5-6% 35 - the regions selection tests have an increased performance raging from 1-2% to 10% 36 - the multicolumn layout tests (now pending review in b137687) have an increased performance 37 raging from 1.8% to 5% 38 39 Tests: fast/multicol/multicol-all-positioned-crash.html 40 fast/multicol/multicol-transform-containing-block.html 41 42 * rendering/FlowThreadController.cpp: 43 (WebCore::FlowThreadController::FlowThreadController): 44 * rendering/FlowThreadController.h: 45 (WebCore::FlowThreadController::currentRenderFlowThread): Deleted. 46 (WebCore::FlowThreadController::setCurrentRenderFlowThread): Deleted. 47 * rendering/LayoutState.h: 48 (WebCore::LayoutState::currentRenderFlowThread): 49 (WebCore::LayoutState::setCurrentRenderFlowThread): 50 * rendering/RenderBlock.cpp: 51 (WebCore::RenderBlockRareData::RenderBlockRareData): 52 (WebCore::RenderBlock::styleWillChange): 53 (WebCore::RenderBlock::styleDidChange): 54 (WebCore::RenderBlock::collapseAnonymousBoxChild): 55 (WebCore::RenderBlock::cachedFlowThreadContainingBlock): 56 (WebCore::RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate): 57 (WebCore::RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate): 58 (WebCore::RenderBlock::updateCachedFlowThreadContainingBlock): 59 (WebCore::RenderBlock::locateFlowThreadContainingBlock): 60 * rendering/RenderBlock.h: 61 * rendering/RenderBlockFlow.cpp: 62 (WebCore::RenderBlockFlow::styleWillChange): 63 * rendering/RenderBox.cpp: 64 (WebCore::RenderBox::borderBoxRectInRegion): 65 * rendering/RenderFlowThread.cpp: 66 (WebCore::RenderFlowThread::layout): 67 (WebCore::RenderFlowThread::updateAllLayerToRegionMappings): 68 (WebCore::RenderFlowThread::repaintRectangleInRegions): 69 (WebCore::CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer): Deleted. 70 (WebCore::CurrentRenderFlowThreadMaintainer::~CurrentRenderFlowThreadMaintainer): Deleted. 71 (WebCore::CurrentRenderFlowThreadDisabler::CurrentRenderFlowThreadDisabler): Deleted. 72 (WebCore::CurrentRenderFlowThreadDisabler::~CurrentRenderFlowThreadDisabler): Deleted. 73 * rendering/RenderFlowThread.h: 74 * rendering/RenderLayer.cpp: 75 (WebCore::RenderLayer::paintLayer): 76 (WebCore::RenderLayer::hitTestLayer): 77 (WebCore::RenderLayer::mapLayerClipRectsToFragmentationLayer): 78 (WebCore::RenderLayer::calculateClipRects): 79 * rendering/RenderObject.cpp: 80 (WebCore::RenderObject::showRegionsInformation): 81 (WebCore::RenderObject::insertedIntoTree): 82 (WebCore::RenderObject::removeFromRenderFlowThread): 83 (WebCore::RenderObject::removeFromRenderFlowThreadIncludingDescendants): 84 (WebCore::RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants): 85 (WebCore::RenderObject::currentRenderNamedFlowFragment): 86 (WebCore::RenderObject::locateFlowThreadContainingBlock): 87 (WebCore::RenderObject::locateFlowThreadContainingBlockNoCache): Deleted. 88 (WebCore::RenderObject::removeFromRenderFlowThreadRecursive): Deleted. 89 * rendering/RenderObject.h: 90 (WebCore::RenderObject::flowThreadContainingBlock): 91 * rendering/RenderRegion.cpp: 92 (WebCore::RenderRegion::computeOverflowFromFlowThread): 93 * rendering/RenderView.cpp: 94 (WebCore::RenderView::pushLayoutStateForCurrentFlowThread): 95 (WebCore::RenderView::popLayoutStateForCurrentFlowThread): 96 * rendering/RenderView.h: 97 1 98 2014-10-15 Chris Dumez <cdumez@apple.com> 2 99 -
trunk/Source/WebCore/rendering/FlowThreadController.cpp
r173765 r174761 43 43 FlowThreadController::FlowThreadController(RenderView* view) 44 44 : m_view(view) 45 , m_currentRenderFlowThread(0)46 45 , m_isRenderNamedFlowThreadOrderDirty(false) 47 46 , m_flowThreadsWithAutoLogicalHeightRegions(0) -
trunk/Source/WebCore/rendering/FlowThreadController.h
r166489 r174761 49 49 ~FlowThreadController(); 50 50 51 RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }52 void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }53 54 51 bool isRenderNamedFlowThreadOrderDirty() const { return m_isRenderNamedFlowThreadOrderDirty; } 55 52 void setIsRenderNamedFlowThreadOrderDirty(bool dirty) … … 97 94 private: 98 95 RenderView* m_view; 99 RenderFlowThread* m_currentRenderFlowThread;100 96 bool m_isRenderNamedFlowThreadOrderDirty; 101 97 unsigned m_flowThreadsWithAutoLogicalHeightRegions; -
trunk/Source/WebCore/rendering/LayoutState.h
r168380 r174761 84 84 85 85 bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); } 86 87 RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; } 88 void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; } 89 86 90 private: 87 91 void propagateLineGridInfo(RenderBox*); … … 123 127 LayoutSize m_lineGridPaginationOrigin; 124 128 129 RenderFlowThread* m_currentRenderFlowThread { nullptr }; 130 125 131 #ifndef NDEBUG 126 132 RenderObject* m_renderer; -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r174729 r174761 69 69 #include "TextBreakIterator.h" 70 70 #include "TransformState.h" 71 71 72 #include <wtf/NeverDestroyed.h> 73 #include <wtf/Optional.h> 72 74 #include <wtf/StackStats.h> 73 75 #include <wtf/TemporaryChange.h> … … 95 97 static TrackedContainerMap* gPositionedContainerMap = 0; 96 98 static TrackedContainerMap* gPercentHeightContainerMap = 0; 97 99 98 100 typedef HashMap<RenderBlock*, std::unique_ptr<ListHashSet<RenderInline*>>> ContinuationOutlineTableMap; 99 101 … … 122 124 WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED; 123 125 public: 124 RenderBlockRareData() 126 RenderBlockRareData() 125 127 : m_paginationStrut(0) 126 128 , m_pageLogicalOffset(0) 127 { 129 , m_flowThreadContainingBlock(Nullopt) 130 { 128 131 } 129 132 130 133 LayoutUnit m_paginationStrut; 131 134 LayoutUnit m_pageLogicalOffset; 135 136 Optional<RenderFlowThread*> m_flowThreadContainingBlock; 132 137 }; 133 138 … … 267 272 268 273 setReplaced(newStyle.isDisplayInlineType()); 269 274 270 275 if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle.position()) { 271 276 if (newStyle.position() == StaticPosition) … … 284 289 containingBlock = containingBlock->parent(); 285 290 } 286 291 287 292 if (is<RenderBlock>(*containingBlock)) 288 293 downcast<RenderBlock>(*containingBlock).removePositionedObjects(this, NewContainingBlock); … … 309 314 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 310 315 { 316 RenderStyle& newStyle = style(); 317 318 bool hadTransform = hasTransform(); 319 bool flowThreadContainingBlockInvalidated = false; 320 if (oldStyle && oldStyle->position() != newStyle.position()) { 321 invalidateFlowThreadContainingBlockIncludingDescendants(); 322 flowThreadContainingBlockInvalidated = true; 323 } 324 311 325 RenderBox::styleDidChange(diff, oldStyle); 312 313 RenderStyle& newStyle = style(); 326 327 if (hadTransform != hasTransform() && !flowThreadContainingBlockInvalidated) 328 invalidateFlowThreadContainingBlockIncludingDescendants(); 314 329 315 330 if (!isAnonymousBlock()) { … … 325 340 propagateStyleToAnonymousChildren(PropagateToBlockChildrenOnly); 326 341 m_lineHeight = -1; 327 342 328 343 // It's possible for our border/padding to change, but for the overall logical width of the block to 329 344 // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true. … … 691 706 692 707 RenderFlowThread* childFlowThread = child->flowThreadContainingBlock(); 693 CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);694 708 if (childFlowThread && childFlowThread->isRenderNamedFlowThread()) 695 709 toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child); … … 3255 3269 } 3256 3270 3271 RenderFlowThread* RenderBlock::cachedFlowThreadContainingBlock() const 3272 { 3273 RenderBlockRareData* rareData = getRareData(this); 3274 3275 if (!rareData || !rareData->m_flowThreadContainingBlock) 3276 return nullptr; 3277 3278 return rareData->m_flowThreadContainingBlock.value(); 3279 } 3280 3281 bool RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate() const 3282 { 3283 RenderBlockRareData* rareData = getRareData(this); 3284 3285 if (!rareData || !rareData->m_flowThreadContainingBlock) 3286 return true; 3287 3288 return false; 3289 } 3290 3291 void RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate() 3292 { 3293 RenderBlockRareData& rareData = ensureRareData(this); 3294 rareData.m_flowThreadContainingBlock = Nullopt; 3295 } 3296 3297 RenderFlowThread* RenderBlock::updateCachedFlowThreadContainingBlock(RenderFlowThread* flowThread) const 3298 { 3299 RenderBlockRareData& rareData = ensureRareData(this); 3300 rareData.m_flowThreadContainingBlock = flowThread; 3301 3302 return flowThread; 3303 } 3304 3305 RenderFlowThread* RenderBlock::locateFlowThreadContainingBlock() const 3306 { 3307 RenderBlockRareData* rareData = getRareData(this); 3308 if (!rareData || !rareData->m_flowThreadContainingBlock) 3309 return updateCachedFlowThreadContainingBlock(RenderBox::locateFlowThreadContainingBlock()); 3310 3311 ASSERT(rareData->m_flowThreadContainingBlock.value() == RenderBox::locateFlowThreadContainingBlock()); 3312 return rareData->m_flowThreadContainingBlock.value(); 3313 } 3314 3257 3315 LayoutUnit RenderBlock::paginationStrut() const 3258 3316 { -
trunk/Source/WebCore/rendering/RenderBlock.h
r174504 r174761 313 313 virtual bool canCollapseAnonymousBlockChild() const { return true; } 314 314 315 RenderFlowThread* cachedFlowThreadContainingBlock() const; 316 void setCachedFlowThreadContainingBlockNeedsUpdate(); 317 virtual bool cachedFlowThreadContainingBlockNeedsUpdate() const; 318 315 319 protected: 320 virtual RenderFlowThread* locateFlowThreadContainingBlock() const override; 316 321 virtual void willBeDestroyed() override; 317 322 … … 450 455 virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const override final; 451 456 virtual const RenderStyle& outlineStyleForRepaint() const override final; 452 457 453 458 virtual RenderElement* hoverAncestor() const override final; 454 459 virtual void updateDragState(bool dragOn) override final; … … 489 494 RenderPtr<RenderBlock> clone() const; 490 495 RenderBlock* continuationBefore(RenderObject* beforeChild); 496 497 RenderFlowThread* updateCachedFlowThreadContainingBlock(RenderFlowThread*) const; 491 498 492 499 private: -
trunk/Source/WebCore/rendering/RenderBlockFlow.cpp
r174746 r174761 1986 1986 EPosition oldPosition = oldStyle->position(); 1987 1987 EPosition newPosition = newStyle.position(); 1988 1988 1989 1989 if (parent() && diff == StyleDifferenceLayout && oldPosition != newPosition) { 1990 1990 if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle.hasOutOfFlowPosition()) 1991 1991 markAllDescendantsWithFloatsForLayout(); 1992 1993 // If this block is inside a multicol and is moving from in-flow positioning to out-of-flow positioning,1994 // remove its info (such as lines-to-region mapping) from the flowthread because it won't be able to do it later.1995 // The flowthread will no longer be in its containing block chain and, as such, flowThreadContainingBlock will return null.1996 if (RenderFlowThread* flowThread = flowThreadContainingBlock(SkipFlowThreadCache)) {1997 if (flowThread->isRenderMultiColumnFlowThread() && !isOutOfFlowPositioned() && (newPosition == AbsolutePosition || newPosition == FixedPosition))1998 flowThread->removeFlowChildInfo(this);1999 }2000 1992 } 2001 1993 } -
trunk/Source/WebCore/rendering/RenderBox.cpp
r174722 r174761 197 197 return borderBoxRect(); 198 198 } 199 199 200 200 ASSERT(flowThread->regionInRange(region, startRegion, endRegion)); 201 201 … … 208 208 LayoutUnit logicalWidth = boxInfo->logicalWidth(); 209 209 LayoutUnit logicalLeft = boxInfo->logicalLeft(); 210 210 211 211 // Now apply the parent inset since it is cumulative whenever anything in the containing block chain shifts. 212 212 // FIXME: Doesn't work right with perpendicular writing modes. 213 213 const RenderBlock* currentBox = containingBlock(); 214 RenderBoxRegionInfo* currentBoxInfo = currentBox->renderBoxRegionInfo(region);214 RenderBoxRegionInfo* currentBoxInfo = isRenderFlowThread() ? nullptr : currentBox->renderBoxRegionInfo(region); 215 215 while (currentBoxInfo && currentBoxInfo->isShifted()) { 216 216 if (currentBox->style().direction() == LTR) … … 218 218 else 219 219 logicalLeft -= (currentBox->logicalWidth() - currentBoxInfo->logicalWidth()) - currentBoxInfo->logicalLeft(); 220 221 // Once we reach the fragmentation container we should stop. 222 if (currentBox->isRenderFlowThread()) 223 break; 224 220 225 currentBox = currentBox->containingBlock(); 221 226 region = currentBox->clampToStartAndEndRegions(region); 222 227 currentBoxInfo = currentBox->renderBoxRegionInfo(region); 223 228 } 224 229 225 230 if (cacheFlag == DoNotCacheRenderBoxRegionInfo) 226 231 delete boxInfo; -
trunk/Source/WebCore/rendering/RenderFlowThread.cpp
r174714 r174761 198 198 validateRegions(); 199 199 200 CurrentRenderFlowThreadMaintainer currentFlowThreadSetter(this);201 200 RenderBlockFlow::layout(); 202 201 … … 289 288 return false; 290 289 291 // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.292 // Let each region figure out the proper enclosing flow thread.293 CurrentRenderFlowThreadDisabler disabler(&view());294 295 290 // If the RenderFlowThread had a z-index layer update, then we need to update the composited layers too. 296 291 bool needsLayerUpdate = layer()->isDirtyRenderFlowThread() || m_layersToRegionMappingsDirty || !m_layerToRegionMap.get(); … … 389 384 LayoutStateDisabler layoutStateDisabler(&view()); // We can't use layout state to repaint, since the regions are somewhere else. 390 385 391 // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.392 // Let each region figure out the proper enclosing flow thread.393 CurrentRenderFlowThreadDisabler disabler(&view());394 395 386 for (auto& region : m_regionList) 396 387 region->repaintFlowThreadContent(repaintRect); … … 1523 1514 } 1524 1515 1525 CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowThread* renderFlowThread)1526 : m_renderFlowThread(renderFlowThread)1527 , m_previousRenderFlowThread(0)1528 {1529 if (!m_renderFlowThread)1530 return;1531 FlowThreadController& controller = m_renderFlowThread->view().flowThreadController();1532 m_previousRenderFlowThread = controller.currentRenderFlowThread();1533 // Remove the assert so we can use this to change the flow thread context.1534 // ASSERT(!m_previousRenderFlowThread || !renderFlowThread->isRenderNamedFlowThread());1535 controller.setCurrentRenderFlowThread(m_renderFlowThread);1536 }1537 1538 CurrentRenderFlowThreadMaintainer::~CurrentRenderFlowThreadMaintainer()1539 {1540 if (!m_renderFlowThread)1541 return;1542 FlowThreadController& controller = m_renderFlowThread->view().flowThreadController();1543 ASSERT(controller.currentRenderFlowThread() == m_renderFlowThread);1544 controller.setCurrentRenderFlowThread(m_previousRenderFlowThread);1545 }1546 1547 CurrentRenderFlowThreadDisabler::CurrentRenderFlowThreadDisabler(RenderView* view)1548 : m_view(view)1549 , m_renderFlowThread(0)1550 {1551 m_renderFlowThread = m_view->flowThreadController().currentRenderFlowThread();1552 if (m_renderFlowThread)1553 view->flowThreadController().setCurrentRenderFlowThread(0);1554 }1555 1556 CurrentRenderFlowThreadDisabler::~CurrentRenderFlowThreadDisabler()1557 {1558 if (m_renderFlowThread)1559 m_view->flowThreadController().setCurrentRenderFlowThread(m_renderFlowThread);1560 }1561 1562 1516 1563 1517 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderFlowThread.h
r174562 r174761 232 232 ContainingRegionMap& containingRegionMap(); 233 233 234 virtual bool cachedFlowThreadContainingBlockNeedsUpdate() const override { return false; } 235 234 236 // FIXME: Eventually as column and region flow threads start nesting, this may end up changing. 235 237 virtual bool shouldCheckColumnBreaks() const { return false; } … … 244 246 protected: 245 247 RenderFlowThread(Document&, PassRef<RenderStyle>); 248 249 virtual RenderFlowThread* locateFlowThreadContainingBlock() const override { return const_cast<RenderFlowThread*>(this); } 246 250 247 251 virtual const char* renderName() const = 0; … … 375 379 RENDER_OBJECT_TYPE_CASTS(RenderFlowThread, isRenderFlowThread()) 376 380 377 class CurrentRenderFlowThreadMaintainer {378 WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadMaintainer);379 public:380 CurrentRenderFlowThreadMaintainer(RenderFlowThread*);381 ~CurrentRenderFlowThreadMaintainer();382 private:383 RenderFlowThread* m_renderFlowThread;384 RenderFlowThread* m_previousRenderFlowThread;385 };386 387 class CurrentRenderFlowThreadDisabler {388 WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadDisabler);389 public:390 CurrentRenderFlowThreadDisabler(RenderView*);391 ~CurrentRenderFlowThreadDisabler();392 private:393 RenderView* m_view;394 RenderFlowThread* m_renderFlowThread;395 };396 397 381 // This structure is used by PODIntervalTree for debugging. 398 382 #ifndef NDEBUG -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r174729 r174761 3772 3772 // Don't paint the layer if the renderer doesn't belong to this region. 3773 3773 // This is true as long as we clamp the range of a box to its containing block range. 3774 3775 // Disable named flow region information for in flow threads such as multi-col.3776 std::unique_ptr<CurrentRenderFlowThreadDisabler> flowThreadDisabler;3777 if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers))3778 flowThreadDisabler = std::make_unique<CurrentRenderFlowThreadDisabler>(&renderer().view());3779 3780 3774 RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment(); 3781 3775 if (namedFlowFragment) { … … 4822 4816 return 0; 4823 4817 4824 // Disable named flow region information for in flow threads such as multi-col.4825 std::unique_ptr<CurrentRenderFlowThreadDisabler> flowThreadDisabler;4826 if (enclosingPaginationLayer(ExcludeCompositedPaginatedLayers))4827 flowThreadDisabler = std::make_unique<CurrentRenderFlowThreadDisabler>(&renderer().view());4828 4829 4818 RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment(); 4830 4819 … … 5233 5222 5234 5223 ASSERT(namedFlowFragment->parent() && namedFlowFragment->parent()->isRenderNamedFlowFragmentContainer()); 5235 5236 CurrentRenderFlowThreadDisabler flowThreadDisabler(&renderer().view()); 5224 5237 5225 ClipRectsContext targetClipRectsContext(&namedFlowFragment->fragmentContainerLayer(), TemporaryClipRects); 5238 5226 namedFlowFragment->fragmentContainerLayer().calculateClipRects(targetClipRectsContext, clipRects); … … 6711 6699 { 6712 6700 LayoutRect regionContentBox = toRenderBox(region->layerOwner()).contentBoxRect(); 6713 CurrentRenderFlowThreadMaintainer flowThreadMaintainer(toRenderFlowThread(&renderer()));6714 6701 CurrentRenderRegionMaintainer regionMaintainer(*region); 6715 6702 region->setRegionObjectsRegionStyle(); … … 6818 6805 hitTestRectInFlowThread.expand(LayoutSize(fabs((double)hitTestOffset.width()), fabs((double)hitTestOffset.height()))); 6819 6806 6820 CurrentRenderFlowThreadMaintainer flowThreadMaintainer(flowThread);6821 6807 CurrentRenderRegionMaintainer regionMaintainer(region); 6822 6808 -
trunk/Source/WebCore/rendering/RenderObject.cpp
r174722 r174761 523 523 } 524 524 525 RenderFlowThread* RenderObject::locateFlowThreadContainingBlockNoCache() const526 {527 ASSERT(flowThreadState() != NotInsideFlowThread);528 529 RenderObject* curr = const_cast<RenderObject*>(this);530 while (curr) {531 if (curr->isRenderFlowThread())532 return toRenderFlowThread(curr);533 curr = curr->containingBlock();534 }535 return 0;536 }537 538 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const539 {540 ASSERT(flowThreadState() != NotInsideFlowThread);541 542 // See if we have the thread cached because we're in the middle of layout.543 RenderFlowThread* flowThread = view().flowThreadController().currentRenderFlowThread();544 if (flowThread && (flowThreadState() == flowThread->flowThreadState())) {545 // Make sure the slow path would return the same result as our cache.546 // FIXME: For the moment, only apply this assertion to regions, as multicol547 // still has some issues and triggers this assert.548 // Created https://bugs.webkit.org/show_bug.cgi?id=132946 for this issue.549 ASSERT(!flowThread->isRenderNamedFlowThread() || flowThread == locateFlowThreadContainingBlockNoCache());550 return flowThread;551 }552 553 // Not in the middle of layout so have to find the thread the slow way.554 return locateFlowThreadContainingBlockNoCache();555 }556 557 525 RenderBlock* RenderObject::firstLineBlock() const 558 526 { … … 1439 1407 void RenderObject::showRegionsInformation() const 1440 1408 { 1441 CurrentRenderFlowThreadDisabler flowThreadDisabler(&view());1442 1443 1409 if (RenderFlowThread* flowThread = flowThreadContainingBlock()) { 1444 1410 const RenderBox* box = isBox() ? toRenderBox(this) : nullptr; … … 2049 2015 if (!isFloating() && parent()->childrenInline()) 2050 2016 parent()->dirtyLinesFromChangedChild(*this); 2051 2052 // We have to unset the current layout RenderFlowThread here, since insertedIntoTree() can happen in 2053 // the middle of layout but for objects inside a nested flow thread that is still being populated. This 2054 // will cause an accurate crawl to happen in order to ensure that the right flow thread is notified. 2055 RenderFlowThread* previousThread = view().flowThreadController().currentRenderFlowThread(); 2056 view().flowThreadController().setCurrentRenderFlowThread(nullptr); 2057 if (parent()->isRenderFlowThread()) 2058 toRenderFlowThread(parent())->flowThreadDescendantInserted(this); 2059 else if (RenderFlowThread* flowThread = parent()->flowThreadContainingBlock()) 2017 2018 if (RenderFlowThread* flowThread = flowThreadContainingBlock()) 2060 2019 flowThread->flowThreadDescendantInserted(this); 2061 view().flowThreadController().setCurrentRenderFlowThread(previousThread);2062 2020 } 2063 2021 … … 2076 2034 if (flowThreadState() == NotInsideFlowThread) 2077 2035 return; 2078 2036 2079 2037 // Sometimes we remove the element from the flow, but it's not destroyed at that time. 2080 // It's only until later when we actually destroy it and remove all the children from it. 2038 // It's only until later when we actually destroy it and remove all the children from it. 2081 2039 // Currently, that happens for firstLetter elements and list markers. 2082 2040 // Pass in the flow thread so that we don't have to look it up for all the children. 2083 removeFromRenderFlowThreadRecursive(flowThreadContainingBlock()); 2084 } 2085 2086 void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderFlowThread) 2087 { 2041 removeFromRenderFlowThreadIncludingDescendants(true); 2042 } 2043 2044 void RenderObject::removeFromRenderFlowThreadIncludingDescendants(bool shouldUpdateState) 2045 { 2046 // Once we reach another flow thread we don't need to update the flow thread state 2047 // but we have to continue cleanup the flow thread info. 2048 if (isRenderFlowThread()) 2049 shouldUpdateState = false; 2050 2088 2051 for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) 2089 child->removeFromRenderFlowThreadRecursive(renderFlowThread); 2090 2091 RenderFlowThread* localFlowThread = renderFlowThread; 2092 if (flowThreadState() == InsideInFlowThread) 2093 localFlowThread = flowThreadContainingBlock(); // We have to ask. We can't just assume we are in the same flow thread. 2094 if (localFlowThread) 2095 localFlowThread->removeFlowChildInfo(this); 2096 setFlowThreadState(NotInsideFlowThread); 2052 child->removeFromRenderFlowThreadIncludingDescendants(shouldUpdateState); 2053 2054 // We have to ask for our containing flow thread as it may be above the removed sub-tree. 2055 RenderFlowThread* flowThreadContainingBlock = this->flowThreadContainingBlock(); 2056 if (flowThreadContainingBlock) 2057 flowThreadContainingBlock->removeFlowChildInfo(this); 2058 if (is<RenderBlock>(*this)) 2059 downcast<RenderBlock>(*this).setCachedFlowThreadContainingBlockNeedsUpdate(); 2060 if (shouldUpdateState) 2061 setFlowThreadState(NotInsideFlowThread); 2062 } 2063 2064 void RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants(RenderFlowThread* flowThread) 2065 { 2066 if (flowThreadState() == NotInsideFlowThread) 2067 return; 2068 2069 if (is<RenderBlock>(*this)) { 2070 RenderBlock& block = downcast<RenderBlock>(*this); 2071 2072 if (block.cachedFlowThreadContainingBlockNeedsUpdate()) 2073 return; 2074 2075 flowThread = block.cachedFlowThreadContainingBlock(); 2076 block.setCachedFlowThreadContainingBlockNeedsUpdate(); 2077 } 2078 2079 if (flowThread) 2080 flowThread->removeFlowChildInfo(this); 2081 2082 for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) 2083 child->invalidateFlowThreadContainingBlockIncludingDescendants(flowThread); 2097 2084 } 2098 2085 … … 2598 2585 RenderNamedFlowFragment* RenderObject::currentRenderNamedFlowFragment() const 2599 2586 { 2600 if (flowThreadState() == NotInsideFlowThread) 2587 RenderFlowThread* flowThread = flowThreadContainingBlock(); 2588 if (!flowThread || !flowThread->isRenderNamedFlowThread()) 2601 2589 return nullptr; 2602 2603 RenderFlowThread* flowThread = view().flowThreadController().currentRenderFlowThread();2604 if (!flowThread)2605 return nullptr;2606 2607 ASSERT(flowThread == flowThreadContainingBlock());2608 2590 2609 2591 // FIXME: Once regions are fully integrated with the compositing system we should uncomment this assert. … … 2612 2594 // ASSERT(flowThread->currentRegion() && flowThread->currentRegion()->isRenderNamedFlowFragment()); 2613 2595 2614 RenderNamedFlowFragment* namedFlowFragment = toRenderNamedFlowFragment(flowThread->currentRegion()); 2615 return namedFlowFragment; 2596 return toRenderNamedFlowFragment(flowThread->currentRegion()); 2597 } 2598 2599 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const 2600 { 2601 RenderBlock* containingBlock = this->containingBlock(); 2602 return containingBlock ? containingBlock->flowThreadContainingBlock() : nullptr; 2616 2603 } 2617 2604 -
trunk/Source/WebCore/rendering/RenderObject.h
r174722 r174761 213 213 bool fixedPositionedWithNamedFlowContainingBlock() const; 214 214 215 enum ShouldUseFlowThreadCache {216 UseFlowThreadCache,217 SkipFlowThreadCache218 };219 220 215 // Function to return our enclosing flow thread if we are contained inside one. This 221 216 // function follows the containing block chain. 222 RenderFlowThread* flowThreadContainingBlock( ShouldUseFlowThreadCache useCache = UseFlowThreadCache) const217 RenderFlowThread* flowThreadContainingBlock() const 223 218 { 224 219 if (flowThreadState() == NotInsideFlowThread) 225 return 0; 226 return (useCache == SkipFlowThreadCache) ? locateFlowThreadContainingBlockNoCache() : locateFlowThreadContainingBlock(); 220 return nullptr; 221 222 return locateFlowThreadContainingBlock(); 227 223 } 228 224 … … 893 889 void setNeedsSimplifiedNormalFlowLayoutBit(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); } 894 890 891 virtual RenderFlowThread* locateFlowThreadContainingBlock() const; 892 void invalidateFlowThreadContainingBlockIncludingDescendants(RenderFlowThread* = nullptr); 893 895 894 private: 896 RenderFlowThread* locateFlowThreadContainingBlock() const;897 RenderFlowThread* locateFlowThreadContainingBlockNoCache() const;898 899 895 void removeFromRenderFlowThread(); 900 void removeFromRenderFlowThread Recursive(RenderFlowThread*);896 void removeFromRenderFlowThreadIncludingDescendants(bool); 901 897 902 898 Color selectionColor(int colorProperty) const; -
trunk/Source/WebCore/rendering/RenderRegion.cpp
r174714 r174761 219 219 { 220 220 ASSERT(isValid()); 221 222 LayoutRect layoutRect; 223 { 224 // When getting the overflow from the flow thread we need to temporarly reset the current flow thread because 225 // we're changing flows. 226 CurrentRenderFlowThreadMaintainer flowThreadMaintainer(m_flowThread); 227 layoutRect = layoutOverflowRectForBox(m_flowThread); 228 } 229 221 222 LayoutRect layoutRect = layoutOverflowRectForBox(m_flowThread); 230 223 layoutRect.setLocation(contentBoxRect().location() + (layoutRect.location() - m_flowThreadPortionRect.location())); 231 224 -
trunk/Source/WebCore/rendering/RenderView.cpp
r174725 r174761 1312 1312 return; 1313 1313 1314 RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();1314 RenderFlowThread* currentFlowThread = object.flowThreadContainingBlock(); 1315 1315 if (!currentFlowThread) 1316 1316 return; 1317 1317 1318 m_layoutState->setCurrentRenderFlowThread(currentFlowThread); 1319 1318 1320 currentFlowThread->pushFlowThreadLayoutState(object); 1319 1321 } … … 1324 1326 return; 1325 1327 1326 RenderFlowThread* currentFlowThread = m_ flowThreadController->currentRenderFlowThread();1328 RenderFlowThread* currentFlowThread = m_layoutState->currentRenderFlowThread(); 1327 1329 if (!currentFlowThread) 1328 1330 return; -
trunk/Source/WebCore/rendering/RenderView.h
r174725 r174761 296 296 void pushLayoutStateForCurrentFlowThread(const RenderObject&); 297 297 void popLayoutStateForCurrentFlowThread(); 298 298 299 299 friend class LayoutStateMaintainer; 300 300 friend class LayoutStateDisabler;
Note: See TracChangeset
for help on using the changeset viewer.