Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: Source/core/frame/FrameView.cpp

Issue 191693002: Delay scrollContents until the next paint (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix nit Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/frame/FrameView.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 return false; 1244 return false;
1245 } 1245 }
1246 1246
1247 bool FrameView::useSlowRepaintsIfNotOverlapped() const 1247 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1248 { 1248 {
1249 return useSlowRepaints(false); 1249 return useSlowRepaints(false);
1250 } 1250 }
1251 1251
1252 bool FrameView::shouldAttemptToScrollUsingFastPath() const 1252 bool FrameView::shouldAttemptToScrollUsingFastPath() const
1253 { 1253 {
1254 // FIXME: useSlowRepaints reads compositing state in parent frames. Composit ing state on the parent
1255 // frames is not necessarily up to date.
1256 // https://code.google.com/p/chromium/issues/detail?id=343766
1257 DisableCompositingQueryAsserts disabler;
1258 return !useSlowRepaints(); 1254 return !useSlowRepaints();
1259 } 1255 }
1260 1256
1261 bool FrameView::contentsInCompositedLayer() const 1257 bool FrameView::contentsInCompositedLayer() const
1262 { 1258 {
1263 RenderView* renderView = this->renderView(); 1259 RenderView* renderView = this->renderView();
1264 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) { 1260 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
1265 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer(); 1261 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer();
1266 if (layer && layer->drawsContent()) 1262 if (layer && layer->drawsContent())
1267 return true; 1263 return true;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 { 1383 {
1388 return m_frame->eventHandler().lastKnownMousePosition(); 1384 return m_frame->eventHandler().lastKnownMousePosition();
1389 } 1385 }
1390 1386
1391 bool FrameView::shouldSetCursor() const 1387 bool FrameView::shouldSetCursor() const
1392 { 1388 {
1393 Page* page = frame().page(); 1389 Page* page = frame().page();
1394 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive(); 1390 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive();
1395 } 1391 }
1396 1392
1393 void FrameView::scrollContentsIfNeededRecursive()
1394 {
1395 scrollContentsIfNeeded();
1396
1397 for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child- >tree().nextSibling()) {
1398 if (FrameView* view = child->view())
1399 view->scrollContentsIfNeededRecursive();
1400 }
1401 }
1402
1403 void FrameView::scrollContentsIfNeeded()
1404 {
1405 bool didScroll = !pendingScrollDelta().isZero();
1406 ScrollView::scrollContentsIfNeeded();
1407 if (didScroll)
1408 updateFixedElementRepaintRectsAfterScroll();
1409 }
1410
1397 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect) 1411 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect)
1398 { 1412 {
1399 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) { 1413 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) {
1400 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1414 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1401 return true; 1415 return true;
1402 } 1416 }
1403 1417
1404 // https://code.google.com/p/chromium/issues/detail?id=343767
1405 DisableCompositingQueryAsserts disabler;
1406 const bool isCompositedContentLayer = contentsInCompositedLayer(); 1418 const bool isCompositedContentLayer = contentsInCompositedLayer();
1407 1419
1408 // Get the rects of the fixed objects visible in the rectToScroll 1420 // Get the rects of the fixed objects visible in the rectToScroll
1409 Region regionToUpdate; 1421 Region regionToUpdate;
1410 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end(); 1422 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1411 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) { 1423 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1412 RenderObject* renderer = *it; 1424 RenderObject* renderer = *it;
1413 if (!renderer->style()->hasViewportConstrainedPosition()) 1425 // m_viewportConstrainedObjects should not contain non-viewport constrai ned objects.
1414 continue; 1426 ASSERT(renderer->style()->hasViewportConstrainedPosition());
1415 1427
1416 // Fixed items should always have layers. 1428 // Fixed items should always have layers.
1417 ASSERT(renderer->hasLayer()); 1429 ASSERT(renderer->hasLayer());
1418 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 1430 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1419 1431
1420 // Layers that paint into their ancestor or into a grouped backing will still need 1432 // Layers that paint into their ancestor or into a grouped backing will still need
1421 // to apply a repaint invalidation. If the layer paints into its own bac king, then 1433 // to apply a repaint invalidation. If the layer paints into its own bac king, then
1422 // it does not need repainting just to scroll. 1434 // it does not need repainting just to scroll.
1423 if (layer->compositingState() == PaintsIntoOwnBacking) 1435 if (layer->compositingState() == PaintsIntoOwnBacking)
1424 continue; 1436 continue;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 1470
1459 // 1) scroll 1471 // 1) scroll
1460 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1472 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1461 1473
1462 // 2) update the area of fixed objects that has been invalidated 1474 // 2) update the area of fixed objects that has been invalidated
1463 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects(); 1475 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1464 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size(); 1476 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
1465 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) { 1477 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
1466 IntRect updateRect = subRectsToUpdate[i]; 1478 IntRect updateRect = subRectsToUpdate[i];
1467 IntRect scrolledRect = updateRect; 1479 IntRect scrolledRect = updateRect;
1468 scrolledRect.move(scrollDelta); 1480 scrolledRect.move(-scrollDelta);
1469 updateRect.unite(scrolledRect); 1481 updateRect.unite(scrolledRect);
1470 if (isCompositedContentLayer) { 1482 if (isCompositedContentLayer) {
1471 updateRect = rootViewToContents(updateRect); 1483 updateRect = rootViewToContents(updateRect);
1472 ASSERT(renderView()); 1484 ASSERT(renderView());
1473 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect); 1485 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect);
1474 continue; 1486 continue;
1475 } 1487 }
1476 if (clipsRepaints()) 1488 if (clipsRepaints())
1477 updateRect.intersect(rectToScroll); 1489 updateRect.intersect(rectToScroll);
1478 hostWindow()->invalidateContentsAndRootView(updateRect); 1490 hostWindow()->invalidateContentsAndRootView(updateRect);
1479 } 1491 }
1480 1492
1481 return true; 1493 return true;
1482 } 1494 }
1483 1495
1484 void FrameView::scrollContentsSlowPath(const IntRect& updateRect) 1496 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1485 { 1497 {
1486 // FIXME: This is called when JS calls scrollTo, at which point there's no g uarantee that
1487 // compositing state is up to date.
1488 // https://code.google.com/p/chromium/issues/detail?id=343767
1489 DisableCompositingQueryAsserts disabler;
1490
1491 if (contentsInCompositedLayer()) { 1498 if (contentsInCompositedLayer()) {
1492 IntRect updateRect = visibleContentRect(); 1499 IntRect updateRect = visibleContentRect();
1493 ASSERT(renderView()); 1500 ASSERT(renderView());
1494 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct); 1501 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct);
1495 } 1502 }
1496 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) { 1503 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1497 if (isEnclosedInCompositingLayer()) { 1504 if (isEnclosedInCompositingLayer()) {
1498 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(), 1505 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(),
1499 frameRenderer->borderTop() + frameRenderer->paddingT op(), 1506 frameRenderer->borderTop() + frameRenderer->paddingT op(),
1500 visibleWidth(), visibleHeight()); 1507 visibleWidth(), visibleHeight());
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 frame().loader().saveScrollState(); 1676 frame().loader().saveScrollState();
1670 } 1677 }
1671 1678
1672 void FrameView::didScrollTimerFired(Timer<FrameView>*) 1679 void FrameView::didScrollTimerFired(Timer<FrameView>*)
1673 { 1680 {
1674 if (m_frame->document() && m_frame->document()->renderer()) { 1681 if (m_frame->document() && m_frame->document()->renderer()) {
1675 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities(); 1682 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities();
1676 } 1683 }
1677 } 1684 }
1678 1685
1679 void FrameView::repaintFixedElementsAfterScrolling() 1686 void FrameView::updateLayersAndCompositingAfterScrollIfNeeded()
1680 { 1687 {
1688 // Nothing to do after scrolling if there are no fixed position elements.
1689 if (!hasViewportConstrainedObjects())
1690 return;
1691
1681 RefPtr<FrameView> protect(this); 1692 RefPtr<FrameView> protect(this);
1682 // For fixed position elements, update widget positions and compositing laye rs after scrolling, 1693
1683 // but only if we're not inside of layout. 1694 // If there fixed position elements, scrolling may cause compositing layers to change.
1684 if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) { 1695 // Update widget and layer positions after scrolling, but only if we're not inside of
1696 // layout.
1697 if (!m_nestedLayoutCount) {
1685 updateWidgetPositions(); 1698 updateWidgetPositions();
1686 if (RenderView* renderView = this->renderView()) 1699 if (RenderView* renderView = this->renderView())
1687 renderView->layer()->updateLayerPositionsAfterDocumentScroll(); 1700 renderView->layer()->updateLayerPositionsAfterDocumentScroll();
1688 } 1701 }
1702
1703 // Compositing layers may change after scrolling.
1704 // FIXME: Maybe no longer needed after we land squashing and kill overlap te sting?
1705 if (RenderView* renderView = this->renderView())
1706 renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateOnS croll);
1689 } 1707 }
1690 1708
1691 void FrameView::updateFixedElementsAfterScrolling() 1709 void FrameView::updateFixedElementRepaintRectsAfterScroll()
1692 { 1710 {
1693 if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) { 1711 if (!hasViewportConstrainedObjects())
1694 if (RenderView* renderView = this->renderView()) 1712 return;
1695 renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdat eOnScroll); 1713
1714 // Update the repaint rects for fixed elements after scrolling and invalidat ion to reflect
1715 // the new scroll position.
1716 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1717 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1718 RenderObject* renderer = *it;
1719 // m_viewportConstrainedObjects should not contain non-viewport constrai ned objects.
1720 ASSERT(renderer->style()->hasViewportConstrainedPosition());
1721
1722 // Fixed items should always have layers.
1723 ASSERT(renderer->hasLayer());
1724
1725 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1726
1727 // Don't need to do this for composited fixed items.
1728 if (layer->compositingState() == PaintsIntoOwnBacking)
1729 continue;
1730
1731 // Also don't need to do this for invisible items.
1732 if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotC ompositedForBoundsOutOfView
1733 || layer->viewportConstrainedNotCompositedReason() == RenderLayer::N otCompositedForNoVisibleContent)
1734 continue;
1735
1736 layer->repainter().computeRepaintRects(renderer->containerForRepaint());
1696 } 1737 }
1697 } 1738 }
1698 1739
1699 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const 1740 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
1700 { 1741 {
1701 Page* page = frame().page(); 1742 Page* page = frame().page();
1702 if (!page) 1743 if (!page)
1703 return ScrollView::shouldRubberBandInDirection(direction); 1744 return ScrollView::shouldRubberBandInDirection(direction);
1704 return page->chrome().client().shouldRubberBandInDirection(direction); 1745 return page->chrome().client().shouldRubberBandInDirection(direction);
1705 } 1746 }
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 bool FrameView::isActive() const 2331 bool FrameView::isActive() const
2291 { 2332 {
2292 Page* page = frame().page(); 2333 Page* page = frame().page();
2293 return page && page->focusController().isActive(); 2334 return page && page->focusController().isActive();
2294 } 2335 }
2295 2336
2296 void FrameView::scrollTo(const IntSize& newOffset) 2337 void FrameView::scrollTo(const IntSize& newOffset)
2297 { 2338 {
2298 LayoutSize offset = scrollOffset(); 2339 LayoutSize offset = scrollOffset();
2299 ScrollView::scrollTo(newOffset); 2340 ScrollView::scrollTo(newOffset);
2300 if (offset != scrollOffset()) 2341 if (offset != scrollOffset()) {
2342 updateLayersAndCompositingAfterScrollIfNeeded();
2301 scrollPositionChanged(); 2343 scrollPositionChanged();
2344 }
2302 frame().loader().client()->didChangeScrollOffset(); 2345 frame().loader().client()->didChangeScrollOffset();
2303 } 2346 }
2304 2347
2305 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec t) 2348 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec t)
2306 { 2349 {
2307 // Add in our offset within the FrameView. 2350 // Add in our offset within the FrameView.
2308 IntRect dirtyRect = rect; 2351 IntRect dirtyRect = rect;
2309 dirtyRect.moveBy(scrollbar->location()); 2352 dirtyRect.moveBy(scrollbar->location());
2310 2353
2311 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout ()) { 2354 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout ()) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 updateLayoutAndStyleIfNeededRecursive(); 2821 updateLayoutAndStyleIfNeededRecursive();
2779 if (RenderView* view = renderView()) { 2822 if (RenderView* view = renderView()) {
2780 ASSERT(!view->needsLayout()); 2823 ASSERT(!view->needsLayout());
2781 view->compositor()->updateCompositingLayers(); 2824 view->compositor()->updateCompositingLayers();
2782 2825
2783 // FIXME: we should not have any dirty bits left at this point. Unfortun ately, this is not yet the case because 2826 // FIXME: we should not have any dirty bits left at this point. Unfortun ately, this is not yet the case because
2784 // the code in updateCompositingLayers sometimes creates new dirty bits when updating direct compositing reasons. 2827 // the code in updateCompositingLayers sometimes creates new dirty bits when updating direct compositing reasons.
2785 // See crbug.com/354100. 2828 // See crbug.com/354100.
2786 view->compositor()->scheduleAnimationIfNeeded(); 2829 view->compositor()->scheduleAnimationIfNeeded();
2787 } 2830 }
2831
2832 scrollContentsIfNeededRecursive();
2788 } 2833 }
2789 2834
2790 void FrameView::updateLayoutAndStyleIfNeededRecursive() 2835 void FrameView::updateLayoutAndStyleIfNeededRecursive()
2791 { 2836 {
2792 // We have to crawl our entire tree looking for any FrameViews that need 2837 // We have to crawl our entire tree looking for any FrameViews that need
2793 // layout and make sure they are up to date. 2838 // layout and make sure they are up to date.
2794 // Mac actually tests for intersection with the dirty region and tries not t o 2839 // Mac actually tests for intersection with the dirty region and tries not t o
2795 // update layout for frames that are outside the dirty region. Not only doe s this seem 2840 // update layout for frames that are outside the dirty region. Not only doe s this seem
2796 // pointless (since those frames will have set a zero timer to layout anyway ), but 2841 // pointless (since those frames will have set a zero timer to layout anyway ), but
2797 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2842 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
3211 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation) 3256 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation)
3212 { 3257 {
3213 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); 3258 ScrollableArea::willRemoveScrollbar(scrollbar, orientation);
3214 if (AXObjectCache* cache = axObjectCache()) { 3259 if (AXObjectCache* cache = axObjectCache()) {
3215 cache->remove(scrollbar); 3260 cache->remove(scrollbar);
3216 cache->handleScrollbarUpdate(this); 3261 cache->handleScrollbarUpdate(this);
3217 } 3262 }
3218 } 3263 }
3219 3264
3220 } // namespace WebCore 3265 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/frame/FrameView.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698