Changeset 135746 in webkit
- Timestamp:
- Nov 26, 2012 11:37:45 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r135742 r135746 1 2012-11-26 Simon Fraser <simon.fraser@apple.com> 2 3 Optimize layer updates after scrolling 4 https://bugs.webkit.org/show_bug.cgi?id=102635 5 6 Reviewed by Sam Weinig. 7 8 updateLayerPositionsAfterScroll() previously unconditionally cleared clip 9 rects, and recomputed repaint rects too often. Recomputing both of these 10 can be very expensive, as they involve tree walks up to the root. 11 12 We can optimize layer updates after document scrolling by only clearing clip 13 rects, and recomputing repaint rects, if we encounter a fixed- or sticky-position 14 element. For overflow scroll, we have to clear clip rects and recompute repaint rects. 15 16 * page/FrameView.cpp: 17 (WebCore::FrameView::repaintFixedElementsAfterScrolling): Call updateLayerPositionsAfterDocumentScroll(). 18 * rendering/RenderLayer.cpp: 19 (WebCore::RenderLayer::updateLayerPositions): Call clearClipRects() because 20 updateLayerPosition() no longer does. 21 (WebCore::RenderLayer::updateLayerPositionsAfterDocumentScroll): Version of updateLayerPositionsAfterScroll() 22 that is for document scrolls. It has no need to push layers to the geometry map. 23 (WebCore::RenderLayer::updateLayerPositionsAfterOverflowScroll): Pushes layers to the geometry map, 24 and calls updateLayerPositionsAfterScroll() with the IsOverflowScroll flag. 25 (WebCore::RenderLayer::updateLayerPositionsAfterScroll): Set the HasChangedAncestor flag 26 if our location changed, and use that as a hint to clear cached rects. Be more conservative 27 than before about when to clear cached clip rects. 28 (WebCore::RenderLayer::updateLayerPosition): Move responsibility for calling 29 clearClipRects() ouf of this function and into callers. 30 (The one caller outside RenderLayer will be removed via bug 102624). 31 Return a bool indicating whether our position changed. 32 (WebCore::RenderLayer::scrollTo): Call updateLayerPositionsAfterOverflowScroll(). 33 (WebCore::RenderLayer::updateClipRects): Added some #ifdeffed out code that is useful 34 to verify that cached clips are correct; it's too slow to leave enabled in debug builds. 35 * rendering/RenderLayer.h: 36 (WebCore::RenderLayer::setLocation): Change to take a LayoutPoint, rather than separate 37 x and y. 38 1 39 2012-11-26 Rafael Brandao <rafael.lobo@openbossa.org> 2 40 -
trunk/Source/WebCore/page/FrameView.cpp
r135025 r135746 1823 1823 if (RenderView* root = rootRenderer(this)) { 1824 1824 root->updateWidgetPositions(); 1825 root->layer()->updateLayerPositionsAfter Scroll();1825 root->layer()->updateLayerPositionsAfterDocumentScroll(); 1826 1826 } 1827 1827 } -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r135605 r135746 344 344 if (geometryMap) 345 345 geometryMap->pushMappingsToAncestor(this, parent()); 346 347 // Clear our cached clip rect information. 348 clearClipRects(); 346 349 347 350 if (hasOverflowControls()) { … … 495 498 } 496 499 497 void RenderLayer::updateLayerPositionsAfterScroll() 500 void RenderLayer::updateLayerPositionsAfterDocumentScroll() 501 { 502 ASSERT(this == renderer()->view()->layer()); 503 504 RenderGeometryMap geometryMap(UseTransforms); 505 updateLayerPositionsAfterScroll(&geometryMap); 506 } 507 508 void RenderLayer::updateLayerPositionsAfterOverflowScroll() 498 509 { 499 510 RenderGeometryMap geometryMap(UseTransforms); … … 501 512 if (this != view->layer()) 502 513 geometryMap.pushMappingsToAncestor(parent(), 0); 503 updateLayerPositionsAfterScroll(&geometryMap); 514 515 // FIXME: why is it OK to not check the ancestors of this layer in order to 516 // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags? 517 updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll); 504 518 } 505 519 … … 516 530 return; 517 531 518 updateLayerPosition(); 532 bool positionChanged = updateLayerPosition(); 533 if (positionChanged) 534 flags |= HasChangedAncestor; 519 535 520 536 if (geometryMap) 521 537 geometryMap->pushMappingsToAncestor(this, parent()); 522 538 523 if ((flags & HasSeenViewportConstrainedAncestor) || renderer()->style()->hasViewportConstrainedPosition()) { 524 // FIXME: Is it worth passing the offsetFromRoot around like in updateLayerPositions? 539 if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll) 540 clearClipRects(); 541 542 if (renderer()->style()->hasViewportConstrainedPosition()) 543 flags |= HasSeenViewportConstrainedAncestor; 544 545 if (renderer()->hasOverflowClip()) 546 flags |= HasSeenAncestorWithOverflowClip; 547 548 if (flags & HasSeenViewportConstrainedAncestor 549 || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) { 525 550 // FIXME: We could track the repaint container as we walk down the tree. 526 551 computeRepaintRects(renderer()->containerForRepaint(), geometryMap); 527 flags |= HasSeenViewportConstrainedAncestor; 528 } else if ((flags & HasSeenAncestorWithOverflowClip) && !m_canSkipRepaintRectsUpdateOnScroll) { 529 // If we have seen an overflow clip, we should update our repaint rects as clippedOverflowRectForRepaint 530 // intersects it with our ancestor overflow clip that may have moved. 531 computeRepaintRects(renderer()->containerForRepaint(), geometryMap); 532 } 533 534 if (renderer()->hasOverflowClip()) 535 flags |= HasSeenAncestorWithOverflowClip; 536 552 } else { 553 // Check that our cached rects are correct. 554 ASSERT(m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint())); 555 ASSERT(m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap)); 556 } 557 537 558 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 538 559 child->updateLayerPositionsAfterScroll(geometryMap, flags); … … 835 856 } 836 857 837 voidRenderLayer::updateLayerPosition()858 bool RenderLayer::updateLayerPosition() 838 859 { 839 860 LayoutPoint localPoint; … … 851 872 } 852 873 853 // Clear our cached clip rect information.854 clearClipRects();855 856 874 if (!renderer()->isOutOfFlowPositioned() && renderer()->parent()) { 857 875 // We must adjust our position by walking up the render tree looking for the … … 901 919 } 902 920 921 bool positionOrOffsetChanged = false; 903 922 if (renderer()->isInFlowPositioned()) { 904 m_offsetForInFlowPosition = toRenderBoxModelObject(renderer())->offsetForInFlowPosition(); 923 LayoutSize newOffset = toRenderBoxModelObject(renderer())->offsetForInFlowPosition(); 924 positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition; 925 m_offsetForInFlowPosition = newOffset; 905 926 localPoint.move(m_offsetForInFlowPosition); 906 927 } else { … … 910 931 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers. 911 932 localPoint -= inlineBoundingBoxOffset; 912 setLocation(localPoint.x(), localPoint.y()); 933 934 positionOrOffsetChanged |= location() != localPoint; 935 setLocation(localPoint); 936 return positionOrOffsetChanged; 913 937 } 914 938 … … 1737 1761 if (!inLayout) { 1738 1762 // If we're in the middle of layout, we'll just update layers once layout has finished. 1739 updateLayerPositionsAfter Scroll();1763 updateLayerPositionsAfterOverflowScroll(); 1740 1764 if (view) { 1741 1765 // Update regions, scrolling may change the clip of a particular region. … … 4129 4153 ASSERT(m_clipRectsCache->m_respectingOverflowClip[clipRectsType] == (clipRectsContext.respectOverflowClip == RespectOverflowClip)); 4130 4154 ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy); 4155 4156 #ifdef CHECK_CACHED_CLIP_RECTS 4157 // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. 4158 ClipRectsContext tempContext(clipRectsContext); 4159 tempContext.clipRectsType = TemporaryClipRects; 4160 ClipRects clipRects; 4161 calculateClipRects(tempContext, clipRects); 4162 ASSERT(clipRects == *m_clipRectsCache->m_clipRects[clipRectsType].get()); 4163 #endif 4131 4164 return; // We have the correct cached value. 4132 4165 } -
trunk/Source/WebCore/rendering/RenderLayer.h
r135605 r135746 310 310 311 311 const LayoutPoint& location() const { return m_topLeft; } 312 void setLocation( LayoutUnit x, LayoutUnit y) { m_topLeft = LayoutPoint(x, y); }312 void setLocation(const LayoutPoint& p) { m_topLeft = p; } 313 313 314 314 const IntSize& size() const { return m_layerSize; } … … 391 391 bool canRender3DTransforms() const; 392 392 393 void updateLayerPosition(); 393 // Returns true if the position changed. 394 bool updateLayerPosition(); 394 395 395 396 enum UpdateLayerPositionsFlag { … … 403 404 404 405 void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags); 405 void updateLayerPositionsAfterScroll(); 406 407 void updateLayerPositionsAfterOverflowScroll(); 408 void updateLayerPositionsAfterDocumentScroll(); 406 409 407 410 bool isPaginated() const { return m_isPaginated; } … … 741 744 enum UpdateLayerPositionsAfterScrollFlag { 742 745 NoFlag = 0, 743 HasSeenViewportConstrainedAncestor = 1 << 0, 744 HasSeenAncestorWithOverflowClip = 1 << 1 746 IsOverflowScroll = 1 << 0, 747 HasSeenViewportConstrainedAncestor = 1 << 1, 748 HasSeenAncestorWithOverflowClip = 1 << 2, 749 HasChangedAncestor = 1 << 3 745 750 }; 746 751 typedef unsigned UpdateLayerPositionsAfterScrollFlags;
Note: See TracChangeset
for help on using the changeset viewer.