Changeset 157793 in webkit
- Timestamp:
- Oct 22, 2013 7:50:37 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r157792 r157793 1 2013-10-22 Andrei Bucur <abucur@adobe.com> 2 3 [CSS Regions] Possible performance regression after r157567 4 https://bugs.webkit.org/show_bug.cgi?id=123016 5 6 Reviewed by Andreas Kling. 7 8 The revision 157567 http://trac.webkit.org/changeset/157567 may have regressed 9 Parser/html5-full-render by ~1.1% and Parser/html-parser by ~2%. These changes 10 try to optimize the initial patch, based on Andreas Kling's review. 11 12 The patch also adds a couple of refactorings that should make the code easier to read: 13 - the CSS Shapes functions are now wrapped in a single #if clause 14 - the CSS Shapes and CSS Regions pre-layout preparations are wrapped in a helper function 15 16 The RenderFlowThread::logicalWidthChangedInRegionsForBlock function is optimized by passing 17 it information about the state of the relayout children flag. If the flag is true already, 18 some of the steps are skipped. 19 20 Tests: no new tests. 21 22 * dom/Element.cpp: 23 (WebCore::Element::webkitGetRegionFlowRanges): 24 * inspector/InspectorOverlay.cpp: 25 (WebCore::buildObjectForElementInfo): 26 * rendering/RenderBlock.cpp: 27 (WebCore::shapeInfoRequiresRelayout): 28 (WebCore::RenderBlock::updateShapesBeforeBlockLayout): 29 (WebCore::RenderBlock::computeShapeSize): 30 (WebCore::RenderBlock::prepareShapesAndPaginationBeforeBlockLayout): 31 * rendering/RenderBlock.h: 32 * rendering/RenderBlockFlow.cpp: 33 (WebCore::RenderBlockFlow::layoutBlock): 34 (WebCore::RenderBlockFlow::createRenderNamedFlowFragmentIfNeeded): 35 (WebCore::RenderBlockFlow::setRenderNamedFlowFragment): 36 (WebCore::RenderBlockFlow::ensureRareData): 37 * rendering/RenderBlockFlow.h: 38 (WebCore::RenderBlockFlow::RenderBlockFlowRareData::RenderBlockFlowRareData): 39 (WebCore::RenderElement::isRenderNamedFlowFragmentContainer): 40 * rendering/RenderDeprecatedFlexibleBox.cpp: 41 (WebCore::RenderDeprecatedFlexibleBox::layoutBlock): 42 * rendering/RenderElement.h: 43 (WebCore::RenderElement::generatingElement): 44 * rendering/RenderFlexibleBox.cpp: 45 (WebCore::RenderFlexibleBox::layoutBlock): 46 * rendering/RenderFlowThread.cpp: 47 (WebCore::RenderFlowThread::logicalWidthChangedInRegionsForBlock): 48 * rendering/RenderFlowThread.h: 49 * rendering/RenderGrid.cpp: 50 (WebCore::RenderGrid::layoutBlock): 51 * rendering/RenderNamedFlowFragment.h: 52 * rendering/RenderObject.cpp: 53 * rendering/RenderObject.h: 54 * rendering/RenderTreeAsText.cpp: 55 (WebCore::write): 56 * style/StyleResolveTree.cpp: 57 (WebCore::Style::elementInsideRegionNeedsRenderer): 58 1 59 2013-10-22 Andreas Kling <akling@apple.com> 2 60 -
trunk/Source/WebCore/dom/Element.cpp
r157653 r157793 2762 2762 Vector<RefPtr<Range>> Element::webkitGetRegionFlowRanges() const 2763 2763 { 2764 Vector<RefPtr<Range>> rangeObjects; 2765 if (!document().cssRegionsEnabled()) 2766 return rangeObjects; 2767 2764 2768 document().updateLayoutIgnorePendingStylesheets(); 2765 2766 Vector<RefPtr<Range>> rangeObjects; 2767 if (document().cssRegionsEnabled() && renderer() && renderer()->isRenderNamedFlowFragmentContainer()) { 2769 if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) { 2768 2770 RenderNamedFlowFragment* region = toRenderBlockFlow(renderer())->renderNamedFlowFragment(); 2769 2771 if (region->isValid()) -
trunk/Source/WebCore/inspector/InspectorOverlay.cpp
r157605 r157793 555 555 } 556 556 557 Render Object* renderer = node->renderer();557 RenderElement* renderer = element->renderer(); 558 558 Frame* containingFrame = node->document().frame(); 559 559 FrameView* containingView = containingFrame->view(); -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r157768 r157793 1406 1406 return info && info->needsLayout(); 1407 1407 } 1408 #endif 1409 1410 bool RenderBlock::updateShapesBeforeBlockLayout() 1411 { 1412 #if ENABLE(CSS_SHAPES) 1413 if (!flowThreadContainingBlock() && !shapeInsideInfo()) 1414 return shapeInfoRequiresRelayout(this); 1415 1416 LayoutUnit oldHeight = logicalHeight(); 1417 LayoutUnit oldTop = logicalTop(); 1418 1419 // Compute the maximum logical height content may cause this block to expand to 1420 // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight 1421 setLogicalHeight(RenderFlowThread::maxLogicalHeight()); 1422 updateLogicalHeight(); 1423 1424 computeShapeSize(); 1425 1426 setLogicalHeight(oldHeight); 1427 setLogicalTop(oldTop); 1428 1429 return shapeInfoRequiresRelayout(this); 1430 #else 1431 return false; 1432 #endif 1433 } 1434 1435 #if ENABLE(CSS_SHAPES) 1408 1436 1409 void RenderBlock::computeShapeSize() 1437 1410 { … … 1450 1423 } 1451 1424 #endif 1425 1426 bool RenderBlock::updateShapesBeforeBlockLayout() 1427 { 1428 #if ENABLE(CSS_SHAPES) 1429 if (!flowThreadContainingBlock() && !shapeInsideInfo()) 1430 return shapeInfoRequiresRelayout(this); 1431 1432 LayoutUnit oldHeight = logicalHeight(); 1433 LayoutUnit oldTop = logicalTop(); 1434 1435 // Compute the maximum logical height content may cause this block to expand to 1436 // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight 1437 setLogicalHeight(RenderFlowThread::maxLogicalHeight()); 1438 updateLogicalHeight(); 1439 1440 computeShapeSize(); 1441 1442 setLogicalHeight(oldHeight); 1443 setLogicalTop(oldTop); 1444 1445 return shapeInfoRequiresRelayout(this); 1446 #else 1447 return false; 1448 #endif 1449 } 1452 1450 1453 1451 void RenderBlock::updateShapesAfterBlockLayout(bool heightChanged) … … 1461 1459 UNUSED_PARAM(heightChanged); 1462 1460 #endif 1461 } 1462 1463 void RenderBlock::prepareShapesAndPaginationBeforeBlockLayout(bool& relayoutChildren) 1464 { 1465 // Regions changing widths can force us to relayout our children. 1466 RenderFlowThread* flowThread = flowThreadContainingBlock(); 1467 if (updateShapesBeforeBlockLayout()) 1468 relayoutChildren = true; 1469 if (flowThread) 1470 flowThread->logicalWidthChangedInRegionsForBlock(this, relayoutChildren); 1463 1471 } 1464 1472 … … 5276 5284 } 5277 5285 5278 bool RenderBlock::logicalWidthChangedInRegions(RenderFlowThread* flowThread) const5279 {5280 if (!flowThread || !flowThread->hasValidRegionInfo())5281 return false;5282 5283 return flowThread->logicalWidthChangedInRegionsForBlock(this);5284 }5285 5286 5286 void RenderBlock::computeRegionRangeForBoxChild(const RenderBox* box) const 5287 5287 { -
trunk/Source/WebCore/rendering/RenderBlock.h
r157705 r157793 507 507 508 508 virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight); 509 void prepareShapesAndPaginationBeforeBlockLayout(bool&); 509 510 510 511 private: … … 715 716 // line, i.e., that it can't be re-used. 716 717 bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const; 717 718 bool logicalWidthChangedInRegions(RenderFlowThread*) const;719 718 720 719 virtual bool requiresColumns(int desiredColumnCount) const; -
trunk/Source/WebCore/rendering/RenderBlockFlow.cpp
r157779 r157793 327 327 LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || styleToUse->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); 328 328 329 // Regions changing widths can force us to relayout our children. 330 RenderFlowThread* flowThread = flowThreadContainingBlock(); 331 if (logicalWidthChangedInRegions(flowThread)) 332 relayoutChildren = true; 333 if (updateShapesBeforeBlockLayout()) 334 relayoutChildren = true; 335 if (namedFlowFragmentNeedsUpdate()) 336 relayoutChildren = true; 329 prepareShapesAndPaginationBeforeBlockLayout(relayoutChildren); 330 if (!relayoutChildren) 331 relayoutChildren = namedFlowFragmentNeedsUpdate(); 337 332 338 333 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track … … 2587 2582 void RenderBlockFlow::createRenderNamedFlowFragmentIfNeeded() 2588 2583 { 2589 if ( renderNamedFlowFragment() || isRenderNamedFlowFragment())2590 return; 2591 2592 if ( document().cssRegionsEnabled() &&style()->isDisplayRegionType() && style()->hasFlowFrom()) {2584 if (!document().cssRegionsEnabled() || renderNamedFlowFragment() || isRenderNamedFlowFragment()) 2585 return; 2586 2587 if (style()->isDisplayRegionType() && style()->hasFlowFrom()) { 2593 2588 RenderNamedFlowFragment* flowFragment = new RenderNamedFlowFragment(document()); 2594 2589 flowFragment->setStyleForNamedFlowFragment(style()); … … 2626 2621 void RenderBlockFlow::setRenderNamedFlowFragment(RenderNamedFlowFragment* flowFragment) 2627 2622 { 2628 if (!m_rareData) 2629 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); 2630 if (m_rareData->m_renderNamedFlowFragment) 2631 m_rareData->m_renderNamedFlowFragment->destroy(); 2632 m_rareData->m_renderNamedFlowFragment = flowFragment; 2623 RenderBlockFlowRareData& rareData = ensureRareData(); 2624 if (rareData.m_renderNamedFlowFragment) 2625 rareData.m_renderNamedFlowFragment->destroy(); 2626 rareData.m_renderNamedFlowFragment = flowFragment; 2627 } 2628 2629 // FIXME: Use this function in more places. 2630 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() 2631 { 2632 if (m_rareData) 2633 return *m_rareData; 2634 2635 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); 2636 return *m_rareData; 2633 2637 } 2634 2638 -
trunk/Source/WebCore/rendering/RenderBlockFlow.h
r157705 r157793 97 97 : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block)) 98 98 , m_lineBreakToAvoidWidow(-1) 99 , m_lineGridBox( 0)100 , m_renderNamedFlowFragment( 0)99 , m_lineGridBox(nullptr) 100 , m_renderNamedFlowFragment(nullptr) 101 101 , m_discardMarginBefore(false) 102 102 , m_discardMarginAfter(false) … … 414 414 Position positionForBox(InlineBox*, bool start = true) const; 415 415 virtual VisiblePosition positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents) OVERRIDE; 416 416 RenderBlockFlowRareData& ensureRareData(); 417 417 virtual void addFocusRingRectsForInlineChildren(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) OVERRIDE; 418 418 … … 507 507 } 508 508 509 inline bool RenderElement::isRenderNamedFlowFragmentContainer() const 510 { 511 return isRenderBlockFlow() && toRenderBlockFlow(this)->renderNamedFlowFragment(); 512 } 513 509 514 // This will catch anyone doing an unnecessary cast. 510 515 void toRenderBlockFlow(const RenderBlockFlow*); -
trunk/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
r157674 r157793 288 288 LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); 289 289 290 // Regions changing widths can force us to relayout our children. 291 RenderFlowThread* flowThread = flowThreadContainingBlock(); 292 if (logicalWidthChangedInRegions(flowThread)) 293 relayoutChildren = true; 294 if (updateShapesBeforeBlockLayout()) 295 relayoutChildren = true; 290 prepareShapesAndPaginationBeforeBlockLayout(relayoutChildren); 296 291 297 292 LayoutSize previousSize = size(); -
trunk/Source/WebCore/rendering/RenderElement.h
r157665 r157793 56 56 bool isRenderReplaced() const; 57 57 bool isRenderInline() const; 58 bool isRenderNamedFlowFragmentContainer() const; 58 59 59 60 virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const { return true; } … … 261 262 inline Element* RenderElement::generatingElement() const 262 263 { 263 if ( isRenderNamedFlowFragment() && parent())264 if (parent() && isRenderNamedFlowFragment()) 264 265 return toRenderElement(parent())->generatingElement(); 265 266 return toElement(RenderObject::generatingNode()); -
trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp
r157408 r157793 340 340 LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); 341 341 342 // Regions changing widths can force us to relayout our children. 343 RenderFlowThread* flowThread = flowThreadContainingBlock(); 344 if (logicalWidthChangedInRegions(flowThread)) 345 relayoutChildren = true; 346 if (updateShapesBeforeBlockLayout()) 347 relayoutChildren = true; 342 prepareShapesAndPaginationBeforeBlockLayout(relayoutChildren); 348 343 349 344 m_numberOfInFlowChildrenOnFirstLine = -1; -
trunk/Source/WebCore/rendering/RenderFlowThread.cpp
r157725 r157793 728 728 } 729 729 730 bool RenderFlowThread::logicalWidthChangedInRegionsForBlock(const RenderBlock* block)731 { 732 if (!has Regions())733 return false;730 void RenderFlowThread::logicalWidthChangedInRegionsForBlock(const RenderBlock* block, bool& relayoutChildren) 731 { 732 if (!hasValidRegionInfo()) 733 return; 734 734 735 735 RenderRegionRangeMap::iterator it = m_regionRangeMap.find(block); 736 736 if (it == m_regionRangeMap.end()) 737 return false;737 return; 738 738 739 739 RenderRegionRange& range = it->value; … … 741 741 range.clearRangeInvalidated(); 742 742 743 // If there will be a relayout anyway skip the next steps because they only verify 744 // the state of the ranges. 745 if (relayoutChildren) 746 return; 747 743 748 RenderRegion* startRegion; 744 749 RenderRegion* endRegion; … … 747 752 // Not necessary for the flow thread, since we already computed the correct info for it. 748 753 // If the regions have changed invalidate the children. 749 if (block == this) 750 return m_pageLogicalSizeChanged; 754 if (block == this) { 755 relayoutChildren = m_pageLogicalSizeChanged; 756 return; 757 } 751 758 752 759 for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { … … 756 763 // We have no information computed for this region so we need to do it. 757 764 OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block); 758 if (!oldInfo) 759 return rangeInvalidated; 765 if (!oldInfo) { 766 relayoutChildren = rangeInvalidated; 767 return; 768 } 760 769 761 770 LayoutUnit oldLogicalWidth = oldInfo->logicalWidth(); 762 771 RenderBoxRegionInfo* newInfo = block->renderBoxRegionInfo(region); 763 if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth) 764 return true; 772 if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth) { 773 relayoutChildren = true; 774 return; 775 } 765 776 766 777 if (region == endRegion) 767 778 break; 768 779 } 769 770 return false;771 780 } 772 781 -
trunk/Source/WebCore/rendering/RenderFlowThread.h
r157725 r157793 127 127 128 128 void removeRenderBoxRegionInfo(RenderBox*); 129 bool logicalWidthChangedInRegionsForBlock(const RenderBlock*);129 void logicalWidthChangedInRegionsForBlock(const RenderBlock*, bool&); 130 130 131 131 LayoutUnit contentLogicalWidthOfFirstRegion() const; -
trunk/Source/WebCore/rendering/RenderGrid.cpp
r157653 r157793 165 165 LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); 166 166 167 // Regions changing widths can force us to relayout our children. 168 RenderFlowThread* flowThread = flowThreadContainingBlock(); 169 if (logicalWidthChangedInRegions(flowThread)) 170 relayoutChildren = true; 171 if (updateShapesBeforeBlockLayout()) 172 relayoutChildren = true; 167 prepareShapesAndPaginationBeforeBlockLayout(relayoutChildren); 173 168 174 169 LayoutSize previousSize = size(); -
trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h
r157725 r157793 38 38 class RenderStyle; 39 39 40 class RenderNamedFlowFragment : public RenderRegion {40 class RenderNamedFlowFragment FINAL : public RenderRegion { 41 41 public: 42 42 explicit RenderNamedFlowFragment(Document&); … … 46 46 47 47 virtual bool isRenderNamedFlowFragment() const OVERRIDE FINAL { return true; } 48 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) ;48 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE; 49 49 50 50 virtual LayoutUnit maxPageLogicalHeight() const; … … 59 59 toRenderLayerModelObject(parent()) : nullptr; } 60 60 61 protected:62 virtual bool shouldHaveAutoLogicalHeight() const;63 64 61 private: 65 virtual const char* renderName() const { return "RenderNamedFlowFragment"; } 62 virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE; 63 virtual const char* renderName() const OVERRIDE { return "RenderNamedFlowFragment"; } 66 64 }; 67 65 -
trunk/Source/WebCore/rendering/RenderObject.cpp
r157567 r157793 2559 2559 } 2560 2560 2561 bool RenderObject::isRenderNamedFlowFragmentContainer() const2562 {2563 if (!isRenderBlockFlow())2564 return false;2565 2566 return toRenderBlockFlow(this)->renderNamedFlowFragment();2567 }2568 2569 2561 #if ENABLE(SVG) 2570 2562 -
trunk/Source/WebCore/rendering/RenderObject.h
r157694 r157793 364 364 bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); } 365 365 bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); } 366 bool isRenderNamedFlowFragmentContainer() const;367 366 368 367 virtual bool isRenderMultiColumnBlock() const { return false; } -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r157725 r157793 576 576 } 577 577 } else { 578 if (! o.isRenderNamedFlowFragmentContainer()) {578 if (!toRenderElement(o).isRenderNamedFlowFragmentContainer()) { 579 579 for (RenderObject* child = toRenderElement(o).firstChild(); child; child = child->nextSibling()) { 580 580 if (child->hasLayer()) -
trunk/Source/WebCore/style/StyleResolveTree.cpp
r157785 r157793 165 165 { 166 166 #if ENABLE(CSS_REGIONS) 167 const RenderObject* parentRenderer = renderingParentNode ? renderingParentNode->renderer() : 0; 167 // The parent of a region should always be an element. 168 const RenderElement* parentRenderer = renderingParentNode ? renderingParentNode->renderer() : 0; 168 169 169 170 bool parentIsRegion = parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderNamedFlowFragmentContainer();
Note: See TracChangeset
for help on using the changeset viewer.