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

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 layout tests 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
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 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 return false; 1252 return false;
1253 } 1253 }
1254 1254
1255 bool FrameView::useSlowRepaintsIfNotOverlapped() const 1255 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1256 { 1256 {
1257 return useSlowRepaints(false); 1257 return useSlowRepaints(false);
1258 } 1258 }
1259 1259
1260 bool FrameView::shouldAttemptToScrollUsingFastPath() const 1260 bool FrameView::shouldAttemptToScrollUsingFastPath() const
1261 { 1261 {
1262 // FIXME: useSlowRepaints reads compositing state in parent frames. Composit ing state on the parent
1263 // frames is not necessarily up to date.
1264 // https://code.google.com/p/chromium/issues/detail?id=343766
1265 DisableCompositingQueryAsserts disabler;
1266 return !useSlowRepaints(); 1262 return !useSlowRepaints();
1267 } 1263 }
1268 1264
1269 bool FrameView::contentsInCompositedLayer() const 1265 bool FrameView::contentsInCompositedLayer() const
1270 { 1266 {
1271 RenderView* renderView = this->renderView(); 1267 RenderView* renderView = this->renderView();
1272 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) { 1268 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
1273 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer(); 1269 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer();
1274 if (layer && layer->drawsContent()) 1270 if (layer && layer->drawsContent())
1275 return true; 1271 return true;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 { 1391 {
1396 return m_frame->eventHandler().lastKnownMousePosition(); 1392 return m_frame->eventHandler().lastKnownMousePosition();
1397 } 1393 }
1398 1394
1399 bool FrameView::shouldSetCursor() const 1395 bool FrameView::shouldSetCursor() const
1400 { 1396 {
1401 Page* page = frame().page(); 1397 Page* page = frame().page();
1402 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive(); 1398 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive();
1403 } 1399 }
1404 1400
1401 void FrameView::scrollContentsIfNeeded()
1402 {
1403 bool didScroll = !pendingScrollDelta().isZero();
1404 ScrollView::scrollContentsIfNeeded();
1405 if (didScroll)
1406 updateFixedElementRepaintRectsAfterScroll();
1407 }
1408
1405 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect) 1409 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect)
1406 { 1410 {
1407 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) { 1411 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) {
1408 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1412 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1409 return true; 1413 return true;
1410 } 1414 }
1411 1415
1412 // https://code.google.com/p/chromium/issues/detail?id=343767
1413 DisableCompositingQueryAsserts disabler;
1414 const bool isCompositedContentLayer = contentsInCompositedLayer(); 1416 const bool isCompositedContentLayer = contentsInCompositedLayer();
1415 1417
1416 // Get the rects of the fixed objects visible in the rectToScroll 1418 // Get the rects of the fixed objects visible in the rectToScroll
1417 Region regionToUpdate; 1419 Region regionToUpdate;
1418 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end(); 1420 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1419 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) { 1421 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1420 RenderObject* renderer = *it; 1422 RenderObject* renderer = *it;
1421 if (!renderer->style()->hasViewportConstrainedPosition()) 1423 if (!renderer->style()->hasViewportConstrainedPosition())
1422 continue; 1424 continue;
1423 1425
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 1468
1467 // 1) scroll 1469 // 1) scroll
1468 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1470 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1469 1471
1470 // 2) update the area of fixed objects that has been invalidated 1472 // 2) update the area of fixed objects that has been invalidated
1471 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects(); 1473 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1472 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size(); 1474 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
1473 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) { 1475 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
1474 IntRect updateRect = subRectsToUpdate[i]; 1476 IntRect updateRect = subRectsToUpdate[i];
1475 IntRect scrolledRect = updateRect; 1477 IntRect scrolledRect = updateRect;
1476 scrolledRect.move(scrollDelta); 1478 scrolledRect.move(-scrollDelta);
Ian Vollick 2014/03/21 00:14:14 Whoa. Was this a bug in the previous code?
esprehn 2014/03/24 21:50:43 Yeah can you explain why do you changed this?
ykyyip 2014/03/24 21:56:10 This changed because RenderView::computeRectForRep
1477 updateRect.unite(scrolledRect); 1479 updateRect.unite(scrolledRect);
1478 if (isCompositedContentLayer) { 1480 if (isCompositedContentLayer) {
1479 updateRect = rootViewToContents(updateRect); 1481 updateRect = rootViewToContents(updateRect);
1480 ASSERT(renderView()); 1482 ASSERT(renderView());
1481 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect); 1483 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect);
1482 continue; 1484 continue;
1483 } 1485 }
1484 if (clipsRepaints()) 1486 if (clipsRepaints())
1485 updateRect.intersect(rectToScroll); 1487 updateRect.intersect(rectToScroll);
1486 hostWindow()->invalidateContentsAndRootView(updateRect); 1488 hostWindow()->invalidateContentsAndRootView(updateRect);
1487 } 1489 }
1488 1490
1489 return true; 1491 return true;
1490 } 1492 }
1491 1493
1492 void FrameView::scrollContentsSlowPath(const IntRect& updateRect) 1494 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1493 { 1495 {
1494 // FIXME: This is called when JS calls scrollTo, at which point there's no g uarantee that
1495 // compositing state is up to date.
1496 // https://code.google.com/p/chromium/issues/detail?id=343767
1497 DisableCompositingQueryAsserts disabler;
1498
1499 if (contentsInCompositedLayer()) { 1496 if (contentsInCompositedLayer()) {
1500 IntRect updateRect = visibleContentRect(); 1497 IntRect updateRect = visibleContentRect();
1501 ASSERT(renderView()); 1498 ASSERT(renderView());
1502 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct); 1499 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct);
1503 } 1500 }
1504 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) { 1501 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1505 if (isEnclosedInCompositingLayer()) { 1502 if (isEnclosedInCompositingLayer()) {
1506 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(), 1503 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(),
1507 frameRenderer->borderTop() + frameRenderer->paddingT op(), 1504 frameRenderer->borderTop() + frameRenderer->paddingT op(),
1508 visibleWidth(), visibleHeight()); 1505 visibleWidth(), visibleHeight());
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 frame().loader().saveScrollState(); 1674 frame().loader().saveScrollState();
1678 } 1675 }
1679 1676
1680 void FrameView::didScrollTimerFired(Timer<FrameView>*) 1677 void FrameView::didScrollTimerFired(Timer<FrameView>*)
1681 { 1678 {
1682 if (m_frame->document() && m_frame->document()->renderer()) { 1679 if (m_frame->document() && m_frame->document()->renderer()) {
1683 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities(); 1680 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities();
1684 } 1681 }
1685 } 1682 }
1686 1683
1687 void FrameView::repaintFixedElementsAfterScrolling() 1684 void FrameView::updateLayersAndCompositingAfterScrollIfNeeded()
1688 { 1685 {
1686 // Nothing to do after scrolling if there are no fixed position elements.
1687 if (!hasViewportConstrainedObjects())
1688 return;
1689
1689 RefPtr<FrameView> protect(this); 1690 RefPtr<FrameView> protect(this);
1690 // For fixed position elements, update widget positions and compositing laye rs after scrolling, 1691
1691 // but only if we're not inside of layout. 1692 // If there fixed position elements, scrolling may cause compositing layers to change.
1692 if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) { 1693 // Update widget and layer positions after scrolling, but only if we're not inside of
1694 // layout.
1695 if (!m_nestedLayoutCount) {
1693 updateWidgetPositions(); 1696 updateWidgetPositions();
1694 if (RenderView* renderView = this->renderView()) 1697 if (RenderView* renderView = this->renderView())
1695 renderView->layer()->updateLayerPositionsAfterDocumentScroll(); 1698 renderView->layer()->updateLayerPositionsAfterDocumentScroll();
1696 } 1699 }
1700
1701 // Compositing layers may change after scrolling.
Ian Vollick 2014/03/21 00:14:14 If we kill overlap testing and land squashing, I t
ykyyip 2014/03/24 21:56:10 Done.
ykyyip 2014/03/24 21:56:10 I also wonder if we can revisit this code and make
1702 if (m_nestedLayoutCount <= 1) {
esprehn 2014/03/24 21:50:43 How do we get into here in a nested layout?
ykyyip 2014/03/24 22:15:03 I'm not sure. This code was moved from a different
1703 if (RenderView* renderView = this->renderView())
1704 renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdat eOnScroll);
1705 }
1697 } 1706 }
1698 1707
1699 void FrameView::updateFixedElementsAfterScrolling() 1708 void FrameView::updateFixedElementRepaintRectsAfterScroll()
1700 { 1709 {
1701 if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) { 1710 if (!hasViewportConstrainedObjects())
1702 if (RenderView* renderView = this->renderView()) 1711 return;
1703 renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdat eOnScroll); 1712
1713 // Update the repaint rects for fixed elements after scrolling and invalidat ion to reflect
1714 // the new scroll position.
1715 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1716 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1717 RenderObject* renderer = *it;
1718 if (!renderer->style()->hasViewportConstrainedPosition())
1719 continue;
1720
1721 // Fixed items should always have layers.
1722 ASSERT(renderer->hasLayer());
1723 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
Ian Vollick 2014/03/21 00:14:14 We don't need to do this if the layer is composite
ykyyip 2014/03/24 21:56:10 Yes, I think we don't need this if the layer has i
ykyyip 2014/03/24 21:56:10 Done.
1724 layer->repainter().computeRepaintRects(renderer->containerForRepaint());
esprehn 2014/03/24 21:50:43 Does this make all fixed position things repaint c
ykyyip 2014/03/24 22:15:03 As far as I understand it, RenderLayerRepainter::c
1704 } 1725 }
1705 } 1726 }
1706 1727
1707 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const 1728 bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
1708 { 1729 {
1709 Page* page = frame().page(); 1730 Page* page = frame().page();
1710 if (!page) 1731 if (!page)
1711 return ScrollView::shouldRubberBandInDirection(direction); 1732 return ScrollView::shouldRubberBandInDirection(direction);
1712 return page->chrome().client().shouldRubberBandInDirection(direction); 1733 return page->chrome().client().shouldRubberBandInDirection(direction);
1713 } 1734 }
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 bool FrameView::isActive() const 2323 bool FrameView::isActive() const
2303 { 2324 {
2304 Page* page = frame().page(); 2325 Page* page = frame().page();
2305 return page && page->focusController().isActive(); 2326 return page && page->focusController().isActive();
2306 } 2327 }
2307 2328
2308 void FrameView::scrollTo(const IntSize& newOffset) 2329 void FrameView::scrollTo(const IntSize& newOffset)
2309 { 2330 {
2310 LayoutSize offset = scrollOffset(); 2331 LayoutSize offset = scrollOffset();
2311 ScrollView::scrollTo(newOffset); 2332 ScrollView::scrollTo(newOffset);
2312 if (offset != scrollOffset()) 2333 if (offset != scrollOffset()) {
2334 updateLayersAndCompositingAfterScrollIfNeeded();
2313 scrollPositionChanged(); 2335 scrollPositionChanged();
2336 }
2314 frame().loader().client()->didChangeScrollOffset(); 2337 frame().loader().client()->didChangeScrollOffset();
2315 } 2338 }
2316 2339
2317 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec t) 2340 void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec t)
2318 { 2341 {
2319 // Add in our offset within the FrameView. 2342 // Add in our offset within the FrameView.
2320 IntRect dirtyRect = rect; 2343 IntRect dirtyRect = rect;
2321 dirtyRect.moveBy(scrollbar->location()); 2344 dirtyRect.moveBy(scrollbar->location());
2322 2345
2323 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout ()) { 2346 if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout ()) {
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
2781 2804
2782 ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOver hangArea, dirtyRect); 2805 ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOver hangArea, dirtyRect);
2783 } 2806 }
2784 2807
2785 void FrameView::updateLayoutAndStyleForPainting() 2808 void FrameView::updateLayoutAndStyleForPainting()
2786 { 2809 {
2787 // Updating layout can run script, which can tear down the FrameView. 2810 // Updating layout can run script, which can tear down the FrameView.
2788 RefPtr<FrameView> protector(this); 2811 RefPtr<FrameView> protector(this);
2789 2812
2790 updateLayoutAndStyleIfNeededRecursive(); 2813 updateLayoutAndStyleIfNeededRecursive();
2814
2791 if (RenderView* view = renderView()) 2815 if (RenderView* view = renderView())
2792 view->compositor()->updateCompositingLayers(); 2816 view->compositor()->updateCompositingLayers();
2817
2818 scrollContentsIfNeeded();
2793 } 2819 }
2794 2820
2795 void FrameView::updateLayoutAndStyleIfNeededRecursive() 2821 void FrameView::updateLayoutAndStyleIfNeededRecursive()
2796 { 2822 {
2797 // We have to crawl our entire tree looking for any FrameViews that need 2823 // We have to crawl our entire tree looking for any FrameViews that need
2798 // layout and make sure they are up to date. 2824 // layout and make sure they are up to date.
2799 // Mac actually tests for intersection with the dirty region and tries not t o 2825 // Mac actually tests for intersection with the dirty region and tries not t o
2800 // update layout for frames that are outside the dirty region. Not only doe s this seem 2826 // update layout for frames that are outside the dirty region. Not only doe s this seem
2801 // pointless (since those frames will have set a zero timer to layout anyway ), but 2827 // pointless (since those frames will have set a zero timer to layout anyway ), but
2802 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2828 // 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
3216 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation) 3242 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation)
3217 { 3243 {
3218 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); 3244 ScrollableArea::willRemoveScrollbar(scrollbar, orientation);
3219 if (AXObjectCache* cache = axObjectCache()) { 3245 if (AXObjectCache* cache = axObjectCache()) {
3220 cache->remove(scrollbar); 3246 cache->remove(scrollbar);
3221 cache->handleScrollbarUpdate(this); 3247 cache->handleScrollbarUpdate(this);
3222 } 3248 }
3223 } 3249 }
3224 3250
3225 } // namespace WebCore 3251 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698