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

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: 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 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 return false; 1254 return false;
1255 } 1255 }
1256 1256
1257 bool FrameView::useSlowRepaintsIfNotOverlapped() const 1257 bool FrameView::useSlowRepaintsIfNotOverlapped() const
1258 { 1258 {
1259 return useSlowRepaints(false); 1259 return useSlowRepaints(false);
1260 } 1260 }
1261 1261
1262 bool FrameView::shouldAttemptToScrollUsingFastPath() const 1262 bool FrameView::shouldAttemptToScrollUsingFastPath() const
1263 { 1263 {
1264 // FIXME: useSlowRepaints reads compositing state in parent frames. Composit ing state on the parent
1265 // frames is not necessarily up to date.
1266 // https://code.google.com/p/chromium/issues/detail?id=343766
1267 DisableCompositingQueryAsserts disabler;
1268 return !useSlowRepaints(); 1264 return !useSlowRepaints();
1269 } 1265 }
1270 1266
1271 bool FrameView::contentsInCompositedLayer() const 1267 bool FrameView::contentsInCompositedLayer() const
1272 { 1268 {
1273 RenderView* renderView = this->renderView(); 1269 RenderView* renderView = this->renderView();
1274 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) { 1270 if (renderView && renderView->compositingState() == PaintsIntoOwnBacking) {
1275 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer(); 1271 GraphicsLayer* layer = renderView->layer()->compositedLayerMapping()->ma inGraphicsLayer();
1276 if (layer && layer->drawsContent()) 1272 if (layer && layer->drawsContent())
1277 return true; 1273 return true;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive(); 1381 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive();
1386 } 1382 }
1387 1383
1388 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect) 1384 bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect & rectToScroll, const IntRect& clipRect)
1389 { 1385 {
1390 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) { 1386 if (!m_viewportConstrainedObjects || m_viewportConstrainedObjects->isEmpty() ) {
1391 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1387 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1392 return true; 1388 return true;
1393 } 1389 }
1394 1390
1395 // https://code.google.com/p/chromium/issues/detail?id=343767
1396 DisableCompositingQueryAsserts disabler;
1397 const bool isCompositedContentLayer = contentsInCompositedLayer();
1398
1399 // Get the rects of the fixed objects visible in the rectToScroll
1400 Region regionToUpdate;
1401 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end(); 1391 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1402 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) { 1392 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1403 RenderObject* renderer = *it; 1393 RenderObject* renderer = *it;
1404 if (!renderer->style()->hasViewportConstrainedPosition()) 1394 if (!renderer->style()->hasViewportConstrainedPosition())
1405 continue; 1395 continue;
1406 1396
1407 // Fixed items should always have layers. 1397 // Fixed items should always have layers.
1408 ASSERT(renderer->hasLayer()); 1398 ASSERT(renderer->hasLayer());
1409 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 1399 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1410 1400
1411 // Layers that paint into their ancestor or into a grouped backing will still need
1412 // to apply a repaint invalidation. If the layer paints into its own bac king, then
1413 // it does not need repainting just to scroll.
1414 if (layer->compositingState() == PaintsIntoOwnBacking)
1415 continue;
1416
1417 if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotC ompositedForBoundsOutOfView
1418 || layer->viewportConstrainedNotCompositedReason() == RenderLayer::N otCompositedForNoVisibleContent) {
1419 // Don't invalidate for invisible fixed layers.
1420 continue;
1421 }
1422
1423 if (layer->hasAncestorWithFilterOutsets()) { 1401 if (layer->hasAncestorWithFilterOutsets()) {
1424 // If the fixed layer has a blur/drop-shadow filter applied on at le ast one of its parents, we cannot 1402 // If the fixed layer has a blur/drop-shadow filter applied on at le ast one of its parents, we cannot
1425 // scroll using the fast path, otherwise the outsets of the filter w ill be moved around the page. 1403 // scroll using the fast path, otherwise the outsets of the filter w ill be moved around the page.
1426 return false; 1404 return false;
1427 } 1405 }
1428
1429 IntRect updateRect = pixelSnappedIntRect(layer->repainter().repaintRectI ncludingNonCompositingDescendants());
1430
1431 RenderLayer* enclosingCompositingLayer = layer->enclosingCompositingLaye r(ExcludeSelf);
1432 if (enclosingCompositingLayer && !enclosingCompositingLayer->renderer()- >isRenderView()) {
1433 // If the fixed-position layer is contained by a composited layer th at is not its containing block,
1434 // then we have to invlidate that enclosing layer, not the RenderVie w.
1435 updateRect.moveBy(scrollPosition());
1436 IntRect previousRect = updateRect;
1437 previousRect.move(scrollDelta);
1438 updateRect.unite(previousRect);
1439 enclosingCompositingLayer->repainter().setBackingNeedsRepaintInRect( updateRect);
1440 } else {
1441 // Coalesce the repaints that will be issued to the renderView.
1442 updateRect = contentsToRootView(updateRect);
1443 if (!isCompositedContentLayer && clipsRepaints())
1444 updateRect.intersect(rectToScroll);
1445 if (!updateRect.isEmpty())
1446 regionToUpdate.unite(updateRect);
1447 }
1448 } 1406 }
1449 1407
1450 // 1) scroll
1451 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect); 1408 hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
1452 1409
1453 // 2) update the area of fixed objects that has been invalidated
1454 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1455 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
1456 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
1457 IntRect updateRect = subRectsToUpdate[i];
1458 IntRect scrolledRect = updateRect;
1459 scrolledRect.move(scrollDelta);
1460 updateRect.unite(scrolledRect);
1461 if (isCompositedContentLayer) {
1462 updateRect = rootViewToContents(updateRect);
1463 ASSERT(renderView());
1464 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect);
1465 continue;
1466 }
1467 if (clipsRepaints())
1468 updateRect.intersect(rectToScroll);
1469 hostWindow()->invalidateContentsAndRootView(updateRect);
1470 }
1471
1472 return true; 1410 return true;
1473 } 1411 }
1474 1412
1475 void FrameView::scrollContentsSlowPath(const IntRect& updateRect) 1413 void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
1476 { 1414 {
1477 // FIXME: This is called when JS calls scrollTo, at which point there's no g uarantee that
1478 // compositing state is up to date.
1479 // https://code.google.com/p/chromium/issues/detail?id=343767
1480 DisableCompositingQueryAsserts disabler;
1481
1482 if (contentsInCompositedLayer()) { 1415 if (contentsInCompositedLayer()) {
1483 IntRect updateRect = visibleContentRect(); 1416 IntRect updateRect = visibleContentRect();
1484 ASSERT(renderView()); 1417 ASSERT(renderView());
1485 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct); 1418 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRe ct);
1486 } 1419 }
1487 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) { 1420 if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
1488 if (isEnclosedInCompositingLayer()) { 1421 if (isEnclosedInCompositingLayer()) {
1489 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(), 1422 LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->padding Left(),
1490 frameRenderer->borderTop() + frameRenderer->paddingT op(), 1423 frameRenderer->borderTop() + frameRenderer->paddingT op(),
1491 visibleWidth(), visibleHeight()); 1424 visibleWidth(), visibleHeight());
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 cache->handleScrollPositionChanged(this); 1591 cache->handleScrollPositionChanged(this);
1659 } 1592 }
1660 1593
1661 void FrameView::didScrollTimerFired(Timer<FrameView>*) 1594 void FrameView::didScrollTimerFired(Timer<FrameView>*)
1662 { 1595 {
1663 if (m_frame->document() && m_frame->document()->renderer()) { 1596 if (m_frame->document() && m_frame->document()->renderer()) {
1664 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities(); 1597 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAl lImageResourcePriorities();
1665 } 1598 }
1666 } 1599 }
1667 1600
1601 void FrameView::invalidateFixedElementsBeforeScrolling(const IntSize& scrollDelt a, const IntRect& rectToScroll)
1602 {
1603 // Invalidate the fixed position layer before updating the compositing state . If the fixed
1604 // position layer gains its own backing after scrolling, the backing it form erly painted into
1605 // will not get invalidated after scrolling, because at that point it alread y forgot about
1606 // the previous compositing state.
1607 // TODO: Add a way to read the stale compositing state to get rid of this di sabler.
1608 DisableCompositingQueryAsserts disabler;
1609 if (!shouldAttemptToScrollUsingFastPath())
1610 return;
1611
1612 if (!hasViewportConstrainedObjects())
1613 return;
1614
1615 const bool isCompositedContentLayer = contentsInCompositedLayer();
1616
1617 Region regionToUpdate;
1618 ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObje cts->end();
1619 for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrained Objects->begin(); it != end; ++it) {
1620 RenderObject* renderer = *it;
1621 if (!renderer->style()->hasViewportConstrainedPosition())
1622 continue;
1623
1624 // Fixed items should always have layers.
1625 ASSERT(renderer->hasLayer());
1626 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
1627
1628 // Layers that paint into their ancestor or into a grouped backing will still need
1629 // to apply a repaint invalidation. If the layer paints into its own bac king, then
1630 // it does not need repainting just to scroll.
1631 if (layer->compositingState() == PaintsIntoOwnBacking)
1632 continue;
1633
1634 if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotC ompositedForBoundsOutOfView
1635 || layer->viewportConstrainedNotCompositedReason() == RenderLayer::N otCompositedForNoVisibleContent) {
1636 // Don't invalidate for invisible fixed layers.
1637 continue;
1638 }
1639
1640 if (layer->hasAncestorWithFilterOutsets()) {
1641 // If the fixed layer has a blur/drop-shadow filter applied on at le ast one of its parents, we cannot
1642 // scroll using the fast path, otherwise the outsets of the filter w ill be moved around the page.
1643 return;
1644 }
1645
1646 IntRect updateRect = pixelSnappedIntRect(layer->repainter().repaintRectI ncludingNonCompositingDescendants());
1647
1648 RenderLayer* enclosingCompositingLayer = layer->enclosingCompositingLaye r(ExcludeSelf);
1649 if (enclosingCompositingLayer && !enclosingCompositingLayer->renderer()- >isRenderView()) {
1650 // If the fixed-position layer is contained by a composited layer th at is not its containing block,
1651 // then we have to invlidate that enclosing layer, not the RenderVie w.
1652 updateRect.moveBy(scrollPosition());
1653 IntRect previousRect = updateRect;
1654 previousRect.move(scrollDelta);
1655 updateRect.unite(previousRect);
1656 enclosingCompositingLayer->repainter().setBackingNeedsRepaintInRect( updateRect);
1657 } else {
1658 // Coalesce the repaints that will be issued to the renderView.
1659 updateRect = contentsToRootView(updateRect);
1660 if (!isCompositedContentLayer && clipsRepaints())
1661 updateRect.intersect(rectToScroll);
1662 if (!updateRect.isEmpty())
1663 regionToUpdate.unite(updateRect);
1664 }
1665 }
1666
1667 // update the area of fixed objects that has been invalidated
1668 Vector<IntRect> subRectsToUpdate = regionToUpdate.rects();
1669 size_t viewportConstrainedObjectsCount = subRectsToUpdate.size();
1670 for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
1671 IntRect updateRect = subRectsToUpdate[i];
1672 IntRect scrolledRect = updateRect;
1673 scrolledRect.move(scrollDelta);
1674 updateRect.unite(scrolledRect);
1675 if (isCompositedContentLayer) {
1676 updateRect = rootViewToContents(updateRect);
1677 ASSERT(renderView());
1678 renderView()->layer()->repainter().setBackingNeedsRepaintInRect(upda teRect);
1679 continue;
1680 }
1681 if (clipsRepaints())
1682 updateRect.intersect(rectToScroll);
1683 hostWindow()->invalidateContentsAndRootView(updateRect);
1684 }
1685 }
1686
1668 void FrameView::repaintFixedElementsAfterScrolling() 1687 void FrameView::repaintFixedElementsAfterScrolling()
1669 { 1688 {
1670 RefPtr<FrameView> protect(this); 1689 RefPtr<FrameView> protect(this);
1671 // For fixed position elements, update widget positions and compositing laye rs after scrolling, 1690 // For fixed position elements, update widget positions and compositing laye rs after scrolling,
1672 // but only if we're not inside of layout. 1691 // but only if we're not inside of layout.
1673 if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) { 1692 if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) {
1674 updateWidgetPositions(); 1693 updateWidgetPositions();
1675 if (RenderView* renderView = this->renderView()) 1694 if (RenderView* renderView = this->renderView())
1676 renderView->layer()->updateLayerPositionsAfterDocumentScroll(); 1695 renderView->layer()->updateLayerPositionsAfterDocumentScroll();
1677 } 1696 }
(...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after
2745 } 2764 }
2746 2765
2747 void FrameView::updateLayoutAndStyleForPainting() 2766 void FrameView::updateLayoutAndStyleForPainting()
2748 { 2767 {
2749 // Updating layout can run script, which can tear down the FrameView. 2768 // Updating layout can run script, which can tear down the FrameView.
2750 RefPtr<FrameView> protector(this); 2769 RefPtr<FrameView> protector(this);
2751 2770
2752 updateLayoutAndStyleIfNeededRecursive(); 2771 updateLayoutAndStyleIfNeededRecursive();
2753 if (RenderView* view = renderView()) 2772 if (RenderView* view = renderView())
2754 view->compositor()->updateCompositingLayers(); 2773 view->compositor()->updateCompositingLayers();
2774 scrollContentsIfNeeded();
2755 } 2775 }
2756 2776
2757 void FrameView::updateLayoutAndStyleIfNeededRecursive() 2777 void FrameView::updateLayoutAndStyleIfNeededRecursive()
2758 { 2778 {
2759 // We have to crawl our entire tree looking for any FrameViews that need 2779 // We have to crawl our entire tree looking for any FrameViews that need
2760 // layout and make sure they are up to date. 2780 // layout and make sure they are up to date.
2761 // Mac actually tests for intersection with the dirty region and tries not t o 2781 // Mac actually tests for intersection with the dirty region and tries not t o
2762 // update layout for frames that are outside the dirty region. Not only doe s this seem 2782 // update layout for frames that are outside the dirty region. Not only doe s this seem
2763 // pointless (since those frames will have set a zero timer to layout anyway ), but 2783 // pointless (since those frames will have set a zero timer to layout anyway ), but
2764 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2784 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation) 3199 void FrameView::willRemoveScrollbar(Scrollbar* scrollbar, ScrollbarOrientation o rientation)
3180 { 3200 {
3181 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); 3201 ScrollableArea::willRemoveScrollbar(scrollbar, orientation);
3182 if (AXObjectCache* cache = axObjectCache()) { 3202 if (AXObjectCache* cache = axObjectCache()) {
3183 cache->remove(scrollbar); 3203 cache->remove(scrollbar);
3184 cache->handleScrollbarUpdate(this); 3204 cache->handleScrollbarUpdate(this);
3185 } 3205 }
3186 } 3206 }
3187 3207
3188 } // namespace WebCore 3208 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698