Changeset 135777 in webkit
- Timestamp:
- Nov 26, 2012, 3:12:49 PM (13 years ago)
- Location:
- branches/safari-536.28-branch/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-536.28-branch/Source/WebCore/ChangeLog
r135776 r135777 1 2012-11-26 Simon Fraser <simon.fraser@apple.com> 2 3 <rdar://problem/12751360> 4 Merge r135746 5 6 2012-11-26 Simon Fraser <simon.fraser@apple.com> 7 8 Optimize layer updates after scrolling 9 https://bugs.webkit.org/show_bug.cgi?id=102635 10 11 Reviewed by Sam Weinig. 12 13 updateLayerPositionsAfterScroll() previously unconditionally cleared clip 14 rects, and recomputed repaint rects too often. Recomputing both of these 15 can be very expensive, as they involve tree walks up to the root. 16 17 We can optimize layer updates after document scrolling by only clearing clip 18 rects, and recomputing repaint rects, if we encounter a fixed- or sticky-position 19 element. For overflow scroll, we have to clear clip rects and recompute repaint rects. 20 21 * page/FrameView.cpp: 22 (WebCore::FrameView::repaintFixedElementsAfterScrolling): Call updateLayerPositionsAfterDocumentScroll(). 23 * rendering/RenderLayer.cpp: 24 (WebCore::RenderLayer::updateLayerPositions): Call clearClipRects() because 25 updateLayerPosition() no longer does. 26 (WebCore::RenderLayer::updateLayerPositionsAfterDocumentScroll): Version of updateLayerPositionsAfterScroll() 27 that is for document scrolls. It has no need to push layers to the geometry map. 28 (WebCore::RenderLayer::updateLayerPositionsAfterOverflowScroll): Pushes layers to the geometry map, 29 and calls updateLayerPositionsAfterScroll() with the IsOverflowScroll flag. 30 (WebCore::RenderLayer::updateLayerPositionsAfterScroll): Set the HasChangedAncestor flag 31 if our location changed, and use that as a hint to clear cached rects. Be more conservative 32 than before about when to clear cached clip rects. 33 (WebCore::RenderLayer::updateLayerPosition): Move responsibility for calling 34 clearClipRects() ouf of this function and into callers. 35 (The one caller outside RenderLayer will be removed via bug 102624). 36 Return a bool indicating whether our position changed. 37 (WebCore::RenderLayer::scrollTo): Call updateLayerPositionsAfterOverflowScroll(). 38 (WebCore::RenderLayer::updateClipRects): Added some #ifdeffed out code that is useful 39 to verify that cached clips are correct; it's too slow to leave enabled in debug builds. 40 * rendering/RenderLayer.h: 41 (WebCore::RenderLayer::setLocation): Change to take a LayoutPoint, rather than separate 42 x and y. 43 1 44 2012-11-26 Simon Fraser <simon.fraser@apple.com> 2 45 -
branches/safari-536.28-branch/Source/WebCore/page/FrameView.cpp
r135776 r135777 1762 1762 if (RenderView* root = rootRenderer(this)) { 1763 1763 root->updateWidgetPositions(); 1764 root->layer()->updateLayerPositionsAfter Scroll();1764 root->layer()->updateLayerPositionsAfterDocumentScroll(); 1765 1765 } 1766 1766 } -
branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.cpp
r135776 r135777 330 330 if (geometryMap) 331 331 geometryMap->pushMappingsToAncestor(this, parent()); 332 333 // Clear our cached clip rect information. 334 clearClipRects(); 332 335 333 336 if (hasOverflowControls()) { … … 452 455 } 453 456 454 void RenderLayer::updateLayerPositionsAfterScroll() 457 void RenderLayer::updateLayerPositionsAfterDocumentScroll() 458 { 459 ASSERT(this == renderer()->view()->layer()); 460 461 RenderGeometryMap geometryMap; 462 updateLayerPositionsAfterScroll(&geometryMap); 463 } 464 465 void RenderLayer::updateLayerPositionsAfterOverflowScroll() 455 466 { 456 467 RenderGeometryMap geometryMap; … … 458 469 if (this != view->layer()) 459 470 geometryMap.pushMappingsToAncestor(parent(), 0); 460 updateLayerPositionsAfterScroll(&geometryMap); 471 472 // FIXME: why is it OK to not check the ancestors of this layer in order to 473 // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags? 474 updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll); 461 475 } 462 476 … … 473 487 return; 474 488 475 updateLayerPosition(); 489 bool positionChanged = updateLayerPosition(); 490 if (positionChanged) 491 flags |= HasChangedAncestor; 476 492 477 493 if (geometryMap) 478 494 geometryMap->pushMappingsToAncestor(this, parent()); 479 495 480 if ((flags & HasSeenViewportConstrainedAncestor) || renderer()->style()->position() == FixedPosition) { 481 // FIXME: Is it worth passing the offsetFromRoot around like in updateLayerPositions? 496 if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll) 497 clearClipRects(); 498 499 if (renderer()->style()->position() == FixedPosition) 500 flags |= HasSeenViewportConstrainedAncestor; 501 502 if (renderer()->hasOverflowClip()) 503 flags |= HasSeenAncestorWithOverflowClip; 504 505 if (flags & HasSeenViewportConstrainedAncestor 506 || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) { 482 507 // FIXME: We could track the repaint container as we walk down the tree. 483 508 computeRepaintRects(renderer()->containerForRepaint(), geometryMap); 484 flags |= HasSeenViewportConstrainedAncestor; 485 } else if ((flags & HasSeenAncestorWithOverflowClip) && !m_canSkipRepaintRectsUpdateOnScroll) { 486 // If we have seen an overflow clip, we should update our repaint rects as clippedOverflowRectForRepaint 487 // intersects it with our ancestor overflow clip that may have moved. 488 computeRepaintRects(renderer()->containerForRepaint(), geometryMap); 489 } 490 491 if (renderer()->hasOverflowClip()) 492 flags |= HasSeenAncestorWithOverflowClip; 493 509 } else { 510 // Check that our cached rects are correct. 511 ASSERT(m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint())); 512 ASSERT(m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap)); 513 } 514 494 515 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) 495 516 child->updateLayerPositionsAfterScroll(geometryMap, flags); … … 753 774 } 754 775 755 voidRenderLayer::updateLayerPosition()776 bool RenderLayer::updateLayerPosition() 756 777 { 757 778 LayoutPoint localPoint; … … 769 790 } 770 791 771 // Clear our cached clip rect information.772 clearClipRects();773 774 792 if (!renderer()->isPositioned() && renderer()->parent()) { 775 793 // We must adjust our position by walking up the render tree looking for the … … 814 832 localPoint -= scrollOffset; 815 833 } 816 834 835 bool positionOrOffsetChanged = false; 817 836 if (renderer()->isRelPositioned()) { 818 m_relativeOffset = renderer()->relativePositionOffset(); 837 LayoutSize newOffset = renderer()->relativePositionOffset(); 838 positionOrOffsetChanged = newOffset != m_relativeOffset; 839 m_relativeOffset = newOffset; 819 840 localPoint.move(m_relativeOffset); 820 841 } else { … … 824 845 // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers. 825 846 localPoint -= inlineBoundingBoxOffset; 826 setLocation(localPoint.x(), localPoint.y()); 847 848 positionOrOffsetChanged |= location() != localPoint; 849 setLocation(localPoint); 850 return positionOrOffsetChanged; 827 851 } 828 852 … … 1566 1590 m_scrollOffset = newScrollOffset; 1567 1591 1592 RenderView* view = renderer()->view(); 1593 1594 // We should have a RenderView if we're trying to scroll. 1595 ASSERT(view); 1596 1568 1597 // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll). 1569 1598 // We don't update compositing layers, because we need to do a deep update from the compositing ancestor. 1570 updateLayerPositionsAfterScroll(); 1571 1572 RenderView* view = renderer()->view(); 1573 1574 // We should have a RenderView if we're trying to scroll. 1575 ASSERT(view); 1576 if (view) { 1599 bool inLayout = view ? view->frameView()->isInLayout() : false; 1600 if (!inLayout) { 1601 // If we're in the middle of layout, we'll just update layers once layout has finished. 1602 updateLayerPositionsAfterOverflowScroll(); 1603 if (view) { 1604 // Update regions, scrolling may change the clip of a particular region. 1577 1605 #if ENABLE(DASHBOARD_SUPPORT) 1578 // Update dashboard regions, scrolling may change the clip of a 1579 // particular region. 1580 view->frameView()->updateDashboardRegions(); 1581 #endif 1582 1583 view->updateWidgetPositions(); 1584 } 1585 1586 updateCompositingLayersAfterScroll(); 1606 view->frameView()->updateDashboardRegions(); 1607 #endif 1608 view->updateWidgetPositions(); 1609 } 1610 updateCompositingLayersAfterScroll(); 1611 } 1587 1612 1588 1613 RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); … … 3830 3855 ASSERT(rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]); 3831 3856 ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == relevancy); 3857 3858 #ifdef CHECK_CACHED_CLIP_RECTS 3859 // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. 3860 ClipRectsContext tempContext(clipRectsContext); 3861 tempContext.clipRectsType = TemporaryClipRects; 3862 ClipRects clipRects; 3863 calculateClipRects(tempContext, clipRects); 3864 ASSERT(clipRects == *m_clipRectsCache->m_clipRects[clipRectsType].get()); 3865 #endif 3832 3866 return; // We have the correct cached value. 3833 3867 } -
branches/safari-536.28-branch/Source/WebCore/rendering/RenderLayer.h
r135776 r135777 301 301 302 302 const LayoutPoint& location() const { return m_topLeft; } 303 void setLocation( LayoutUnit x, LayoutUnit y) { m_topLeft = LayoutPoint(x, y); }303 void setLocation(const LayoutPoint& p) { m_topLeft = p; } 304 304 305 305 const IntSize& size() const { return m_layerSize; } … … 383 383 bool canRender3DTransforms() const; 384 384 385 void updateLayerPosition(); 385 // Returns true if the position changed. 386 bool updateLayerPosition(); 386 387 387 388 enum UpdateLayerPositionsFlag { … … 395 396 396 397 void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags); 397 void updateLayerPositionsAfterScroll(); 398 398 399 void updateLayerPositionsAfterOverflowScroll(); 400 void updateLayerPositionsAfterDocumentScroll(); 401 399 402 void updateTransform(); 400 403 … … 662 665 enum UpdateLayerPositionsAfterScrollFlag { 663 666 NoFlag = 0, 664 HasSeenViewportConstrainedAncestor = 1 << 0, 665 HasSeenAncestorWithOverflowClip = 1 << 1 667 IsOverflowScroll = 1 << 0, 668 HasSeenViewportConstrainedAncestor = 1 << 1, 669 HasSeenAncestorWithOverflowClip = 1 << 2, 670 HasChangedAncestor = 1 << 3 666 671 }; 667 672 typedef unsigned UpdateLayerPositionsAfterScrollFlags;
Note:
See TracChangeset
for help on using the changeset viewer.