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 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |