OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |