Changeset 114651 in webkit
- Timestamp:
- Apr 19, 2012 11:03:46 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r114649 r114651 1 2012-04-19 Sami Kyostila <skyostil@chromium.org> 2 3 [chromium] Allow scrolling non-root layers in the compositor thread 4 https://bugs.webkit.org/show_bug.cgi?id=73350 5 6 Reviewed by James Robinson. 7 8 This patch enables scrolling child layers in the compositor thread. 9 Scroll deltas are accumulated for each scrolled CCLayerImpl and 10 synchronized to the main thread. 11 12 If a layer has no room to scroll in a given direction, one of its 13 ancestor layers is scrolled instead if possible. 14 15 Added new webkit_unit_tests to verify scrolling behavior. 16 17 * platform/graphics/chromium/ContentLayerChromium.cpp: 18 (WebCore::ContentLayerChromium::scrollBy): 19 (WebCore): 20 * platform/graphics/chromium/ContentLayerChromium.h: 21 (ContentLayerDelegate): 22 (ContentLayerChromium): 23 * platform/graphics/chromium/GraphicsLayerChromium.h: 24 (WebCore::GraphicsLayerChromium::didScroll): 25 * platform/graphics/chromium/LayerChromium.cpp: 26 (WebCore::LayerChromium::setMaxScrollPosition): 27 (WebCore): 28 (WebCore::LayerChromium::pushPropertiesTo): 29 * platform/graphics/chromium/LayerChromium.h: 30 (LayerChromium): 31 (WebCore::LayerChromium::maxScrollPosition): 32 (WebCore::LayerChromium::scrollable): 33 (WebCore::LayerChromium::scrollBy): 34 * platform/graphics/chromium/cc/CCLayerImpl.cpp: 35 (WebCore::CCLayerImpl::findLayerInSubtree): 36 (WebCore): 37 (WebCore::CCLayerImpl::tryScroll): 38 * platform/graphics/chromium/cc/CCLayerImpl.h: 39 (CCLayerImpl): 40 * platform/graphics/chromium/cc/CCLayerTreeHost.cpp: 41 (WebCore::findLayerById): 42 (WebCore): 43 (WebCore::findFirstScrollableLayer): 44 (WebCore::CCLayerTreeHost::applyScrollAndScale): 45 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: 46 (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl): 47 (WebCore::CCLayerTreeHostImpl::startPageScaleAnimation): 48 (WebCore::CCLayerTreeHostImpl::contentSize): 49 (WebCore): 50 (WebCore::CCLayerTreeHostImpl::calculateVisibleLayers): 51 (WebCore::CCLayerTreeHostImpl::prepareToDraw): 52 (WebCore::findRootScrollLayer): 53 (WebCore::findScrollLayerForContentLayer): 54 (WebCore::CCLayerTreeHostImpl::setRootLayer): 55 (WebCore::adjustScrollsForPageScaleChange): 56 (WebCore::applyPageScaleDeltaToScrollLayers): 57 (WebCore::CCLayerTreeHostImpl::setPageScaleFactorAndLimits): 58 (WebCore::CCLayerTreeHostImpl::setPageScaleDelta): 59 (WebCore::CCLayerTreeHostImpl::updateMaxScrollPosition): 60 (WebCore::CCLayerTreeHostImpl::scrollBegin): 61 (WebCore::CCLayerTreeHostImpl::scrollBy): 62 (WebCore::CCLayerTreeHostImpl::scrollEnd): 63 (WebCore::CCLayerTreeHostImpl::pinchGestureUpdate): 64 (WebCore::CCLayerTreeHostImpl::computePinchZoomDeltas): 65 (WebCore::CCLayerTreeHostImpl::makeScrollAndScaleSet): 66 (WebCore::collectScrollDeltas): 67 (WebCore::CCLayerTreeHostImpl::processScrollDeltas): 68 (WebCore::CCLayerTreeHostImpl::animatePageScale): 69 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h: 70 (WebCore::CCLayerTreeHostImpl::rootScrollLayer): 71 (CCLayerTreeHostImpl): 72 (LayerGeometry): 73 1 74 2012-04-19 Yury Semikhatsky <yurys@chromium.org> 2 75 -
trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
r113809 r114651 146 146 } 147 147 148 void ContentLayerChromium::scrollBy(const IntSize& scrollDelta) 149 { 150 setScrollPosition(scrollPosition() + scrollDelta); 151 if (m_delegate) 152 m_delegate->didScroll(scrollDelta); 153 } 154 148 155 } 149 156 #endif // USE(ACCELERATED_COMPOSITING) -
trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
r113902 r114651 47 47 virtual ~ContentLayerDelegate() { } 48 48 virtual void paintContents(GraphicsContext&, const IntRect& clip) = 0; 49 virtual void didScroll(const IntSize&) = 0; 49 50 }; 50 51 … … 64 65 virtual void setOpaque(bool) OVERRIDE; 65 66 67 virtual void scrollBy(const IntSize&) OVERRIDE; 68 66 69 protected: 67 70 explicit ContentLayerChromium(ContentLayerDelegate*); -
trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
r113090 r114651 114 114 // ContentLayerDelegate implementation. 115 115 virtual void paintContents(GraphicsContext&, const IntRect& clip); 116 virtual void didScroll(const IntSize&) OVERRIDE { } 116 117 117 118 // CCLayerAnimationDelegate implementation. -
trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
r114081 r114651 382 382 } 383 383 384 void LayerChromium::setMaxScrollPosition(const IntSize& maxScrollPosition) 385 { 386 if (m_maxScrollPosition == maxScrollPosition) 387 return; 388 m_maxScrollPosition = maxScrollPosition; 389 setNeedsCommit(); 390 } 391 384 392 void LayerChromium::setScrollable(bool scrollable) 385 393 { … … 502 510 layer->setPreserves3D(preserves3D()); 503 511 layer->setScrollPosition(m_scrollPosition); 512 layer->setMaxScrollPosition(m_maxScrollPosition); 504 513 layer->setSublayerTransform(m_sublayerTransform); 505 514 if (!transformIsAnimating()) -
trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h
r114284 r114651 142 142 const IntPoint& scrollPosition() const { return m_scrollPosition; } 143 143 144 void setMaxScrollPosition(const IntSize&); 145 const IntSize& maxScrollPosition() const { return m_maxScrollPosition; } 146 144 147 void setScrollable(bool); 148 bool scrollable() const { return m_scrollable; } 145 149 void setShouldScrollOnMainThread(bool); 146 150 void setHaveWheelEventHandlers(bool); … … 148 152 void setNonFastScrollableRegion(const Region&); 149 153 void setNonFastScrollableRegionChanged() { m_nonFastScrollableRegionChanged = true; } 154 virtual void scrollBy(const IntSize&) { } 150 155 151 156 void setDrawCheckerboardForMissingTiles(bool); … … 304 309 IntRect m_visibleLayerRect; 305 310 IntPoint m_scrollPosition; 311 IntSize m_maxScrollPosition; 306 312 bool m_scrollable; 307 313 bool m_shouldScrollOnMainThread; -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
r114081 r114651 161 161 } 162 162 163 CCInputHandlerClient::ScrollStatus CCLayerImpl::tryScroll(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type) const 164 { 165 if (shouldScrollOnMainThread()) { 166 TRACE_EVENT("tryScroll Failed shouldScrollOnMainThread", this, 0); 167 return CCInputHandlerClient::ScrollFailed; 168 } 169 170 if (!screenSpaceTransform().isInvertible()) { 171 TRACE_EVENT("tryScroll Failed nonInvertibleTransform", this, 0); 172 return CCInputHandlerClient::ScrollIgnored; 173 } 174 175 IntPoint contentPoint(screenSpaceTransform().inverse().mapPoint(viewportPoint)); 176 if (nonFastScrollableRegion().contains(contentPoint)) { 177 TRACE_EVENT("tryScroll Failed nonFastScrollableRegion", this, 0); 178 return CCInputHandlerClient::ScrollFailed; 179 } 180 181 if (type == CCInputHandlerClient::Wheel && haveWheelEventHandlers()) { 182 TRACE_EVENT("tryScroll Failed wheelEventHandlers", this, 0); 183 return CCInputHandlerClient::ScrollFailed; 184 } 185 186 if (!scrollable()) { 187 TRACE_EVENT("tryScroll Ignored not scrollable", this, 0); 188 return CCInputHandlerClient::ScrollIgnored; 189 } 190 191 return CCInputHandlerClient::ScrollStarted; 192 } 193 163 194 const IntRect CCLayerImpl::getDrawRect() const 164 195 { -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
r114284 r114651 34 34 #include "TextStream.h" 35 35 #include "TransformationMatrix.h" 36 #include "cc/CCInputHandler.h" 36 37 #include "cc/CCLayerAnimationController.h" 37 38 #include "cc/CCRenderSurface.h" … … 200 201 void setDrawCheckerboardForMissingTiles(bool checkerboard) { m_drawCheckerboardForMissingTiles = checkerboard; } 201 202 bool drawCheckerboardForMissingTiles() const { return m_drawCheckerboardForMissingTiles; } 203 204 CCInputHandlerClient::ScrollStatus tryScroll(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType) const; 202 205 203 206 const IntRect& visibleLayerRect() const { return m_visibleLayerRect; } -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
r114601 r114651 572 572 } 573 573 574 static LayerChromium* findFirstScrollableLayer(LayerChromium* layer) 575 { 576 if (!layer) 577 return 0; 578 579 if (layer->scrollable()) 580 return layer; 581 582 for (size_t i = 0; i < layer->children().size(); ++i) { 583 LayerChromium* found = findFirstScrollableLayer(layer->children()[i].get()); 584 if (found) 585 return found; 586 } 587 588 return 0; 589 } 590 574 591 void CCLayerTreeHost::applyScrollAndScale(const CCScrollAndScaleSet& info) 575 592 { 576 // FIXME: pushing scroll offsets to non-root layers not implemented 577 if (!info.scrolls.size()) 578 return; 579 580 ASSERT(info.scrolls.size() == 1); 581 IntSize scrollDelta = info.scrolls[0].scrollDelta; 582 m_client->applyScrollAndScale(scrollDelta, info.pageScaleDelta); 593 if (!m_rootLayer) 594 return; 595 596 LayerChromium* rootScrollLayer = findFirstScrollableLayer(m_rootLayer.get()); 597 IntSize rootScrollDelta; 598 599 for (size_t i = 0; i < info.scrolls.size(); ++i) { 600 LayerChromium* layer = CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayer.get(), info.scrolls[i].layerId); 601 if (!layer) 602 continue; 603 if (layer == rootScrollLayer) 604 rootScrollDelta += info.scrolls[i].scrollDelta; 605 else 606 layer->scrollBy(info.scrolls[i].scrollDelta); 607 } 608 if (!rootScrollDelta.isZero() || info.pageScaleDelta != 1) 609 m_client->applyScrollAndScale(rootScrollDelta, info.pageScaleDelta); 583 610 } 584 611 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h
r113602 r114651 47 47 template<typename LayerType> static bool renderSurfaceContributesToTarget(LayerType*, int targetSurfaceLayerID); 48 48 49 // Returns a layer with the given id if one exists in the subtree starting 50 // from the given root layer (including mask and replica layers). 51 template<typename LayerType> static LayerType* findLayerInSubtree(LayerType* rootLayer, int layerId); 52 49 53 struct ScrollUpdateInfo { 50 54 int layerId; … … 72 76 } 73 77 78 template<typename LayerType> 79 LayerType* CCLayerTreeHostCommon::findLayerInSubtree(LayerType* rootLayer, int layerId) 80 { 81 if (rootLayer->id() == layerId) 82 return rootLayer; 83 84 if (rootLayer->maskLayer() && rootLayer->maskLayer()->id() == layerId) 85 return rootLayer->maskLayer(); 86 87 if (rootLayer->replicaLayer() && rootLayer->replicaLayer()->id() == layerId) 88 return rootLayer->replicaLayer(); 89 90 for (size_t i = 0; i < rootLayer->children().size(); ++i) { 91 if (LayerType* found = findLayerInSubtree(rootLayer->children()[i].get(), layerId)) 92 return found; 93 } 94 return 0; 95 } 96 74 97 } // namespace WebCore 75 98 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
r114601 r114651 105 105 , m_sourceFrameNumber(-1) 106 106 , m_frameNumber(0) 107 , m_scrollLayerImpl(0) 107 , m_rootScrollLayerImpl(0) 108 , m_currentlyScrollingLayerImpl(0) 108 109 , m_settings(settings) 109 110 , m_visible(true) … … 165 166 void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTime, double duration) 166 167 { 167 if (!m_ scrollLayerImpl)168 return; 169 170 IntSize scrollTotal = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());168 if (!m_rootScrollLayerImpl) 169 return; 170 171 IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 171 172 scrollTotal.scale(m_pageScaleDelta); 172 173 float scaleTotal = m_pageScale * m_pageScaleDelta; … … 358 359 // TODO(aelias): Hardcoding the first child here is weird. Think of 359 360 // a cleaner way to get the contentBounds on the Impl side. 360 if (!m_ scrollLayerImpl || m_scrollLayerImpl->children().isEmpty())361 if (!m_rootScrollLayerImpl || m_rootScrollLayerImpl->children().isEmpty()) 361 362 return IntSize(); 362 return m_ scrollLayerImpl->children()[0]->contentBounds();363 return m_rootScrollLayerImpl->children()[0]->contentBounds(); 363 364 } 364 365 … … 369 370 frame.renderPasses.clear(); 370 371 frame.renderSurfaceLayerList.clear(); 372 m_mostRecentRenderSurfaceLayerList.clear(); 371 373 372 374 if (!m_rootLayerImpl) … … 375 377 if (!calculateRenderPasses(frame.renderPasses, frame.renderSurfaceLayerList)) 376 378 return false; 379 380 m_mostRecentRenderSurfaceLayerList = frame.renderSurfaceLayerList; 377 381 378 382 // If we return true, then we expect drawLayers() to be called before this function is called again. … … 460 464 } 461 465 462 static CCLayerImpl* find ScrollLayer(CCLayerImpl* layer)466 static CCLayerImpl* findRootScrollLayer(CCLayerImpl* layer) 463 467 { 464 468 if (!layer) … … 469 473 470 474 for (size_t i = 0; i < layer->children().size(); ++i) { 471 CCLayerImpl* found = find ScrollLayer(layer->children()[i].get());475 CCLayerImpl* found = findRootScrollLayer(layer->children()[i].get()); 472 476 if (found) 473 477 return found; … … 477 481 } 478 482 483 // Content layers can be either directly scrollable or contained in an outer 484 // scrolling layer which applies the scroll transform. Given a content layer, 485 // this function returns the associated scroll layer if any. 486 static CCLayerImpl* findScrollLayerForContentLayer(CCLayerImpl* layerImpl) 487 { 488 if (!layerImpl) 489 return 0; 490 491 if (layerImpl->scrollable()) 492 return layerImpl; 493 494 if (layerImpl->drawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable()) 495 return layerImpl->parent(); 496 497 return 0; 498 } 499 479 500 void CCLayerTreeHostImpl::setRootLayer(PassOwnPtr<CCLayerImpl> layer) 480 501 { 481 502 m_rootLayerImpl = layer; 482 483 // FIXME: Currently, this only finds the first scrollable layer. 484 m_scrollLayerImpl = findScrollLayer(m_rootLayerImpl.get()); 503 m_rootScrollLayerImpl = findRootScrollLayer(m_rootLayerImpl.get()); 504 505 if (!m_currentlyScrollingLayerImpl) 506 return; 507 508 if (m_rootLayerImpl && CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayerImpl.get(), m_currentlyScrollingLayerImpl->id())) 509 return; 510 511 m_currentlyScrollingLayerImpl = 0; 512 } 513 514 PassOwnPtr<CCLayerImpl> CCLayerTreeHostImpl::releaseRootLayer() 515 { 516 m_mostRecentRenderSurfaceLayerList.clear(); 517 return m_rootLayerImpl.release(); 485 518 } 486 519 … … 533 566 } 534 567 568 static void adjustScrollsForPageScaleChange(CCLayerImpl* layerImpl, float pageScaleChange) 569 { 570 if (!layerImpl) 571 return; 572 573 if (layerImpl->scrollable()) { 574 // We need to convert impl-side scroll deltas to pageScale space. 575 FloatSize scrollDelta = layerImpl->scrollDelta(); 576 scrollDelta.scale(pageScaleChange); 577 layerImpl->setScrollDelta(scrollDelta); 578 } 579 580 for (size_t i = 0; i < layerImpl->children().size(); ++i) 581 adjustScrollsForPageScaleChange(layerImpl->children()[i].get(), pageScaleChange); 582 } 583 584 static void applyPageScaleDeltaToScrollLayers(CCLayerImpl* layerImpl, float pageScaleDelta) 585 { 586 if (!layerImpl) 587 return; 588 589 if (layerImpl->scrollable()) 590 layerImpl->setPageScaleDelta(pageScaleDelta); 591 592 for (size_t i = 0; i < layerImpl->children().size(); ++i) 593 applyPageScaleDeltaToScrollLayers(layerImpl->children()[i].get(), pageScaleDelta); 594 } 595 535 596 void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale) 536 597 { … … 547 608 m_pageScale = pageScale; 548 609 549 adjustScrollsForPageScaleChange(pageScaleChange); 610 if (pageScaleChange != 1) 611 adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange); 550 612 551 613 // Clamp delta to limits and refresh display matrix. 552 614 setPageScaleDelta(m_pageScaleDelta / m_sentPageScaleDelta); 553 615 m_sentPageScaleDelta = 1; 554 applyPageScaleDeltaToScrollLayer(); 555 } 556 557 void CCLayerTreeHostImpl::adjustScrollsForPageScaleChange(float pageScaleChange) 558 { 559 if (pageScaleChange == 1) 560 return; 561 562 // We also need to convert impl-side scroll deltas to pageScale space. 563 if (m_scrollLayerImpl) { 564 FloatSize scrollDelta = m_scrollLayerImpl->scrollDelta(); 565 scrollDelta.scale(pageScaleChange); 566 m_scrollLayerImpl->setScrollDelta(scrollDelta); 567 } 616 applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); 568 617 } 569 618 … … 583 632 584 633 updateMaxScrollPosition(); 585 applyPageScaleDeltaToScrollLayer(); 586 } 587 588 void CCLayerTreeHostImpl::applyPageScaleDeltaToScrollLayer() 589 { 590 if (m_scrollLayerImpl) 591 m_scrollLayerImpl->setPageScaleDelta(m_pageScaleDelta); 634 applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); 592 635 } 593 636 594 637 void CCLayerTreeHostImpl::updateMaxScrollPosition() 595 638 { 596 if (!m_ scrollLayerImpl || !m_scrollLayerImpl->children().size())639 if (!m_rootScrollLayerImpl || !m_rootScrollLayerImpl->children().size()) 597 640 return; 598 641 599 642 FloatSize viewBounds = m_viewportSize; 600 if (CCLayerImpl* clipLayer = m_ scrollLayerImpl->parent()) {643 if (CCLayerImpl* clipLayer = m_rootScrollLayerImpl->parent()) { 601 644 if (clipLayer->masksToBounds()) 602 645 viewBounds = clipLayer->bounds(); … … 609 652 maxScroll.clampNegativeToZero(); 610 653 611 m_scrollLayerImpl->setMaxScrollPosition(maxScroll); 612 613 // TODO(aelias): Also update sublayers. 654 m_rootScrollLayerImpl->setMaxScrollPosition(maxScroll); 614 655 } 615 656 … … 619 660 } 620 661 662 bool CCLayerTreeHostImpl::ensureMostRecentRenderSurfaceLayerList() 663 { 664 if (m_mostRecentRenderSurfaceLayerList.size()) 665 return true; 666 667 // If we are called after setRootLayer() but before prepareToDraw(), we need to recalculate 668 // the visible layers. The return value is ignored because we don't care about checkerboarding. 669 CCRenderPassList passes; 670 calculateRenderPasses(passes, m_mostRecentRenderSurfaceLayerList); 671 672 return m_mostRecentRenderSurfaceLayerList.size(); 673 } 674 621 675 CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type) 622 676 { 623 // TODO: Check for scrollable sublayers. 624 if (!m_scrollLayerImpl || !m_scrollLayerImpl->scrollable()) { 625 TRACE_EVENT("scrollBegin Ignored no scrollable", this, 0); 677 TRACE_EVENT("CCLayerTreeHostImpl::scrollBegin", this, 0); 678 679 m_currentlyScrollingLayerImpl = 0; 680 681 if (!ensureMostRecentRenderSurfaceLayerList()) 626 682 return ScrollIgnored; 627 } 628 629 if (m_scrollLayerImpl->shouldScrollOnMainThread()) { 630 TRACE_EVENT("scrollBegin Failed shouldScrollOnMainThread", this, 0); 631 return ScrollFailed; 632 } 633 634 IntPoint scrollLayerContentPoint(m_scrollLayerImpl->screenSpaceTransform().inverse().mapPoint(viewportPoint)); 635 if (m_scrollLayerImpl->nonFastScrollableRegion().contains(scrollLayerContentPoint)) { 636 TRACE_EVENT("scrollBegin Failed nonFastScrollableRegion", this, 0); 637 return ScrollFailed; 638 } 639 640 if (type == CCInputHandlerClient::Wheel && m_scrollLayerImpl->haveWheelEventHandlers()) { 641 TRACE_EVENT("scrollBegin Failed wheelEventHandlers", this, 0); 642 return ScrollFailed; 643 } 644 645 return ScrollStarted; 683 684 // First find out which layer was hit by walking the saved list of visible layers from the most recent frame. 685 CCLayerImpl* layerImpl = 0; 686 typedef CCLayerIterator<CCLayerImpl, CCLayerList, CCRenderSurface, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType; 687 CCLayerIteratorType end = CCLayerIteratorType::end(&m_mostRecentRenderSurfaceLayerList); 688 for (CCLayerIteratorType it = CCLayerIteratorType::begin(&m_mostRecentRenderSurfaceLayerList); it != end; ++it) { 689 CCLayerImpl* renderSurfaceLayerImpl = (*it); 690 if (!renderSurfaceLayerImpl->screenSpaceTransform().isInvertible()) 691 continue; 692 IntPoint contentPoint(renderSurfaceLayerImpl->screenSpaceTransform().inverse().mapPoint(viewportPoint)); 693 if (!renderSurfaceLayerImpl->visibleLayerRect().contains(contentPoint)) 694 continue; 695 layerImpl = renderSurfaceLayerImpl; 696 break; 697 } 698 699 // Walk up the hierarchy and look for a scrollable layer. 700 CCLayerImpl* potentiallyScrollingLayerImpl = 0; 701 for (; layerImpl; layerImpl = layerImpl->parent()) { 702 // The content layer can also block attempts to scroll outside the main thread. 703 if (layerImpl->tryScroll(viewportPoint, type) == ScrollFailed) 704 return ScrollFailed; 705 706 CCLayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl); 707 if (!scrollLayerImpl) 708 continue; 709 710 ScrollStatus status = scrollLayerImpl->tryScroll(viewportPoint, type); 711 712 // If any layer wants to divert the scroll event to the main thread, abort. 713 if (status == ScrollFailed) 714 return ScrollFailed; 715 716 if (status == ScrollStarted && !potentiallyScrollingLayerImpl) 717 potentiallyScrollingLayerImpl = scrollLayerImpl; 718 } 719 720 if (potentiallyScrollingLayerImpl) { 721 m_currentlyScrollingLayerImpl = potentiallyScrollingLayerImpl; 722 return ScrollStarted; 723 } 724 return ScrollIgnored; 646 725 } 647 726 … … 649 728 { 650 729 TRACE_EVENT("CCLayerTreeHostImpl::scrollBy", this, 0); 651 if (!m_scrollLayerImpl) 652 return; 653 654 m_scrollLayerImpl->scrollBy(scrollDelta); 655 m_client->setNeedsCommitOnImplThread(); 656 m_client->setNeedsRedrawOnImplThread(); 730 if (!m_currentlyScrollingLayerImpl) 731 return; 732 733 FloatSize pendingDelta(scrollDelta); 734 pendingDelta.scale(1 / m_pageScaleDelta); 735 736 for (CCLayerImpl* layerImpl = m_currentlyScrollingLayerImpl; layerImpl && !pendingDelta.isZero(); layerImpl = layerImpl->parent()) { 737 if (!layerImpl->scrollable()) 738 continue; 739 FloatSize previousDelta(layerImpl->scrollDelta()); 740 layerImpl->scrollBy(pendingDelta); 741 // Reset the pending scroll delta to zero if the layer was able to move along the requested 742 // axis. This is to ensure it is possible to scroll exactly to the beginning or end of a 743 // scroll area regardless of the scroll step. For diagonal scrolls this also avoids applying 744 // the scroll on one axis to multiple layers. 745 if (previousDelta.width() != layerImpl->scrollDelta().width()) 746 pendingDelta.setWidth(0); 747 if (previousDelta.height() != layerImpl->scrollDelta().height()) 748 pendingDelta.setHeight(0); 749 } 750 751 if (pendingDelta != scrollDelta) { 752 m_client->setNeedsCommitOnImplThread(); 753 m_client->setNeedsRedrawOnImplThread(); 754 } 657 755 } 658 756 659 757 void CCLayerTreeHostImpl::scrollEnd() 660 758 { 759 m_currentlyScrollingLayerImpl = 0; 661 760 } 662 761 … … 672 771 TRACE_EVENT("CCLayerTreeHostImpl::pinchGestureUpdate", this, 0); 673 772 674 if (!m_ scrollLayerImpl)773 if (!m_rootScrollLayerImpl) 675 774 return; 676 775 … … 687 786 m_previousPinchAnchor = anchor; 688 787 689 m_ scrollLayerImpl->scrollBy(roundedIntSize(move));788 m_rootScrollLayerImpl->scrollBy(roundedIntSize(move)); 690 789 m_client->setNeedsCommitOnImplThread(); 691 790 m_client->setNeedsRedrawOnImplThread(); … … 709 808 void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo) 710 809 { 711 if (!m_ scrollLayerImpl)810 if (!m_rootScrollLayerImpl) 712 811 return; 713 812 … … 721 820 // Compute where the scroll offset/page scale would be if fully pinch-zoomed 722 821 // out from the anchor point. 723 IntSize scrollBegin = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());822 IntSize scrollBegin = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 724 823 scrollBegin.scale(m_pageScaleDelta); 725 824 float scaleBegin = m_pageScale * m_pageScaleDelta; … … 740 839 void CCLayerTreeHostImpl::makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale) 741 840 { 742 if (!m_ scrollLayerImpl)841 if (!m_rootScrollLayerImpl) 743 842 return; 744 843 745 844 CCLayerTreeHostCommon::ScrollUpdateInfo scroll; 746 scroll.layerId = m_ scrollLayerImpl->id();747 scroll.scrollDelta = scrollOffset - toSize(m_ scrollLayerImpl->scrollPosition());845 scroll.layerId = m_rootScrollLayerImpl->id(); 846 scroll.scrollDelta = scrollOffset - toSize(m_rootScrollLayerImpl->scrollPosition()); 748 847 scrollInfo->scrolls.append(scroll); 749 m_ scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);848 m_rootScrollLayerImpl->setSentScrollDelta(scroll.scrollDelta); 750 849 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = pageScale / m_pageScale; 751 850 } 752 851 852 static void collectScrollDeltas(CCScrollAndScaleSet* scrollInfo, CCLayerImpl* layerImpl) 853 { 854 if (!layerImpl) 855 return; 856 857 if (!layerImpl->scrollDelta().isZero()) { 858 IntSize scrollDelta = flooredIntSize(layerImpl->scrollDelta()); 859 CCLayerTreeHostCommon::ScrollUpdateInfo scroll; 860 scroll.layerId = layerImpl->id(); 861 scroll.scrollDelta = scrollDelta; 862 scrollInfo->scrolls.append(scroll); 863 layerImpl->setSentScrollDelta(scrollDelta); 864 } 865 866 for (size_t i = 0; i < layerImpl->children().size(); ++i) 867 collectScrollDeltas(scrollInfo, layerImpl->children()[i].get()); 868 } 869 753 870 PassOwnPtr<CCScrollAndScaleSet> CCLayerTreeHostImpl::processScrollDeltas() 754 871 { 755 872 OwnPtr<CCScrollAndScaleSet> scrollInfo = adoptPtr(new CCScrollAndScaleSet()); 756 bool didMove = m_scrollLayerImpl && (!m_scrollLayerImpl->scrollDelta().isZero() || m_pageScaleDelta != 1.0f); 873 collectScrollDeltas(scrollInfo.get(), m_rootLayerImpl.get()); 874 875 bool didMove = scrollInfo->scrolls.size() || m_pageScaleDelta != 1; 757 876 if (!didMove || m_pinchGestureActive || m_pageScaleAnimation) { 758 877 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = 1; … … 766 885 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = m_pageScaleDelta; 767 886 768 // FIXME: track scrolls from layers other than the root769 CCLayerTreeHostCommon::ScrollUpdateInfo scroll;770 scroll.layerId = m_scrollLayerImpl->id();771 scroll.scrollDelta = flooredIntSize(m_scrollLayerImpl->scrollDelta());772 scrollInfo->scrolls.append(scroll);773 774 m_scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);775 776 887 return scrollInfo.release(); 777 888 } … … 788 899 void CCLayerTreeHostImpl::animatePageScale(double monotonicTime) 789 900 { 790 if (!m_pageScaleAnimation || !m_ scrollLayerImpl)791 return; 792 793 IntSize scrollTotal = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());901 if (!m_pageScaleAnimation || !m_rootScrollLayerImpl) 902 return; 903 904 IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 794 905 795 906 setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScale); 796 907 IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime); 797 908 nextScroll.scale(1 / m_pageScaleDelta); 798 m_ scrollLayerImpl->scrollBy(nextScroll - scrollTotal);909 m_rootScrollLayerImpl->scrollBy(nextScroll - scrollTotal); 799 910 m_client->setNeedsRedrawOnImplThread(); 800 911 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
r114218 r114651 123 123 124 124 void setRootLayer(PassOwnPtr<CCLayerImpl>); 125 PassOwnPtr<CCLayerImpl> releaseRootLayer() { return m_rootLayerImpl.release(); }125 PassOwnPtr<CCLayerImpl> releaseRootLayer(); 126 126 CCLayerImpl* rootLayer() { return m_rootLayerImpl.get(); } 127 127 128 CCLayerImpl* scrollLayer() const { return m_scrollLayerImpl; }128 CCLayerImpl* rootScrollLayer() const { return m_rootScrollLayerImpl; } 129 129 130 130 bool visible() const { return m_visible; } … … 170 170 171 171 void setPageScaleDelta(float); 172 void applyPageScaleDeltaToScrollLayer();173 void adjustScrollsForPageScaleChange(float);174 172 void updateMaxScrollPosition(); 175 173 void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList); … … 180 178 void sendDidLoseContextRecursive(CCLayerImpl*); 181 179 void clearRenderSurfacesOnCCLayerImplRecursive(CCLayerImpl*); 180 bool ensureMostRecentRenderSurfaceLayerList(); 182 181 183 182 void dumpRenderSurfaces(TextStream&, int indent, const CCLayerImpl*) const; … … 185 184 OwnPtr<LayerRendererChromium> m_layerRenderer; 186 185 OwnPtr<CCLayerImpl> m_rootLayerImpl; 187 CCLayerImpl* m_scrollLayerImpl; 186 CCLayerImpl* m_rootScrollLayerImpl; 187 CCLayerImpl* m_currentlyScrollingLayerImpl; 188 188 CCSettings m_settings; 189 189 IntSize m_viewportSize; … … 212 212 CCLayerSorter m_layerSorter; 213 213 214 // List of visible layers in the most recent frame. Used for input event hit testing. 215 CCLayerList m_mostRecentRenderSurfaceLayerList; 216 214 217 FloatRect m_rootDamageRect; 215 218 }; -
trunk/Source/WebKit/chromium/ChangeLog
r114647 r114651 1 2012-04-19 Sami Kyostila <skyostil@chromium.org> 2 3 [chromium] Add tests for scrolling non-root layers in the compositor thread 4 https://bugs.webkit.org/show_bug.cgi?id=73350 5 6 Reviewed by James Robinson. 7 8 * src/WebContentLayerImpl.cpp: 9 (WebKit::WebContentLayerImpl::didScroll): 10 (WebKit): 11 * src/WebContentLayerImpl.h: 12 (WebContentLayerImpl): 13 * tests/CCLayerImplTest.cpp: 14 (WebCore::TEST): 15 (WebCore): 16 * tests/CCLayerTreeHostImplTest.cpp: 17 (WebKitTests::CCLayerTreeHostImplTest::createScrollableLayer): 18 (CCLayerTreeHostImplTest): 19 (WebKitTests::CCLayerTreeHostImplTest::initializeLayerRendererAndDrawFrame): 20 (WebKitTests::TEST_F): 21 (WebKitTests): 22 * tests/CCLayerTreeHostTest.cpp: 23 (WTF::TestOpacityChangeLayerDelegate::didScroll): 24 (WTF::MockContentLayerDelegate::paintContents): 25 (WTF::MockContentLayerDelegate::didScroll): 26 (CCLayerTreeHostTestScrollChildLayer): 27 (WTF::CCLayerTreeHostTestScrollChildLayer::CCLayerTreeHostTestScrollChildLayer): 28 (WTF::CCLayerTreeHostTestScrollChildLayer::beginTest): 29 (WTF::CCLayerTreeHostTestScrollChildLayer::applyScrollAndScale): 30 (WTF::CCLayerTreeHostTestScrollChildLayer::beginCommitOnCCThread): 31 (WTF::CCLayerTreeHostTestScrollChildLayer::drawLayersOnCCThread): 32 (WTF::CCLayerTreeHostTestScrollChildLayer::afterTest): 33 (WTF): 34 (WTF::TEST_F): 35 1 36 2012-04-19 Alec Flett <alecflett@chromium.org> 2 37 -
trunk/Source/WebKit/chromium/src/WebContentLayerImpl.cpp
r105460 r114651 73 73 } 74 74 75 void WebContentLayerImpl::didScroll(const WebCore::IntSize&) 76 { 77 } 78 75 79 } // namespace WebKit -
trunk/Source/WebKit/chromium/src/WebContentLayerImpl.h
r105460 r114651 45 45 // ContentLayerDelegate implementation. 46 46 virtual void paintContents(WebCore::GraphicsContext&, const WebCore::IntRect& clip); 47 virtual void didScroll(const WebCore::IntSize&); 47 48 48 49 WebContentLayerClient* m_contentClient; -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
r113947 r114651 1326 1326 } 1327 1327 1328 TEST(CCLayerTreeHostCommonTest, verifySubtreeSearch) 1329 { 1330 RefPtr<LayerChromium> root = LayerChromium::create(); 1331 RefPtr<LayerChromium> child = LayerChromium::create(); 1332 RefPtr<LayerChromium> grandChild = LayerChromium::create(); 1333 RefPtr<LayerChromium> maskLayer = LayerChromium::create(); 1334 RefPtr<LayerChromium> replicaLayer = LayerChromium::create(); 1335 1336 grandChild->setReplicaLayer(replicaLayer.get()); 1337 child->addChild(grandChild.get()); 1338 child->setMaskLayer(maskLayer.get()); 1339 root->addChild(child.get()); 1340 1341 int nonexistentId = -1; 1342 EXPECT_EQ(root, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), root->id())); 1343 EXPECT_EQ(child, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), child->id())); 1344 EXPECT_EQ(grandChild, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), grandChild->id())); 1345 EXPECT_EQ(maskLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), maskLayer->id())); 1346 EXPECT_EQ(replicaLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), replicaLayer->id())); 1347 EXPECT_EQ(0, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), nonexistentId)); 1348 } 1349 1328 1350 // FIXME: 1329 1351 // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942 -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
r114473 r114651 98 98 } 99 99 100 static PassOwnPtr<CCLayerImpl> createScrollableLayer(int id, const FloatPoint& position, const IntSize& size) 101 { 102 OwnPtr<CCLayerImpl> layer = CCLayerImpl::create(id); 103 layer->setScrollable(true); 104 layer->setDrawsContent(true); 105 layer->setPosition(position); 106 layer->setBounds(size); 107 layer->setMaxScrollPosition(IntSize(size.width() * 2, size.height() * 2)); 108 return layer.release(); 109 } 110 111 void initializeLayerRendererAndDrawFrame() 112 { 113 m_hostImpl->initializeLayerRenderer(createContext()); 114 CCLayerTreeHostImpl::FrameData frame; 115 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); 116 m_hostImpl->drawLayers(frame); 117 } 118 100 119 protected: 101 120 PassRefPtr<GraphicsContext3D> createContext() … … 181 200 { 182 201 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 202 root->setVisibleLayerRect(IntRect(0, 0, 100, 100)); 183 203 root->setScrollable(true); 184 204 root->setScrollPosition(IntPoint(0, 0)); 185 205 root->setMaxScrollPosition(IntSize(100, 100)); 186 206 m_hostImpl->setRootLayer(root.release()); 207 initializeLayerRendererAndDrawFrame(); 187 208 } 188 209 … … 198 219 { 199 220 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 221 root->setVisibleLayerRect(IntRect(0, 0, 100, 100)); 200 222 root->setScrollable(true); 201 223 root->setScrollPosition(IntPoint(0, 0)); 202 224 root->setMaxScrollPosition(IntSize(100, 100)); 203 225 m_hostImpl->setRootLayer(root.release()); 226 initializeLayerRendererAndDrawFrame(); 204 227 } 205 228 CCLayerImpl* root = m_hostImpl->rootLayer(); … … 216 239 { 217 240 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 241 root->setVisibleLayerRect(IntRect(0, 0, 100, 100)); 218 242 root->setScrollable(true); 219 243 root->setScrollPosition(IntPoint(0, 0)); … … 221 245 root->setShouldScrollOnMainThread(true); 222 246 m_hostImpl->setRootLayer(root.release()); 247 initializeLayerRendererAndDrawFrame(); 248 223 249 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollFailed); 224 250 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Gesture), CCInputHandlerClient::ScrollFailed); … … 228 254 { 229 255 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 256 root->setVisibleLayerRect(IntRect(0, 0, 100, 100)); 230 257 root->setScrollable(true); 231 258 root->setScrollPosition(IntPoint(0, 0)); … … 233 260 root->setNonFastScrollableRegion(IntRect(0, 0, 50, 50)); 234 261 m_hostImpl->setRootLayer(root.release()); 262 initializeLayerRendererAndDrawFrame(); 263 235 264 // All scroll types inside the non-fast scrollable region should fail. 236 265 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollFailed); … … 248 277 TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionWithOffset) 249 278 { 250 m_hostImpl->initializeLayerRenderer(createContext());251 252 279 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 280 root->setBounds(IntSize(1, 1)); 281 root->setVisibleLayerRect(IntRect(0, 0, 100, 100)); 253 282 root->setScrollable(true); 254 283 root->setScrollPosition(IntPoint(0, 0)); … … 257 286 root->setPosition(FloatPoint(-25, 0)); 258 287 m_hostImpl->setRootLayer(root.release()); 259 CCLayerTreeHostImpl::FrameData frame; 260 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); 261 m_hostImpl->drawLayers(frame); // Update draw transforms so we can correctly map points into layer space. 288 initializeLayerRendererAndDrawFrame(); 262 289 263 290 // This point would fall into the non-fast scrollable region except that we've moved the layer down by 25 pixels. … … 274 301 setupScrollAndContentsLayers(IntSize(100, 100)); 275 302 m_hostImpl->setViewportSize(IntSize(50, 50)); 276 277 CCLayerImpl* scrollLayer = m_hostImpl->scrollLayer(); 303 initializeLayerRendererAndDrawFrame(); 304 305 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 278 306 ASSERT(scrollLayer); 279 307 … … 354 382 setupScrollAndContentsLayers(IntSize(100, 100)); 355 383 m_hostImpl->setViewportSize(IntSize(50, 50)); 356 357 CCLayerImpl* scrollLayer = m_hostImpl->scrollLayer(); 384 initializeLayerRendererAndDrawFrame(); 385 386 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 358 387 ASSERT(scrollLayer); 359 388 … … 560 589 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); 561 590 m_hostImpl->drawLayers(frame); 591 } 592 593 TEST_F(CCLayerTreeHostImplTest, scrollRootIgnored) 594 { 595 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 596 root->setScrollable(false); 597 m_hostImpl->setRootLayer(root.release()); 598 initializeLayerRendererAndDrawFrame(); 599 600 // Scroll event is ignored because layer is not scrollable. 601 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 602 EXPECT_FALSE(m_didRequestRedraw); 603 EXPECT_FALSE(m_didRequestCommit); 604 } 605 606 TEST_F(CCLayerTreeHostImplTest, scrollNonCompositedRoot) 607 { 608 // Test the configuration where a non-composited root layer is embedded in a 609 // scrollable outer layer. 610 IntSize surfaceSize(10, 10); 611 612 OwnPtr<CCLayerImpl> contentLayer = CCLayerImpl::create(1); 613 contentLayer->setIsNonCompositedContent(true); 614 contentLayer->setDrawsContent(true); 615 contentLayer->setPosition(IntPoint(5, 5)); 616 contentLayer->setBounds(surfaceSize); 617 contentLayer->setContentBounds(IntSize(surfaceSize.width() * 2, surfaceSize.height() * 2)); 618 619 OwnPtr<CCLayerImpl> scrollLayer = CCLayerImpl::create(0); 620 scrollLayer->setScrollable(true); 621 scrollLayer->addChild(contentLayer.release()); 622 623 m_hostImpl->setRootLayer(scrollLayer.release()); 624 m_hostImpl->setViewportSize(surfaceSize); 625 initializeLayerRendererAndDrawFrame(); 626 627 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 628 m_hostImpl->scrollBy(IntSize(0, 10)); 629 m_hostImpl->scrollEnd(); 630 EXPECT_TRUE(m_didRequestRedraw); 631 EXPECT_TRUE(m_didRequestCommit); 632 } 633 634 TEST_F(CCLayerTreeHostImplTest, scrollChildCallsCommitAndRedraw) 635 { 636 IntSize surfaceSize(10, 10); 637 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 638 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 639 m_hostImpl->setRootLayer(root.release()); 640 m_hostImpl->setViewportSize(surfaceSize); 641 initializeLayerRendererAndDrawFrame(); 642 643 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 644 m_hostImpl->scrollBy(IntSize(0, 10)); 645 m_hostImpl->scrollEnd(); 646 EXPECT_TRUE(m_didRequestRedraw); 647 EXPECT_TRUE(m_didRequestCommit); 648 } 649 650 TEST_F(CCLayerTreeHostImplTest, scrollMissesChild) 651 { 652 IntSize surfaceSize(10, 10); 653 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 654 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 655 m_hostImpl->setRootLayer(root.release()); 656 m_hostImpl->setViewportSize(surfaceSize); 657 initializeLayerRendererAndDrawFrame(); 658 659 // Scroll event is ignored because the input coordinate is outside the layer boundaries. 660 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(15, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 661 EXPECT_FALSE(m_didRequestRedraw); 662 EXPECT_FALSE(m_didRequestCommit); 663 } 664 665 TEST_F(CCLayerTreeHostImplTest, scrollMissesBackfacingChild) 666 { 667 IntSize surfaceSize(10, 10); 668 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 669 OwnPtr<CCLayerImpl> child = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 670 m_hostImpl->setViewportSize(surfaceSize); 671 672 TransformationMatrix matrix; 673 matrix.rotate3d(180, 0, 0); 674 child->setTransform(matrix); 675 child->setDoubleSided(false); 676 677 root->addChild(child.release()); 678 m_hostImpl->setRootLayer(root.release()); 679 initializeLayerRendererAndDrawFrame(); 680 681 // Scroll event is ignored because the scrollable layer is not facing the viewer and there is 682 // nothing scrollable behind it. 683 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 684 EXPECT_FALSE(m_didRequestRedraw); 685 EXPECT_FALSE(m_didRequestCommit); 686 } 687 688 TEST_F(CCLayerTreeHostImplTest, scrollBlockedByContentLayer) 689 { 690 IntSize surfaceSize(10, 10); 691 OwnPtr<CCLayerImpl> contentLayer = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 692 contentLayer->setShouldScrollOnMainThread(true); 693 contentLayer->setScrollable(false); 694 695 OwnPtr<CCLayerImpl> scrollLayer = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 696 scrollLayer->addChild(contentLayer.release()); 697 698 m_hostImpl->setRootLayer(scrollLayer.release()); 699 m_hostImpl->setViewportSize(surfaceSize); 700 initializeLayerRendererAndDrawFrame(); 701 702 // Scrolling fails because the content layer is asking to be scrolled on the main thread. 703 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollFailed); 704 } 705 706 TEST_F(CCLayerTreeHostImplTest, scrollRootAndChangePageScaleOnMainThread) 707 { 708 IntSize surfaceSize(10, 10); 709 float pageScale = 2; 710 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 711 m_hostImpl->setRootLayer(root.release()); 712 m_hostImpl->setViewportSize(surfaceSize); 713 initializeLayerRendererAndDrawFrame(); 714 715 IntSize scrollDelta(0, 10); 716 IntSize expectedScrollDelta(scrollDelta); 717 IntSize expectedMaxScroll(m_hostImpl->rootLayer()->maxScrollPosition()); 718 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 719 m_hostImpl->scrollBy(scrollDelta); 720 m_hostImpl->scrollEnd(); 721 722 // Set new page scale from main thread. 723 m_hostImpl->setPageScaleFactorAndLimits(pageScale, pageScale, pageScale); 724 725 // The scale should apply to the scroll delta. 726 expectedScrollDelta.scale(pageScale); 727 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 728 expectContains(*scrollInfo.get(), 0, expectedScrollDelta); 729 730 // The scroll range should also have been updated. 731 EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), expectedMaxScroll); 732 733 // The page scale delta remains constant because the impl thread did not scale. 734 EXPECT_EQ(m_hostImpl->rootLayer()->pageScaleDelta(), 1); 735 } 736 737 TEST_F(CCLayerTreeHostImplTest, scrollRootAndChangePageScaleOnImplThread) 738 { 739 IntSize surfaceSize(10, 10); 740 float pageScale = 2; 741 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 742 m_hostImpl->setRootLayer(root.release()); 743 m_hostImpl->setViewportSize(surfaceSize); 744 m_hostImpl->setPageScaleFactorAndLimits(1, 1, pageScale); 745 initializeLayerRendererAndDrawFrame(); 746 747 IntSize scrollDelta(0, 10); 748 IntSize expectedScrollDelta(scrollDelta); 749 IntSize expectedMaxScroll(m_hostImpl->rootLayer()->maxScrollPosition()); 750 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 751 m_hostImpl->scrollBy(scrollDelta); 752 m_hostImpl->scrollEnd(); 753 754 // Set new page scale on impl thread by pinching. 755 m_hostImpl->pinchGestureBegin(); 756 m_hostImpl->pinchGestureUpdate(pageScale, IntPoint()); 757 m_hostImpl->pinchGestureEnd(); 758 759 // The scroll delta is not scaled because the main thread did not scale. 760 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 761 expectContains(*scrollInfo.get(), 0, expectedScrollDelta); 762 763 // The scroll range should also have been updated. 764 EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), expectedMaxScroll); 765 766 // The page scale delta should match the new scale on the impl side. 767 EXPECT_EQ(m_hostImpl->rootLayer()->pageScaleDelta(), pageScale); 768 } 769 770 TEST_F(CCLayerTreeHostImplTest, scrollChildAndChangePageScaleOnMainThread) 771 { 772 IntSize surfaceSize(10, 10); 773 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 774 // Also mark the root scrollable so it becomes the root scroll layer. 775 root->setScrollable(true); 776 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 777 m_hostImpl->setRootLayer(root.release()); 778 m_hostImpl->setViewportSize(surfaceSize); 779 initializeLayerRendererAndDrawFrame(); 780 781 CCLayerImpl* child = m_hostImpl->rootLayer()->children()[0].get(); 782 783 IntSize scrollDelta(0, 10); 784 IntSize expectedScrollDelta(scrollDelta); 785 IntSize expectedMaxScroll(child->maxScrollPosition()); 786 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 787 m_hostImpl->scrollBy(scrollDelta); 788 m_hostImpl->scrollEnd(); 789 790 float pageScale = 2; 791 m_hostImpl->setPageScaleFactorAndLimits(pageScale, 1, pageScale); 792 793 // The scale should apply to the scroll delta. 794 expectedScrollDelta.scale(pageScale); 795 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 796 expectContains(*scrollInfo.get(), 1, expectedScrollDelta); 797 798 // The scroll range should not have changed. 799 EXPECT_EQ(child->maxScrollPosition(), expectedMaxScroll); 800 801 // The page scale delta remains constant because the impl thread did not scale. 802 EXPECT_EQ(child->pageScaleDelta(), 1); 803 } 804 805 TEST_F(CCLayerTreeHostImplTest, scrollChildBeyondLimit) 806 { 807 // Scroll a child layer beyond its maximum scroll range and make sure the 808 // parent layer is scrolled on the axis on which the child was unable to 809 // scroll. 810 IntSize surfaceSize(10, 10); 811 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 812 813 OwnPtr<CCLayerImpl> grandChild = createScrollableLayer(2, FloatPoint(5, 5), surfaceSize); 814 grandChild->setScrollPosition(IntPoint(0, 5)); 815 816 OwnPtr<CCLayerImpl> child = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 817 child->setScrollPosition(IntPoint(3, 0)); 818 child->addChild(grandChild.release()); 819 820 root->addChild(child.release()); 821 m_hostImpl->setRootLayer(root.release()); 822 m_hostImpl->setViewportSize(surfaceSize); 823 initializeLayerRendererAndDrawFrame(); 824 { 825 IntSize scrollDelta(-3, -7); 826 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 827 m_hostImpl->scrollBy(scrollDelta); 828 m_hostImpl->scrollEnd(); 829 830 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 831 832 // The grand child should have scrolled up to its limit. 833 CCLayerImpl* child = m_hostImpl->rootLayer()->children()[0].get(); 834 CCLayerImpl* grandChild = child->children()[0].get(); 835 expectContains(*scrollInfo.get(), grandChild->id(), IntSize(0, -5)); 836 837 // The child should have only scrolled on the other axis. 838 expectContains(*scrollInfo.get(), child->id(), IntSize(-3, 0)); 839 } 840 } 841 842 TEST_F(CCLayerTreeHostImplTest, scrollBeforeRedraw) 843 { 844 IntSize surfaceSize(10, 10); 845 m_hostImpl->setRootLayer(createScrollableLayer(0, FloatPoint(5, 5), surfaceSize)); 846 m_hostImpl->setViewportSize(surfaceSize); 847 848 // Draw one frame and then immediately rebuild the layer tree to mimic a tree synchronization. 849 initializeLayerRendererAndDrawFrame(); 850 m_hostImpl->releaseRootLayer(); 851 m_hostImpl->setRootLayer(createScrollableLayer(0, FloatPoint(5, 5), surfaceSize)); 852 853 // Scrolling should still work even though we did not draw yet. 854 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 562 855 } 563 856 -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
r114203 r114651 1418 1418 1419 1419 virtual bool preserves3D() { return false; } 1420 virtual void didScroll(const IntSize&) { } 1420 1421 1421 1422 private: … … 1552 1553 bool drawsContent() const { return true; } 1553 1554 MOCK_CONST_METHOD0(preserves3D, bool()); 1554 void paintContents(GraphicsContext&, const IntRect&) { } 1555 virtual void paintContents(GraphicsContext&, const IntRect&) { } 1556 virtual void didScroll(const IntSize&) { } 1555 1557 void notifySyncRequired() { } 1556 1558 }; … … 2314 2316 } 2315 2317 2318 class CCLayerTreeHostTestScrollChildLayer : public CCLayerTreeHostTest { 2319 public: 2320 CCLayerTreeHostTestScrollChildLayer() 2321 : m_scrollAmount(2, 1) 2322 { 2323 } 2324 2325 virtual void beginTest() 2326 { 2327 m_layerTreeHost->setViewportSize(IntSize(10, 10)); 2328 m_rootScrollLayer = ContentLayerChromium::create(&m_mockDelegate); 2329 m_rootScrollLayer->setBounds(IntSize(10, 10)); 2330 m_rootScrollLayer->setIsDrawable(true); 2331 m_rootScrollLayer->setScrollable(true); 2332 m_rootScrollLayer->setMaxScrollPosition(IntSize(100, 100)); 2333 m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer); 2334 m_childLayer = ContentLayerChromium::create(&m_mockDelegate); 2335 m_childLayer->setBounds(IntSize(50, 50)); 2336 m_childLayer->setIsDrawable(true); 2337 m_childLayer->setScrollable(true); 2338 m_childLayer->setMaxScrollPosition(IntSize(100, 100)); 2339 m_rootScrollLayer->addChild(m_childLayer); 2340 postSetNeedsCommitToMainThread(); 2341 } 2342 2343 virtual void applyScrollAndScale(const IntSize& scrollDelta, float) 2344 { 2345 IntPoint position = m_rootScrollLayer->scrollPosition(); 2346 m_rootScrollLayer->setScrollPosition(position + scrollDelta); 2347 } 2348 2349 virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl) 2350 { 2351 EXPECT_EQ(m_rootScrollLayer->scrollPosition(), IntPoint()); 2352 if (!m_layerTreeHost->frameNumber()) 2353 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint()); 2354 else 2355 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint() + m_scrollAmount); 2356 } 2357 2358 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) 2359 { 2360 if (impl->frameNumber() == 1) { 2361 EXPECT_EQ(impl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 2362 impl->scrollBy(m_scrollAmount); 2363 impl->scrollEnd(); 2364 } else if (impl->frameNumber() == 2) 2365 endTest(); 2366 } 2367 2368 virtual void afterTest() 2369 { 2370 } 2371 2372 private: 2373 const IntSize m_scrollAmount; 2374 MockContentLayerDelegate m_mockDelegate; 2375 RefPtr<LayerChromium> m_childLayer; 2376 RefPtr<LayerChromium> m_rootScrollLayer; 2377 }; 2378 2379 TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread) 2380 { 2381 runTest(true); 2382 } 2383 2316 2384 } // namespace
Note: See TracChangeset
for help on using the changeset viewer.