| 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 |