Changeset 120444 in webkit
- Timestamp:
- Jun 15, 2012 5:45:58 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r120433 r120444 1 2012-06-15 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 Layer hit testing code by Shawn Singh. 16 17 Added new unit tests to verify layer scrolling behavior: 18 19 CCLayerTreeHostCommonTest.verifySubtreeSearch 20 CCLayerTreeHostImplTest.clearRootRenderSurfaceAndScroll 21 CCLayerTreeHostImplTest.inhibitScrollAndPageScaleUpdatesWhileAnimatingPageScale 22 CCLayerTreeHostImplTest.inhibitScrollAndPageScaleUpdatesWhilePinchZooming 23 CCLayerTreeHostImplTest.replaceTreeWhileScrolling 24 CCLayerTreeHostImplTest.scrollBeforeRedraw 25 CCLayerTreeHostImplTest.scrollBlockedByContentLayer 26 CCLayerTreeHostImplTest.scrollChildAndChangePageScaleOnMainThread 27 CCLayerTreeHostImplTest.scrollChildBeyondLimit 28 CCLayerTreeHostImplTest.scrollChildCallsCommitAndRedraw 29 CCLayerTreeHostImplTest.scrollEventBubbling 30 CCLayerTreeHostImplTest.scrollMissesBackfacingChild 31 CCLayerTreeHostImplTest.scrollMissesChild 32 CCLayerTreeHostImplTest.scrollNonCompositedRoot 33 CCLayerTreeHostImplTest.scrollRootAndChangePageScaleOnImplThread 34 CCLayerTreeHostImplTest.scrollRootAndChangePageScaleOnMainThread 35 CCLayerTreeHostImplTest.scrollRootIgnored 36 CCLayerTreeHostImplTest.scrollWithoutRootLayer 37 CCLayerTreeHostTestScrollChildLayer 38 WebCompositorInputHandlerImplTest.gestureScrollOnMainThread 39 40 * platform/graphics/chromium/LayerChromium.cpp: 41 (WebCore::LayerChromium::LayerChromium): 42 (WebCore::LayerChromium::setMaxScrollPosition): 43 (WebCore): 44 (WebCore::LayerChromium::scrollBy): 45 (WebCore::LayerChromium::pushPropertiesTo): 46 * platform/graphics/chromium/LayerChromium.h: 47 (WebCore): 48 (LayerChromiumScrollDelegate): 49 (WebCore::LayerChromiumScrollDelegate::~LayerChromiumScrollDelegate): 50 (LayerChromium): 51 (WebCore::LayerChromium::maxScrollPosition): 52 (WebCore::LayerChromium::scrollable): 53 (WebCore::LayerChromium::setLayerScrollDelegate): 54 * platform/graphics/chromium/cc/CCInputHandler.h: 55 * platform/graphics/chromium/cc/CCLayerImpl.cpp: 56 (WebCore::CCLayerImpl::tryScroll): 57 (WebCore): 58 (WebCore::sortLayers): 59 * platform/graphics/chromium/cc/CCLayerImpl.h: 60 (CCLayerImpl): 61 * platform/graphics/chromium/cc/CCLayerTreeHost.cpp: 62 (WebCore::CCLayerTreeHost::finishCommitOnImplThread): 63 (WebCore::findFirstScrollableLayer): 64 (WebCore): 65 (WebCore::CCLayerTreeHost::applyScrollAndScale): 66 * platform/graphics/chromium/cc/CCLayerTreeHostCommon.h: 67 (CCLayerTreeHostCommon): 68 (WebCore): 69 (WebCore::CCLayerTreeHostCommon::findLayerInSubtree): 70 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp: 71 (WebCore::CCLayerTreeHostImpl::CCLayerTreeHostImpl): 72 (WebCore::CCLayerTreeHostImpl::~CCLayerTreeHostImpl): 73 (WebCore::CCLayerTreeHostImpl::startPageScaleAnimation): 74 (WebCore::CCLayerTreeHostImpl::calculateRenderSurfaceLayerList): 75 (WebCore::CCLayerTreeHostImpl::calculateRenderPasses): 76 (WebCore::CCLayerTreeHostImpl::contentSize): 77 (WebCore::CCLayerTreeHostImpl::prepareToDraw): 78 (WebCore::CCLayerTreeHostImpl::drawLayers): 79 (WebCore::findRootScrollLayer): 80 (WebCore): 81 (WebCore::findScrollLayerForContentLayer): 82 (WebCore::CCLayerTreeHostImpl::setRootLayer): 83 (WebCore::CCLayerTreeHostImpl::detachLayerTree): 84 (WebCore::adjustScrollsForPageScaleChange): 85 (WebCore::applyPageScaleDeltaToScrollLayers): 86 (WebCore::CCLayerTreeHostImpl::setPageScaleFactorAndLimits): 87 (WebCore::CCLayerTreeHostImpl::setPageScaleDelta): 88 (WebCore::CCLayerTreeHostImpl::updateMaxScrollPosition): 89 (WebCore::CCLayerTreeHostImpl::ensureRenderSurfaceLayerList): 90 (WebCore::CCLayerTreeHostImpl::clearCurrentlyScrollingLayer): 91 (WebCore::CCLayerTreeHostImpl::scrollBegin): 92 (WebCore::CCLayerTreeHostImpl::scrollBy): 93 (WebCore::CCLayerTreeHostImpl::scrollEnd): 94 (WebCore::CCLayerTreeHostImpl::pinchGestureUpdate): 95 (WebCore::CCLayerTreeHostImpl::computePinchZoomDeltas): 96 (WebCore::CCLayerTreeHostImpl::makeScrollAndScaleSet): 97 (WebCore::collectScrollDeltas): 98 (WebCore::CCLayerTreeHostImpl::processScrollDeltas): 99 (WebCore::CCLayerTreeHostImpl::animatePageScale): 100 (WebCore::CCLayerTreeHostImpl::animateLayers): 101 (WebCore::CCLayerTreeHostImpl::clearRenderSurfaces): 102 * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h: 103 (FrameData): 104 (CCLayerTreeHostImpl): 105 (WebCore::CCLayerTreeHostImpl::rootScrollLayer): 106 1 107 2012-06-15 Jian Li <jianli@chromium.org> 2 108 -
trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
r120360 r120444 95 95 , m_contentsScale(1.0) 96 96 , m_layerAnimationDelegate(0) 97 , m_layerScrollDelegate(0) 97 98 { 98 99 } … … 396 397 } 397 398 399 void LayerChromium::setMaxScrollPosition(const IntSize& maxScrollPosition) 400 { 401 if (m_maxScrollPosition == maxScrollPosition) 402 return; 403 m_maxScrollPosition = maxScrollPosition; 404 setNeedsCommit(); 405 } 406 398 407 void LayerChromium::setScrollable(bool scrollable) 399 408 { … … 427 436 m_nonFastScrollableRegionChanged = true; 428 437 setNeedsCommit(); 438 } 439 440 void LayerChromium::scrollBy(const IntSize& scrollDelta) 441 { 442 setScrollPosition(scrollPosition() + scrollDelta); 443 if (m_layerScrollDelegate) 444 m_layerScrollDelegate->didScroll(scrollDelta); 429 445 } 430 446 … … 546 562 layer->setPreserves3D(preserves3D()); 547 563 layer->setScrollPosition(m_scrollPosition); 564 layer->setMaxScrollPosition(m_maxScrollPosition); 548 565 layer->setSublayerTransform(m_sublayerTransform); 549 566 if (!transformIsAnimating()) -
trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h
r120340 r120444 66 66 class ScrollbarLayerChromium; 67 67 68 // Delegate for handling scroll input for a LayerChromium. 69 class LayerChromiumScrollDelegate { 70 public: 71 virtual void didScroll(const IntSize&) = 0; 72 73 protected: 74 virtual ~LayerChromiumScrollDelegate() { } 75 }; 76 68 77 // Base class for composited layers. Special layer types are derived from 69 78 // this class. … … 152 161 const IntPoint& scrollPosition() const { return m_scrollPosition; } 153 162 163 void setMaxScrollPosition(const IntSize&); 164 const IntSize& maxScrollPosition() const { return m_maxScrollPosition; } 165 154 166 void setScrollable(bool); 167 bool scrollable() const { return m_scrollable; } 155 168 void setShouldScrollOnMainThread(bool); 156 169 void setHaveWheelEventHandlers(bool); … … 158 171 void setNonFastScrollableRegion(const Region&); 159 172 void setNonFastScrollableRegionChanged() { m_nonFastScrollableRegionChanged = true; } 173 void setLayerScrollDelegate(LayerChromiumScrollDelegate* layerScrollDelegate) { m_layerScrollDelegate = layerScrollDelegate; } 174 void scrollBy(const IntSize&); 160 175 161 176 void setDrawCheckerboardForMissingTiles(bool); … … 327 342 IntRect m_scissorRect; 328 343 IntPoint m_scrollPosition; 344 IntSize m_maxScrollPosition; 329 345 bool m_scrollable; 330 346 bool m_shouldScrollOnMainThread; … … 379 395 380 396 CCLayerAnimationDelegate* m_layerAnimationDelegate; 397 LayerChromiumScrollDelegate* m_layerScrollDelegate; 381 398 }; 382 399 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h
r111270 r120444 46 46 WTF_MAKE_NONCOPYABLE(CCInputHandlerClient); 47 47 public: 48 enum ScrollStatus { Scroll Failed, ScrollStarted, ScrollIgnored };48 enum ScrollStatus { ScrollOnMainThread, ScrollStarted, ScrollIgnored }; 49 49 enum ScrollInputType { Gesture, Wheel }; 50 50 51 51 // Attempt to start scrolling a layer at a given point in window 52 52 // coordinates. Returns ScrollStarted if the layer at the coordinates can 53 // be scrolled, Scroll Failed if the scroll event should instead be53 // be scrolled, ScrollOnMainThread if the scroll event should instead be 54 54 // delegated to the main thread, or ScrollIgnored if there is nothing to 55 55 // be scrolled at the given coordinates. -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
r120340 r120444 34 34 #include "cc/CCDebugBorderDrawQuad.h" 35 35 #include "cc/CCLayerSorter.h" 36 #include "cc/CCMathUtil.h" 36 37 #include "cc/CCQuadCuller.h" 37 38 #include "cc/CCSolidColorDrawQuad.h" … … 187 188 } 188 189 190 CCInputHandlerClient::ScrollStatus CCLayerImpl::tryScroll(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type) const 191 { 192 if (shouldScrollOnMainThread()) { 193 TRACE_EVENT0("cc", "CCLayerImpl::tryScroll: Failed shouldScrollOnMainThread"); 194 return CCInputHandlerClient::ScrollOnMainThread; 195 } 196 197 if (!screenSpaceTransform().isInvertible()) { 198 TRACE_EVENT0("cc", "CCLayerImpl::tryScroll: Ignored nonInvertibleTransform"); 199 return CCInputHandlerClient::ScrollIgnored; 200 } 201 202 if (!nonFastScrollableRegion().isEmpty()) { 203 bool clipped = false; 204 FloatPoint hitTestPointInLocalSpace = CCMathUtil::projectPoint(screenSpaceTransform().inverse(), FloatPoint(viewportPoint), clipped); 205 if (!clipped && nonFastScrollableRegion().contains(flooredIntPoint(hitTestPointInLocalSpace))) { 206 TRACE_EVENT0("cc", "CCLayerImpl::tryScroll: Failed nonFastScrollableRegion"); 207 return CCInputHandlerClient::ScrollOnMainThread; 208 } 209 } 210 211 if (type == CCInputHandlerClient::Wheel && haveWheelEventHandlers()) { 212 TRACE_EVENT0("cc", "CCLayerImpl::tryScroll: Failed wheelEventHandlers"); 213 return CCInputHandlerClient::ScrollOnMainThread; 214 } 215 216 if (!scrollable()) { 217 TRACE_EVENT0("cc", "CCLayerImpl::tryScroll: Ignored not scrollable"); 218 return CCInputHandlerClient::ScrollIgnored; 219 } 220 221 return CCInputHandlerClient::ScrollStarted; 222 } 223 189 224 const IntRect CCLayerImpl::getDrawRect() const 190 225 { … … 239 274 void sortLayers(Vector<CCLayerImpl*>::iterator first, Vector<CCLayerImpl*>::iterator end, CCLayerSorter* layerSorter) 240 275 { 241 TRACE_EVENT ("LayerRendererChromium::sortLayers", 0, 0);276 TRACE_EVENT0("cc", "LayerRendererChromium::sortLayers"); 242 277 layerSorter->sort(first, end); 243 278 } -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
r120340 r120444 32 32 #include "Region.h" 33 33 #include "TextStream.h" 34 #include "cc/CCInputHandler.h" 34 35 #include "cc/CCLayerAnimationController.h" 35 36 #include "cc/CCRenderSurface.h" … … 218 219 void setDrawCheckerboardForMissingTiles(bool checkerboard) { m_drawCheckerboardForMissingTiles = checkerboard; } 219 220 bool drawCheckerboardForMissingTiles() const { return m_drawCheckerboardForMissingTiles; } 221 222 CCInputHandlerClient::ScrollStatus tryScroll(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType) const; 220 223 221 224 const IntRect& visibleLayerRect() const { return m_visibleLayerRect; } -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
r120360 r120444 243 243 ASSERT(CCProxy::isImplThread()); 244 244 245 hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl-> releaseRootLayer(), hostImpl));245 hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->detachLayerTree(), hostImpl)); 246 246 247 247 // We may have added an animation during the tree sync. This will cause both layer tree hosts … … 619 619 } 620 620 621 static LayerChromium* findFirstScrollableLayer(LayerChromium* layer) 622 { 623 if (!layer) 624 return 0; 625 626 if (layer->scrollable()) 627 return layer; 628 629 for (size_t i = 0; i < layer->children().size(); ++i) { 630 LayerChromium* found = findFirstScrollableLayer(layer->children()[i].get()); 631 if (found) 632 return found; 633 } 634 635 return 0; 636 } 637 621 638 void CCLayerTreeHost::applyScrollAndScale(const CCScrollAndScaleSet& info) 622 639 { 623 // FIXME: pushing scroll offsets to non-root layers not implemented 624 if (!info.scrolls.size()) 625 return; 626 627 ASSERT(info.scrolls.size() == 1); 628 IntSize scrollDelta = info.scrolls[0].scrollDelta; 629 m_client->applyScrollAndScale(scrollDelta, info.pageScaleDelta); 640 if (!m_rootLayer) 641 return; 642 643 LayerChromium* rootScrollLayer = findFirstScrollableLayer(m_rootLayer.get()); 644 IntSize rootScrollDelta; 645 646 for (size_t i = 0; i < info.scrolls.size(); ++i) { 647 LayerChromium* layer = CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayer.get(), info.scrolls[i].layerId); 648 if (!layer) 649 continue; 650 if (layer == rootScrollLayer) 651 rootScrollDelta += info.scrolls[i].scrollDelta; 652 else 653 layer->scrollBy(info.scrolls[i].scrollDelta); 654 } 655 if (!rootScrollDelta.isZero() || info.pageScaleDelta != 1) 656 m_client->applyScrollAndScale(rootScrollDelta, info.pageScaleDelta); 630 657 } 631 658 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.h
r120261 r120444 53 53 template<typename LayerType> static bool renderSurfaceContributesToTarget(LayerType*, int targetSurfaceLayerID); 54 54 55 // Returns a layer with the given id if one exists in the subtree starting 56 // from the given root layer (including mask and replica layers). 57 template<typename LayerType> static LayerType* findLayerInSubtree(LayerType* rootLayer, int layerId); 58 55 59 struct ScrollUpdateInfo { 56 60 int layerId; … … 78 82 } 79 83 84 template<typename LayerType> 85 LayerType* CCLayerTreeHostCommon::findLayerInSubtree(LayerType* rootLayer, int layerId) 86 { 87 if (rootLayer->id() == layerId) 88 return rootLayer; 89 90 if (rootLayer->maskLayer() && rootLayer->maskLayer()->id() == layerId) 91 return rootLayer->maskLayer(); 92 93 if (rootLayer->replicaLayer() && rootLayer->replicaLayer()->id() == layerId) 94 return rootLayer->replicaLayer(); 95 96 for (size_t i = 0; i < rootLayer->children().size(); ++i) { 97 if (LayerType* found = findLayerInSubtree(rootLayer->children()[i].get(), layerId)) 98 return found; 99 } 100 return 0; 101 } 102 80 103 } // namespace WebCore 81 104 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
r120360 r120444 116 116 , m_sourceFrameNumber(-1) 117 117 , m_frameNumber(0) 118 , m_scrollLayerImpl(0) 118 , m_rootScrollLayerImpl(0) 119 , m_currentlyScrollingLayerImpl(0) 120 , m_scrollingLayerIdFromPreviousTree(-1) 119 121 , m_settings(settings) 120 122 , m_visible(true) … … 139 141 { 140 142 ASSERT(CCProxy::isImplThread()); 141 TRACE_EVENT ("CCLayerTreeHostImpl::~CCLayerTreeHostImpl()", this, 0);143 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::~CCLayerTreeHostImpl()"); 142 144 143 145 if (m_rootLayerImpl) … … 183 185 void CCLayerTreeHostImpl::startPageScaleAnimation(const IntSize& targetPosition, bool anchorPoint, float pageScale, double startTime, double duration) 184 186 { 185 if (!m_ scrollLayerImpl)186 return; 187 188 IntSize scrollTotal = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());187 if (!m_rootScrollLayerImpl) 188 return; 189 190 IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 189 191 scrollTotal.scale(m_pageScaleDelta); 190 192 float scaleTotal = m_pageScale * m_pageScaleDelta; … … 236 238 { 237 239 ASSERT(renderSurfaceLayerList.isEmpty()); 240 ASSERT(m_rootLayerImpl); 238 241 239 242 renderSurfaceLayerList.append(m_rootLayerImpl.get()); … … 247 250 248 251 { 249 TRACE_EVENT ("CCLayerTreeHostImpl::calcDrawEtc", this, 0);252 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::calcDrawEtc"); 250 253 WebTransformationMatrix identityMatrix; 251 254 WebTransformationMatrix deviceScaleTransform; … … 270 273 calculateRenderSurfaceLayerList(renderSurfaceLayerList); 271 274 272 TRACE_EVENT1(" webkit", "CCLayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(renderSurfaceLayerList.size()));275 TRACE_EVENT1("cc", "CCLayerTreeHostImpl::calculateRenderPasses", "renderSurfaceLayerList.size()", static_cast<long long unsigned>(renderSurfaceLayerList.size())); 273 276 274 277 m_rootLayerImpl->setScissorRect(enclosingIntRect(m_rootScissorRect)); … … 375 378 // TODO(aelias): Hardcoding the first child here is weird. Think of 376 379 // a cleaner way to get the contentBounds on the Impl side. 377 if (!m_ scrollLayerImpl || m_scrollLayerImpl->children().isEmpty())380 if (!m_rootScrollLayerImpl || m_rootScrollLayerImpl->children().isEmpty()) 378 381 return IntSize(); 379 return m_ scrollLayerImpl->children()[0]->contentBounds();382 return m_rootScrollLayerImpl->children()[0]->contentBounds(); 380 383 } 381 384 382 385 bool CCLayerTreeHostImpl::prepareToDraw(FrameData& frame) 383 386 { 384 TRACE_EVENT ("CCLayerTreeHostImpl::prepareToDraw", this, 0);387 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::prepareToDraw"); 385 388 ASSERT(canDraw()); 386 389 390 frame.renderSurfaceLayerList = &m_renderSurfaceLayerList; 387 391 frame.renderPasses.clear(); 388 frame.renderSurfaceLayerList .clear();392 frame.renderSurfaceLayerList->clear(); 389 393 frame.willDrawLayers.clear(); 390 394 391 if (!calculateRenderPasses(frame.renderPasses, frame.renderSurfaceLayerList, frame.willDrawLayers))395 if (!calculateRenderPasses(frame.renderPasses, *frame.renderSurfaceLayerList, frame.willDrawLayers)) 392 396 return false; 393 397 … … 403 407 void CCLayerTreeHostImpl::drawLayers(const FrameData& frame) 404 408 { 405 TRACE_EVENT ("CCLayerTreeHostImpl::drawLayers", this, 0);409 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::drawLayers"); 406 410 ASSERT(canDraw()); 407 411 ASSERT(!frame.renderPasses.isEmpty()); … … 427 431 428 432 if (m_debugRectHistory->enabled(settings())) 429 m_debugRectHistory->saveDebugRectsForCurrentFrame(m_rootLayerImpl.get(), frame.renderSurfaceLayerList, settings());433 m_debugRectHistory->saveDebugRectsForCurrentFrame(m_rootLayerImpl.get(), *frame.renderSurfaceLayerList, settings()); 430 434 431 435 if (m_headsUpDisplay->enabled(settings())) … … 491 495 } 492 496 493 static CCLayerImpl* find ScrollLayer(CCLayerImpl* layer)497 static CCLayerImpl* findRootScrollLayer(CCLayerImpl* layer) 494 498 { 495 499 if (!layer) … … 500 504 501 505 for (size_t i = 0; i < layer->children().size(); ++i) { 502 CCLayerImpl* found = find ScrollLayer(layer->children()[i].get());506 CCLayerImpl* found = findRootScrollLayer(layer->children()[i].get()); 503 507 if (found) 504 508 return found; … … 508 512 } 509 513 514 // Content layers can be either directly scrollable or contained in an outer 515 // scrolling layer which applies the scroll transform. Given a content layer, 516 // this function returns the associated scroll layer if any. 517 static CCLayerImpl* findScrollLayerForContentLayer(CCLayerImpl* layerImpl) 518 { 519 if (!layerImpl) 520 return 0; 521 522 if (layerImpl->scrollable()) 523 return layerImpl; 524 525 if (layerImpl->drawsContent() && layerImpl->parent() && layerImpl->parent()->scrollable()) 526 return layerImpl->parent(); 527 528 return 0; 529 } 530 510 531 void CCLayerTreeHostImpl::setRootLayer(PassOwnPtr<CCLayerImpl> layer) 511 532 { 512 533 m_rootLayerImpl = layer; 513 514 // FIXME: Currently, this only finds the first scrollable layer. 515 m_scrollLayerImpl = findScrollLayer(m_rootLayerImpl.get()); 534 m_rootScrollLayerImpl = findRootScrollLayer(m_rootLayerImpl.get()); 535 m_currentlyScrollingLayerImpl = 0; 536 537 if (m_rootLayerImpl && m_scrollingLayerIdFromPreviousTree != -1) 538 m_currentlyScrollingLayerImpl = CCLayerTreeHostCommon::findLayerInSubtree(m_rootLayerImpl.get(), m_scrollingLayerIdFromPreviousTree); 539 540 m_scrollingLayerIdFromPreviousTree = -1; 541 } 542 543 PassOwnPtr<CCLayerImpl> CCLayerTreeHostImpl::detachLayerTree() 544 { 545 // Clear all data structures that have direct references to the layer tree. 546 m_scrollingLayerIdFromPreviousTree = m_currentlyScrollingLayerImpl ? m_currentlyScrollingLayerImpl->id() : -1; 547 m_currentlyScrollingLayerImpl = 0; 548 m_renderSurfaceLayerList.clear(); 549 550 return m_rootLayerImpl.release(); 516 551 } 517 552 … … 577 612 } 578 613 614 static void adjustScrollsForPageScaleChange(CCLayerImpl* layerImpl, float pageScaleChange) 615 { 616 if (!layerImpl) 617 return; 618 619 if (layerImpl->scrollable()) { 620 // We need to convert impl-side scroll deltas to pageScale space. 621 FloatSize scrollDelta = layerImpl->scrollDelta(); 622 scrollDelta.scale(pageScaleChange); 623 layerImpl->setScrollDelta(scrollDelta); 624 } 625 626 for (size_t i = 0; i < layerImpl->children().size(); ++i) 627 adjustScrollsForPageScaleChange(layerImpl->children()[i].get(), pageScaleChange); 628 } 629 630 static void applyPageScaleDeltaToScrollLayers(CCLayerImpl* layerImpl, float pageScaleDelta) 631 { 632 if (!layerImpl) 633 return; 634 635 if (layerImpl->scrollable()) 636 layerImpl->setPageScaleDelta(pageScaleDelta); 637 638 for (size_t i = 0; i < layerImpl->children().size(); ++i) 639 applyPageScaleDeltaToScrollLayers(layerImpl->children()[i].get(), pageScaleDelta); 640 } 641 579 642 void CCLayerTreeHostImpl::setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale) 580 643 { … … 591 654 m_pageScale = pageScale; 592 655 593 adjustScrollsForPageScaleChange(pageScaleChange); 656 if (pageScaleChange != 1) 657 adjustScrollsForPageScaleChange(m_rootScrollLayerImpl, pageScaleChange); 594 658 595 659 // Clamp delta to limits and refresh display matrix. 596 660 setPageScaleDelta(m_pageScaleDelta / m_sentPageScaleDelta); 597 661 m_sentPageScaleDelta = 1; 598 applyPageScaleDeltaToScrollLayer(); 599 } 600 601 void CCLayerTreeHostImpl::adjustScrollsForPageScaleChange(float pageScaleChange) 602 { 603 if (pageScaleChange == 1) 604 return; 605 606 // We also need to convert impl-side scroll deltas to pageScale space. 607 if (m_scrollLayerImpl) { 608 FloatSize scrollDelta = m_scrollLayerImpl->scrollDelta(); 609 scrollDelta.scale(pageScaleChange); 610 m_scrollLayerImpl->setScrollDelta(scrollDelta); 611 } 662 applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); 612 663 } 613 664 … … 627 678 628 679 updateMaxScrollPosition(); 629 applyPageScaleDeltaToScrollLayer(); 630 } 631 632 void CCLayerTreeHostImpl::applyPageScaleDeltaToScrollLayer() 633 { 634 if (m_scrollLayerImpl) 635 m_scrollLayerImpl->setPageScaleDelta(m_pageScaleDelta); 680 applyPageScaleDeltaToScrollLayers(m_rootScrollLayerImpl, m_pageScaleDelta); 636 681 } 637 682 638 683 void CCLayerTreeHostImpl::updateMaxScrollPosition() 639 684 { 640 if (!m_ scrollLayerImpl || !m_scrollLayerImpl->children().size())685 if (!m_rootScrollLayerImpl || !m_rootScrollLayerImpl->children().size()) 641 686 return; 642 687 643 688 FloatSize viewBounds = m_viewportSize; 644 if (CCLayerImpl* clipLayer = m_ scrollLayerImpl->parent()) {689 if (CCLayerImpl* clipLayer = m_rootScrollLayerImpl->parent()) { 645 690 if (clipLayer->masksToBounds()) 646 691 viewBounds = clipLayer->bounds(); … … 656 701 maxScroll.clampNegativeToZero(); 657 702 658 m_scrollLayerImpl->setMaxScrollPosition(maxScroll); 659 660 // TODO(aelias): Also update sublayers. 703 m_rootScrollLayerImpl->setMaxScrollPosition(maxScroll); 661 704 } 662 705 … … 666 709 } 667 710 711 bool CCLayerTreeHostImpl::ensureRenderSurfaceLayerList() 712 { 713 if (!m_rootLayerImpl) 714 return false; 715 716 // We need both a non-empty render surface layer list and a root render 717 // surface to be able to iterate over the visible layers. 718 if (m_renderSurfaceLayerList.size() && m_rootLayerImpl->renderSurface()) 719 return true; 720 721 // If we are called after setRootLayer() but before prepareToDraw(), we need 722 // to recalculate the visible layers. This prevents being unable to scroll 723 // during part of a commit. 724 m_renderSurfaceLayerList.clear(); 725 calculateRenderSurfaceLayerList(m_renderSurfaceLayerList); 726 727 return m_renderSurfaceLayerList.size(); 728 } 729 668 730 CCInputHandlerClient::ScrollStatus CCLayerTreeHostImpl::scrollBegin(const IntPoint& viewportPoint, CCInputHandlerClient::ScrollInputType type) 669 731 { 670 // TODO: Check for scrollable sublayers. 671 if (!m_scrollLayerImpl || !m_scrollLayerImpl->scrollable()) { 672 TRACE_EVENT("scrollBegin Ignored no scrollable", this, 0); 732 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::scrollBegin"); 733 734 ASSERT(!m_currentlyScrollingLayerImpl); 735 clearCurrentlyScrollingLayer(); 736 737 if (!ensureRenderSurfaceLayerList()) 673 738 return ScrollIgnored; 674 }675 676 if (m_scrollLayerImpl->shouldScrollOnMainThread()) {677 TRACE_EVENT("scrollBegin Failed shouldScrollOnMainThread", this, 0);678 return ScrollFailed;679 }680 739 681 740 IntPoint deviceViewportPoint = viewportPoint; 682 741 deviceViewportPoint.scale(m_settings.deviceScaleFactor, m_settings.deviceScaleFactor); 683 742 684 // The inverse of the screen space transform takes us from physical pixels to layout pixels. 685 IntPoint scrollLayerPoint(m_scrollLayerImpl->screenSpaceTransform().inverse().mapPoint(deviceViewportPoint)); 686 687 if (m_scrollLayerImpl->nonFastScrollableRegion().contains(scrollLayerPoint)) { 688 TRACE_EVENT("scrollBegin Failed nonFastScrollableRegion", this, 0); 689 return ScrollFailed; 690 } 691 692 if (type == CCInputHandlerClient::Wheel && m_scrollLayerImpl->haveWheelEventHandlers()) { 693 TRACE_EVENT("scrollBegin Failed wheelEventHandlers", this, 0); 694 return ScrollFailed; 695 } 696 697 return ScrollStarted; 743 // First find out which layer was hit from the saved list of visible layers 744 // in the most recent frame. 745 CCLayerImpl* layerImpl = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(viewportPoint, m_renderSurfaceLayerList); 746 747 // Walk up the hierarchy and look for a scrollable layer. 748 CCLayerImpl* potentiallyScrollingLayerImpl = 0; 749 for (; layerImpl; layerImpl = layerImpl->parent()) { 750 // The content layer can also block attempts to scroll outside the main thread. 751 if (layerImpl->tryScroll(deviceViewportPoint, type) == ScrollOnMainThread) 752 return ScrollOnMainThread; 753 754 CCLayerImpl* scrollLayerImpl = findScrollLayerForContentLayer(layerImpl); 755 if (!scrollLayerImpl) 756 continue; 757 758 ScrollStatus status = scrollLayerImpl->tryScroll(viewportPoint, type); 759 760 // If any layer wants to divert the scroll event to the main thread, abort. 761 if (status == ScrollOnMainThread) 762 return ScrollOnMainThread; 763 764 if (status == ScrollStarted && !potentiallyScrollingLayerImpl) 765 potentiallyScrollingLayerImpl = scrollLayerImpl; 766 } 767 768 if (potentiallyScrollingLayerImpl) { 769 m_currentlyScrollingLayerImpl = potentiallyScrollingLayerImpl; 770 return ScrollStarted; 771 } 772 return ScrollIgnored; 698 773 } 699 774 700 775 void CCLayerTreeHostImpl::scrollBy(const IntSize& scrollDelta) 701 776 { 702 TRACE_EVENT("CCLayerTreeHostImpl::scrollBy", this, 0); 703 if (!m_scrollLayerImpl) 704 return; 705 706 m_scrollLayerImpl->scrollBy(scrollDelta); 707 m_client->setNeedsCommitOnImplThread(); 708 m_client->setNeedsRedrawOnImplThread(); 777 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::scrollBy"); 778 if (!m_currentlyScrollingLayerImpl) 779 return; 780 781 FloatSize pendingDelta(scrollDelta); 782 pendingDelta.scale(1 / m_pageScaleDelta); 783 784 for (CCLayerImpl* layerImpl = m_currentlyScrollingLayerImpl; layerImpl && !pendingDelta.isZero(); layerImpl = layerImpl->parent()) { 785 if (!layerImpl->scrollable()) 786 continue; 787 FloatSize previousDelta(layerImpl->scrollDelta()); 788 layerImpl->scrollBy(pendingDelta); 789 // Reset the pending scroll delta to zero if the layer was able to move along the requested 790 // axis. This is to ensure it is possible to scroll exactly to the beginning or end of a 791 // scroll area regardless of the scroll step. For diagonal scrolls this also avoids applying 792 // the scroll on one axis to multiple layers. 793 if (previousDelta.width() != layerImpl->scrollDelta().width()) 794 pendingDelta.setWidth(0); 795 if (previousDelta.height() != layerImpl->scrollDelta().height()) 796 pendingDelta.setHeight(0); 797 } 798 799 if (!scrollDelta.isZero() && pendingDelta.isEmpty()) { 800 m_client->setNeedsCommitOnImplThread(); 801 m_client->setNeedsRedrawOnImplThread(); 802 } 803 } 804 805 void CCLayerTreeHostImpl::clearCurrentlyScrollingLayer() 806 { 807 m_currentlyScrollingLayerImpl = 0; 808 m_scrollingLayerIdFromPreviousTree = -1; 709 809 } 710 810 711 811 void CCLayerTreeHostImpl::scrollEnd() 712 812 { 813 clearCurrentlyScrollingLayer(); 713 814 } 714 815 … … 722 823 const IntPoint& anchor) 723 824 { 724 TRACE_EVENT ("CCLayerTreeHostImpl::pinchGestureUpdate", this, 0);725 726 if (!m_ scrollLayerImpl)825 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::pinchGestureUpdate"); 826 827 if (!m_rootScrollLayerImpl) 727 828 return; 728 829 … … 739 840 m_previousPinchAnchor = anchor; 740 841 741 m_ scrollLayerImpl->scrollBy(roundedIntSize(move));842 m_rootScrollLayerImpl->scrollBy(roundedIntSize(move)); 742 843 m_client->setNeedsCommitOnImplThread(); 743 844 m_client->setNeedsRedrawOnImplThread(); … … 761 862 void CCLayerTreeHostImpl::computePinchZoomDeltas(CCScrollAndScaleSet* scrollInfo) 762 863 { 763 if (!m_ scrollLayerImpl)864 if (!m_rootScrollLayerImpl) 764 865 return; 765 866 … … 773 874 // Compute where the scroll offset/page scale would be if fully pinch-zoomed 774 875 // out from the anchor point. 775 IntSize scrollBegin = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());876 IntSize scrollBegin = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 776 877 scrollBegin.scale(m_pageScaleDelta); 777 878 float scaleBegin = m_pageScale * m_pageScaleDelta; … … 793 894 void CCLayerTreeHostImpl::makeScrollAndScaleSet(CCScrollAndScaleSet* scrollInfo, const IntSize& scrollOffset, float pageScale) 794 895 { 795 if (!m_ scrollLayerImpl)896 if (!m_rootScrollLayerImpl) 796 897 return; 797 898 798 899 CCLayerTreeHostCommon::ScrollUpdateInfo scroll; 799 scroll.layerId = m_ scrollLayerImpl->id();800 scroll.scrollDelta = scrollOffset - toSize(m_ scrollLayerImpl->scrollPosition());900 scroll.layerId = m_rootScrollLayerImpl->id(); 901 scroll.scrollDelta = scrollOffset - toSize(m_rootScrollLayerImpl->scrollPosition()); 801 902 scrollInfo->scrolls.append(scroll); 802 m_ scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);903 m_rootScrollLayerImpl->setSentScrollDelta(scroll.scrollDelta); 803 904 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = pageScale / m_pageScale; 804 905 } 805 906 907 static void collectScrollDeltas(CCScrollAndScaleSet* scrollInfo, CCLayerImpl* layerImpl) 908 { 909 if (!layerImpl) 910 return; 911 912 if (!layerImpl->scrollDelta().isZero()) { 913 IntSize scrollDelta = flooredIntSize(layerImpl->scrollDelta()); 914 CCLayerTreeHostCommon::ScrollUpdateInfo scroll; 915 scroll.layerId = layerImpl->id(); 916 scroll.scrollDelta = scrollDelta; 917 scrollInfo->scrolls.append(scroll); 918 layerImpl->setSentScrollDelta(scrollDelta); 919 } 920 921 for (size_t i = 0; i < layerImpl->children().size(); ++i) 922 collectScrollDeltas(scrollInfo, layerImpl->children()[i].get()); 923 } 924 806 925 PassOwnPtr<CCScrollAndScaleSet> CCLayerTreeHostImpl::processScrollDeltas() 807 926 { 808 927 OwnPtr<CCScrollAndScaleSet> scrollInfo = adoptPtr(new CCScrollAndScaleSet()); 809 bool didMove = m_scrollLayerImpl && (!m_scrollLayerImpl->scrollDelta().isZero() || m_pageScaleDelta != 1.0f); 810 if ( !didMove ||m_pinchGestureActive || m_pageScaleAnimation) {928 929 if (m_pinchGestureActive || m_pageScaleAnimation) { 811 930 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = 1; 812 931 if (m_pinchGestureActive) … … 817 936 } 818 937 938 collectScrollDeltas(scrollInfo.get(), m_rootLayerImpl.get()); 819 939 m_sentPageScaleDelta = scrollInfo->pageScaleDelta = m_pageScaleDelta; 820 821 // FIXME: track scrolls from layers other than the root822 CCLayerTreeHostCommon::ScrollUpdateInfo scroll;823 scroll.layerId = m_scrollLayerImpl->id();824 scroll.scrollDelta = flooredIntSize(m_scrollLayerImpl->scrollDelta());825 scrollInfo->scrolls.append(scroll);826 827 m_scrollLayerImpl->setSentScrollDelta(scroll.scrollDelta);828 940 829 941 return scrollInfo.release(); … … 841 953 void CCLayerTreeHostImpl::animatePageScale(double monotonicTime) 842 954 { 843 if (!m_pageScaleAnimation || !m_ scrollLayerImpl)844 return; 845 846 IntSize scrollTotal = flooredIntSize(m_ scrollLayerImpl->scrollPosition() + m_scrollLayerImpl->scrollDelta());955 if (!m_pageScaleAnimation || !m_rootScrollLayerImpl) 956 return; 957 958 IntSize scrollTotal = flooredIntSize(m_rootScrollLayerImpl->scrollPosition() + m_rootScrollLayerImpl->scrollDelta()); 847 959 848 960 setPageScaleDelta(m_pageScaleAnimation->pageScaleAtTime(monotonicTime) / m_pageScale); 849 961 IntSize nextScroll = m_pageScaleAnimation->scrollOffsetAtTime(monotonicTime); 850 962 nextScroll.scale(1 / m_pageScaleDelta); 851 m_ scrollLayerImpl->scrollBy(nextScroll - scrollTotal);963 m_rootScrollLayerImpl->scrollBy(nextScroll - scrollTotal); 852 964 m_client->setNeedsRedrawOnImplThread(); 853 965 … … 863 975 return; 864 976 865 TRACE_EVENT ("CCLayerTreeHostImpl::animateLayers", this, 0);977 TRACE_EVENT0("cc", "CCLayerTreeHostImpl::animateLayers"); 866 978 867 979 OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector)); … … 907 1019 { 908 1020 clearRenderSurfacesOnCCLayerImplRecursive(m_rootLayerImpl.get()); 909 // FIXME: If we have any RenderSurfaceLayerList saved, then make the list empty here.1021 m_renderSurfaceLayerList.clear(); 910 1022 } 911 1023 -
trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
r120360 r120444 87 87 struct FrameData { 88 88 CCRenderPassList renderPasses; 89 CCLayerList renderSurfaceLayerList;89 CCLayerList* renderSurfaceLayerList; 90 90 CCLayerList willDrawLayers; 91 91 }; … … 134 134 135 135 void setRootLayer(PassOwnPtr<CCLayerImpl>); 136 PassOwnPtr<CCLayerImpl> releaseRootLayer() { return m_rootLayerImpl.release(); }137 136 CCLayerImpl* rootLayer() { return m_rootLayerImpl.get(); } 138 137 139 CCLayerImpl* scrollLayer() const { return m_scrollLayerImpl; } 138 // Release ownership of the current layer tree and replace it with an empty 139 // tree. Returns the root layer of the detached tree. 140 PassOwnPtr<CCLayerImpl> detachLayerTree(); 141 142 CCLayerImpl* rootScrollLayer() const { return m_rootScrollLayerImpl; } 140 143 141 144 bool visible() const { return m_visible; } … … 197 200 198 201 void setPageScaleDelta(float); 199 void applyPageScaleDeltaToScrollLayer();200 void adjustScrollsForPageScaleChange(float);201 202 void updateMaxScrollPosition(); 202 203 void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList); … … 211 212 void sendDidLoseContextRecursive(CCLayerImpl*); 212 213 void clearRenderSurfaces(); 214 bool ensureRenderSurfaceLayerList(); 215 void clearCurrentlyScrollingLayer(); 213 216 214 217 void dumpRenderSurfaces(TextStream&, int indent, const CCLayerImpl*) const; … … 217 220 OwnPtr<CCRenderer> m_layerRenderer; 218 221 OwnPtr<CCLayerImpl> m_rootLayerImpl; 219 CCLayerImpl* m_scrollLayerImpl; 222 CCLayerImpl* m_rootScrollLayerImpl; 223 CCLayerImpl* m_currentlyScrollingLayerImpl; 224 int m_scrollingLayerIdFromPreviousTree; 220 225 CCLayerTreeSettings m_settings; 221 226 IntSize m_viewportSize; … … 249 254 FloatRect m_rootScissorRect; 250 255 256 // List of visible layers for the most recently prepared frame. Used for 257 // rendering and input event hit testing. 258 CCLayerList m_renderSurfaceLayerList; 259 251 260 OwnPtr<CCFrameRateCounter> m_fpsCounter; 252 261 OwnPtr<CCDebugRectHistory> m_debugRectHistory; -
trunk/Source/WebKit/chromium/ChangeLog
r120423 r120444 1 2012-06-15 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 New unit tests to verify layer scrolling behavior and the associated 9 utility functions. 10 11 * src/WebCompositorInputHandlerImpl.cpp: 12 (WebKit::WebCompositorInputHandlerImpl::handleInputEventInternal): 13 (WebKit::WebCompositorInputHandlerImpl::handleGestureFling): 14 * tests/CCLayerTreeHostCommonTest.cpp: 15 * tests/CCLayerTreeHostImplTest.cpp: 16 * tests/CCLayerTreeHostTest.cpp: 17 (WTF::MockContentLayerDelegate::paintContents): 18 (CCLayerTreeHostTestScrollChildLayer): 19 (WTF::CCLayerTreeHostTestScrollChildLayer::CCLayerTreeHostTestScrollChildLayer): 20 (WTF::CCLayerTreeHostTestScrollChildLayer::beginTest): 21 (WTF::CCLayerTreeHostTestScrollChildLayer::applyScrollAndScale): 22 (WTF::CCLayerTreeHostTestScrollChildLayer::beginCommitOnCCThread): 23 (WTF::CCLayerTreeHostTestScrollChildLayer::drawLayersOnCCThread): 24 (WTF::CCLayerTreeHostTestScrollChildLayer::afterTest): 25 (WTF): 26 (WTF::TEST_F): 27 * tests/WebCompositorInputHandlerImplTest.cpp: 28 (WebKit::TEST_F): 29 1 30 2012-06-15 Hironori Bono <hbono@chromium.org> 2 31 -
trunk/Source/WebKit/chromium/src/WebCompositorInputHandlerImpl.cpp
r112364 r120444 192 192 // event to the main thread. Change back to DropEvent once we have synchronization bugs sorted out. 193 193 return DidNotHandle; 194 case CCInputHandlerClient::Scroll Failed:194 case CCInputHandlerClient::ScrollOnMainThread: 195 195 return DidNotHandle; 196 196 } … … 207 207 m_gestureScrollStarted = true; 208 208 return DidHandle; 209 case CCInputHandlerClient::Scroll Failed:209 case CCInputHandlerClient::ScrollOnMainThread: 210 210 return DidNotHandle; 211 211 case CCInputHandlerClient::ScrollIgnored: … … 279 279 return DidHandle; 280 280 } 281 case CCInputHandlerClient::Scroll Failed: {282 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGestureFling:: failed");281 case CCInputHandlerClient::ScrollOnMainThread: { 282 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGestureFling::scrollOnMainThread"); 283 283 return DidNotHandle; 284 284 } -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
r120380 r120444 3663 3663 } 3664 3664 3665 TEST(CCLayerTreeHostCommonTest, verifySubtreeSearch) 3666 { 3667 RefPtr<LayerChromium> root = LayerChromium::create(); 3668 RefPtr<LayerChromium> child = LayerChromium::create(); 3669 RefPtr<LayerChromium> grandChild = LayerChromium::create(); 3670 RefPtr<LayerChromium> maskLayer = LayerChromium::create(); 3671 RefPtr<LayerChromium> replicaLayer = LayerChromium::create(); 3672 3673 grandChild->setReplicaLayer(replicaLayer.get()); 3674 child->addChild(grandChild.get()); 3675 child->setMaskLayer(maskLayer.get()); 3676 root->addChild(child.get()); 3677 3678 int nonexistentId = -1; 3679 EXPECT_EQ(root, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), root->id())); 3680 EXPECT_EQ(child, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), child->id())); 3681 EXPECT_EQ(grandChild, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), grandChild->id())); 3682 EXPECT_EQ(maskLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), maskLayer->id())); 3683 EXPECT_EQ(replicaLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), replicaLayer->id())); 3684 EXPECT_EQ(0, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), nonexistentId)); 3685 } 3665 3686 3666 3687 // FIXME: -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
r120360 r120444 140 140 } 141 141 142 static PassOwnPtr<CCLayerImpl> createScrollableLayer(int id, const FloatPoint& position, const IntSize& size) 143 { 144 OwnPtr<CCLayerImpl> layer = CCLayerImpl::create(id); 145 layer->setScrollable(true); 146 layer->setDrawsContent(true); 147 layer->setPosition(position); 148 layer->setBounds(size); 149 layer->setContentBounds(size); 150 layer->setMaxScrollPosition(IntSize(size.width() * 2, size.height() * 2)); 151 return layer.release(); 152 } 153 154 void initializeLayerRendererAndDrawFrame() 155 { 156 m_hostImpl->initializeLayerRenderer(createContext(), UnthrottledUploader); 157 CCLayerTreeHostImpl::FrameData frame; 158 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); 159 m_hostImpl->drawLayers(frame); 160 m_hostImpl->didDrawAllLayers(frame); 161 } 162 142 163 protected: 143 164 PassRefPtr<CCGraphicsContext> createContext() … … 224 245 TEST_F(CCLayerTreeHostImplTest, scrollRootCallsCommitAndRedraw) 225 246 { 226 { 227 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 228 root->setScrollable(true); 229 root->setScrollPosition(IntPoint(0, 0)); 230 root->setMaxScrollPosition(IntSize(100, 100)); 231 m_hostImpl->setRootLayer(root.release()); 232 } 247 setupScrollAndContentsLayers(IntSize(100, 100)); 248 m_hostImpl->setViewportSize(IntSize(50, 50)); 249 initializeLayerRendererAndDrawFrame(); 233 250 234 251 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); … … 239 256 } 240 257 258 TEST_F(CCLayerTreeHostImplTest, scrollWithoutRootLayer) 259 { 260 // We should not crash when trying to scroll an empty layer tree. 261 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 262 } 263 264 TEST_F(CCLayerTreeHostImplTest, replaceTreeWhileScrolling) 265 { 266 const int scrollLayerId = 0; 267 268 setupScrollAndContentsLayers(IntSize(100, 100)); 269 m_hostImpl->setViewportSize(IntSize(50, 50)); 270 initializeLayerRendererAndDrawFrame(); 271 272 // We should not crash if the tree is replaced while we are scrolling. 273 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 274 m_hostImpl->detachLayerTree(); 275 276 setupScrollAndContentsLayers(IntSize(100, 100)); 277 278 // We should still be scrolling, because the scrolled layer also exists in the new tree. 279 IntSize scrollDelta(0, 10); 280 m_hostImpl->scrollBy(scrollDelta); 281 m_hostImpl->scrollEnd(); 282 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 283 expectContains(*scrollInfo, scrollLayerId, scrollDelta); 284 } 285 286 TEST_F(CCLayerTreeHostImplTest, clearRootRenderSurfaceAndScroll) 287 { 288 setupScrollAndContentsLayers(IntSize(100, 100)); 289 m_hostImpl->setViewportSize(IntSize(50, 50)); 290 initializeLayerRendererAndDrawFrame(); 291 292 // We should be able to scroll even if the root layer loses its render surface after the most 293 // recent render. 294 m_hostImpl->rootLayer()->clearRenderSurface(); 295 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 296 } 297 241 298 TEST_F(CCLayerTreeHostImplTest, wheelEventHandlers) 242 299 { 243 { 244 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 245 root->setScrollable(true); 246 root->setScrollPosition(IntPoint(0, 0)); 247 root->setMaxScrollPosition(IntSize(100, 100)); 248 m_hostImpl->setRootLayer(root.release()); 249 } 300 setupScrollAndContentsLayers(IntSize(100, 100)); 301 m_hostImpl->setViewportSize(IntSize(50, 50)); 302 initializeLayerRendererAndDrawFrame(); 250 303 CCLayerImpl* root = m_hostImpl->rootLayer(); 251 304 252 305 root->setHaveWheelEventHandlers(true); 306 253 307 // With registered event handlers, wheel scrolls have to go to the main thread. 254 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::Scroll Failed);308 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread); 255 309 256 310 // But gesture scrolls can still be handled. … … 260 314 TEST_F(CCLayerTreeHostImplTest, shouldScrollOnMainThread) 261 315 { 262 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 263 root->setScrollable(true); 264 root->setScrollPosition(IntPoint(0, 0)); 265 root->setMaxScrollPosition(IntSize(100, 100)); 316 setupScrollAndContentsLayers(IntSize(100, 100)); 317 m_hostImpl->setViewportSize(IntSize(50, 50)); 318 initializeLayerRendererAndDrawFrame(); 319 CCLayerImpl* root = m_hostImpl->rootLayer(); 320 266 321 root->setShouldScrollOnMainThread(true); 267 m_hostImpl->setRootLayer(root.release()); 268 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::Scroll Failed);269 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Gesture), CCInputHandlerClient::Scroll Failed);322 323 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread); 324 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Gesture), CCInputHandlerClient::ScrollOnMainThread); 270 325 } 271 326 272 327 TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionBasic) 273 328 { 274 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 275 root->setScrollable(true); 276 root->setScrollPosition(IntPoint(0, 0)); 277 root->setMaxScrollPosition(IntSize(100, 100)); 329 setupScrollAndContentsLayers(IntSize(200, 200)); 330 m_hostImpl->setViewportSize(IntSize(100, 100)); 331 initializeLayerRendererAndDrawFrame(); 332 CCLayerImpl* root = m_hostImpl->rootLayer(); 333 278 334 root->setNonFastScrollableRegion(IntRect(0, 0, 50, 50)); 279 m_hostImpl->setRootLayer(root.release()); 335 280 336 // All scroll types inside the non-fast scrollable region should fail. 281 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Wheel), CCInputHandlerClient::Scroll Failed);282 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Gesture), CCInputHandlerClient::Scroll Failed);337 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread); 338 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Gesture), CCInputHandlerClient::ScrollOnMainThread); 283 339 284 340 // All scroll types outside this region should succeed. … … 293 349 TEST_F(CCLayerTreeHostImplTest, nonFastScrollableRegionWithOffset) 294 350 { 295 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0);296 root->setScrollable(true);297 root->setScrollPosition(IntPoint(0, 0));298 root->setMaxScrollPosition(IntSize(100, 100)); 351 setupScrollAndContentsLayers(IntSize(200, 200)); 352 m_hostImpl->setViewportSize(IntSize(100, 100)); 353 CCLayerImpl* root = m_hostImpl->rootLayer(); 354 299 355 root->setNonFastScrollableRegion(IntRect(0, 0, 50, 50)); 300 356 root->setPosition(FloatPoint(-25, 0)); 301 m_hostImpl->setRootLayer(root.release()); 302 CCLayerTreeHostImpl::FrameData frame; 303 EXPECT_TRUE(m_hostImpl->prepareToDraw(frame)); 304 m_hostImpl->drawLayers(frame); // Update draw transforms so we can correctly map points into layer space. 357 initializeLayerRendererAndDrawFrame(); 305 358 306 359 // This point would fall into the non-fast scrollable region except that we've moved the layer down by 25 pixels. … … 310 363 311 364 // This point is still inside the non-fast region. 312 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(10, 10), CCInputHandlerClient::Wheel), CCInputHandlerClient::Scroll Failed);365 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(10, 10), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread); 313 366 } 314 367 … … 317 370 setupScrollAndContentsLayers(IntSize(100, 100)); 318 371 m_hostImpl->setViewportSize(IntSize(50, 50)); 319 320 CCLayerImpl* scrollLayer = m_hostImpl->scrollLayer(); 372 initializeLayerRendererAndDrawFrame(); 373 374 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 321 375 ASSERT(scrollLayer); 322 376 … … 397 451 setupScrollAndContentsLayers(IntSize(100, 100)); 398 452 m_hostImpl->setViewportSize(IntSize(50, 50)); 399 400 CCLayerImpl* scrollLayer = m_hostImpl->scrollLayer(); 453 initializeLayerRendererAndDrawFrame(); 454 455 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 401 456 ASSERT(scrollLayer); 402 457 … … 440 495 expectContains(*scrollInfo, scrollLayer->id(), IntSize(-50, -50)); 441 496 } 497 } 498 499 TEST_F(CCLayerTreeHostImplTest, inhibitScrollAndPageScaleUpdatesWhilePinchZooming) 500 { 501 setupScrollAndContentsLayers(IntSize(100, 100)); 502 m_hostImpl->setViewportSize(IntSize(50, 50)); 503 initializeLayerRendererAndDrawFrame(); 504 505 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 506 ASSERT(scrollLayer); 507 508 const float minPageScale = 0.5, maxPageScale = 4; 509 510 // Pinch zoom in. 511 { 512 // Start a pinch in gesture at the bottom right corner of the viewport. 513 const float zoomInDelta = 2; 514 m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale); 515 m_hostImpl->pinchGestureBegin(); 516 m_hostImpl->pinchGestureUpdate(zoomInDelta, IntPoint(50, 50)); 517 518 // Because we are pinch zooming in, we shouldn't get any scroll or page 519 // scale deltas. 520 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 521 EXPECT_EQ(scrollInfo->pageScaleDelta, 1); 522 EXPECT_EQ(scrollInfo->scrolls.size(), 0u); 523 524 // Once the gesture ends, we get the final scroll and page scale values. 525 m_hostImpl->pinchGestureEnd(); 526 scrollInfo = m_hostImpl->processScrollDeltas(); 527 EXPECT_EQ(scrollInfo->pageScaleDelta, zoomInDelta); 528 expectContains(*scrollInfo, scrollLayer->id(), IntSize(25, 25)); 529 } 530 531 // Pinch zoom out. 532 { 533 // Start a pinch out gesture at the bottom right corner of the viewport. 534 const float zoomOutDelta = 0.75; 535 m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale); 536 m_hostImpl->pinchGestureBegin(); 537 m_hostImpl->pinchGestureUpdate(zoomOutDelta, IntPoint(50, 50)); 538 539 // Since we are pinch zooming out, we should get an update to zoom all 540 // the way out to the minimum page scale. 541 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 542 EXPECT_EQ(scrollInfo->pageScaleDelta, minPageScale); 543 expectContains(*scrollInfo, scrollLayer->id(), IntSize(0, 0)); 544 545 // Once the gesture ends, we get the final scroll and page scale values. 546 m_hostImpl->pinchGestureEnd(); 547 scrollInfo = m_hostImpl->processScrollDeltas(); 548 EXPECT_EQ(scrollInfo->pageScaleDelta, zoomOutDelta); 549 expectContains(*scrollInfo, scrollLayer->id(), IntSize(8, 8)); 550 } 551 } 552 553 TEST_F(CCLayerTreeHostImplTest, inhibitScrollAndPageScaleUpdatesWhileAnimatingPageScale) 554 { 555 setupScrollAndContentsLayers(IntSize(100, 100)); 556 m_hostImpl->setViewportSize(IntSize(50, 50)); 557 initializeLayerRendererAndDrawFrame(); 558 559 CCLayerImpl* scrollLayer = m_hostImpl->rootScrollLayer(); 560 ASSERT(scrollLayer); 561 562 const float minPageScale = 0.5, maxPageScale = 4; 563 const double startTime = 1; 564 const double duration = 0.1; 565 const double halfwayThroughAnimation = startTime + duration / 2; 566 const double endTime = startTime + duration; 567 568 // Start a page scale animation. 569 const float pageScaleDelta = 2; 570 m_hostImpl->setPageScaleFactorAndLimits(1, minPageScale, maxPageScale); 571 m_hostImpl->startPageScaleAnimation(IntSize(50, 50), false, pageScaleDelta, startTime, duration); 572 573 // We should immediately get the final zoom and scroll values for the 574 // animation. 575 m_hostImpl->animate(halfwayThroughAnimation, halfwayThroughAnimation); 576 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 577 EXPECT_EQ(scrollInfo->pageScaleDelta, pageScaleDelta); 578 expectContains(*scrollInfo, scrollLayer->id(), IntSize(25, 25)); 579 580 // Scrolling during the animation is ignored. 581 const IntSize scrollDelta(0, 10); 582 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(25, 25), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 583 m_hostImpl->scrollBy(scrollDelta); 584 m_hostImpl->scrollEnd(); 585 586 // The final page scale and scroll deltas should match what we got 587 // earlier. 588 m_hostImpl->animate(endTime, endTime); 589 scrollInfo = m_hostImpl->processScrollDeltas(); 590 EXPECT_EQ(scrollInfo->pageScaleDelta, pageScaleDelta); 591 expectContains(*scrollInfo, scrollLayer->id(), IntSize(25, 25)); 442 592 } 443 593 … … 656 806 m_hostImpl->drawLayers(frame); 657 807 m_hostImpl->didDrawAllLayers(frame); 808 } 809 810 TEST_F(CCLayerTreeHostImplTest, scrollRootIgnored) 811 { 812 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 813 root->setScrollable(false); 814 m_hostImpl->setRootLayer(root.release()); 815 initializeLayerRendererAndDrawFrame(); 816 817 // Scroll event is ignored because layer is not scrollable. 818 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(0, 0), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 819 EXPECT_FALSE(m_didRequestRedraw); 820 EXPECT_FALSE(m_didRequestCommit); 821 } 822 823 TEST_F(CCLayerTreeHostImplTest, scrollNonCompositedRoot) 824 { 825 // Test the configuration where a non-composited root layer is embedded in a 826 // scrollable outer layer. 827 IntSize surfaceSize(10, 10); 828 829 OwnPtr<CCLayerImpl> contentLayer = CCLayerImpl::create(1); 830 contentLayer->setIsNonCompositedContent(true); 831 contentLayer->setDrawsContent(true); 832 contentLayer->setPosition(IntPoint(5, 5)); 833 contentLayer->setBounds(surfaceSize); 834 contentLayer->setContentBounds(IntSize(surfaceSize.width() * 2, surfaceSize.height() * 2)); 835 836 OwnPtr<CCLayerImpl> scrollLayer = CCLayerImpl::create(0); 837 scrollLayer->setScrollable(true); 838 scrollLayer->setMaxScrollPosition(surfaceSize); 839 scrollLayer->addChild(contentLayer.release()); 840 841 m_hostImpl->setRootLayer(scrollLayer.release()); 842 m_hostImpl->setViewportSize(surfaceSize); 843 initializeLayerRendererAndDrawFrame(); 844 845 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 846 m_hostImpl->scrollBy(IntSize(0, 10)); 847 m_hostImpl->scrollEnd(); 848 EXPECT_TRUE(m_didRequestRedraw); 849 EXPECT_TRUE(m_didRequestCommit); 850 } 851 852 TEST_F(CCLayerTreeHostImplTest, scrollChildCallsCommitAndRedraw) 853 { 854 IntSize surfaceSize(10, 10); 855 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 856 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 857 m_hostImpl->setRootLayer(root.release()); 858 m_hostImpl->setViewportSize(surfaceSize); 859 initializeLayerRendererAndDrawFrame(); 860 861 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 862 m_hostImpl->scrollBy(IntSize(0, 10)); 863 m_hostImpl->scrollEnd(); 864 EXPECT_TRUE(m_didRequestRedraw); 865 EXPECT_TRUE(m_didRequestCommit); 866 } 867 868 TEST_F(CCLayerTreeHostImplTest, scrollMissesChild) 869 { 870 IntSize surfaceSize(10, 10); 871 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 872 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 873 m_hostImpl->setRootLayer(root.release()); 874 m_hostImpl->setViewportSize(surfaceSize); 875 initializeLayerRendererAndDrawFrame(); 876 877 // Scroll event is ignored because the input coordinate is outside the layer boundaries. 878 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(15, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 879 EXPECT_FALSE(m_didRequestRedraw); 880 EXPECT_FALSE(m_didRequestCommit); 881 } 882 883 TEST_F(CCLayerTreeHostImplTest, scrollMissesBackfacingChild) 884 { 885 IntSize surfaceSize(10, 10); 886 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 887 OwnPtr<CCLayerImpl> child = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 888 m_hostImpl->setViewportSize(surfaceSize); 889 890 WebTransformationMatrix matrix; 891 matrix.rotate3d(180, 0, 0); 892 child->setTransform(matrix); 893 child->setDoubleSided(false); 894 895 root->addChild(child.release()); 896 m_hostImpl->setRootLayer(root.release()); 897 initializeLayerRendererAndDrawFrame(); 898 899 // Scroll event is ignored because the scrollable layer is not facing the viewer and there is 900 // nothing scrollable behind it. 901 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollIgnored); 902 EXPECT_FALSE(m_didRequestRedraw); 903 EXPECT_FALSE(m_didRequestCommit); 904 } 905 906 TEST_F(CCLayerTreeHostImplTest, scrollBlockedByContentLayer) 907 { 908 IntSize surfaceSize(10, 10); 909 OwnPtr<CCLayerImpl> contentLayer = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 910 contentLayer->setShouldScrollOnMainThread(true); 911 contentLayer->setScrollable(false); 912 913 OwnPtr<CCLayerImpl> scrollLayer = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 914 scrollLayer->addChild(contentLayer.release()); 915 916 m_hostImpl->setRootLayer(scrollLayer.release()); 917 m_hostImpl->setViewportSize(surfaceSize); 918 initializeLayerRendererAndDrawFrame(); 919 920 // Scrolling fails because the content layer is asking to be scrolled on the main thread. 921 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollOnMainThread); 922 } 923 924 TEST_F(CCLayerTreeHostImplTest, scrollRootAndChangePageScaleOnMainThread) 925 { 926 IntSize surfaceSize(10, 10); 927 float pageScale = 2; 928 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 929 m_hostImpl->setRootLayer(root.release()); 930 m_hostImpl->setViewportSize(surfaceSize); 931 initializeLayerRendererAndDrawFrame(); 932 933 IntSize scrollDelta(0, 10); 934 IntSize expectedScrollDelta(scrollDelta); 935 IntSize expectedMaxScroll(m_hostImpl->rootLayer()->maxScrollPosition()); 936 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 937 m_hostImpl->scrollBy(scrollDelta); 938 m_hostImpl->scrollEnd(); 939 940 // Set new page scale from main thread. 941 m_hostImpl->setPageScaleFactorAndLimits(pageScale, pageScale, pageScale); 942 943 // The scale should apply to the scroll delta. 944 expectedScrollDelta.scale(pageScale); 945 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 946 expectContains(*scrollInfo.get(), 0, expectedScrollDelta); 947 948 // The scroll range should also have been updated. 949 EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), expectedMaxScroll); 950 951 // The page scale delta remains constant because the impl thread did not scale. 952 EXPECT_EQ(m_hostImpl->rootLayer()->pageScaleDelta(), 1); 953 } 954 955 TEST_F(CCLayerTreeHostImplTest, scrollRootAndChangePageScaleOnImplThread) 956 { 957 IntSize surfaceSize(10, 10); 958 float pageScale = 2; 959 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 960 m_hostImpl->setRootLayer(root.release()); 961 m_hostImpl->setViewportSize(surfaceSize); 962 m_hostImpl->setPageScaleFactorAndLimits(1, 1, pageScale); 963 initializeLayerRendererAndDrawFrame(); 964 965 IntSize scrollDelta(0, 10); 966 IntSize expectedScrollDelta(scrollDelta); 967 IntSize expectedMaxScroll(m_hostImpl->rootLayer()->maxScrollPosition()); 968 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 969 m_hostImpl->scrollBy(scrollDelta); 970 m_hostImpl->scrollEnd(); 971 972 // Set new page scale on impl thread by pinching. 973 m_hostImpl->pinchGestureBegin(); 974 m_hostImpl->pinchGestureUpdate(pageScale, IntPoint()); 975 m_hostImpl->pinchGestureEnd(); 976 977 // The scroll delta is not scaled because the main thread did not scale. 978 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 979 expectContains(*scrollInfo.get(), 0, expectedScrollDelta); 980 981 // The scroll range should also have been updated. 982 EXPECT_EQ(m_hostImpl->rootLayer()->maxScrollPosition(), expectedMaxScroll); 983 984 // The page scale delta should match the new scale on the impl side. 985 EXPECT_EQ(m_hostImpl->rootLayer()->pageScaleDelta(), pageScale); 986 } 987 988 TEST_F(CCLayerTreeHostImplTest, scrollChildAndChangePageScaleOnMainThread) 989 { 990 IntSize surfaceSize(10, 10); 991 OwnPtr<CCLayerImpl> root = CCLayerImpl::create(0); 992 // Also mark the root scrollable so it becomes the root scroll layer. 993 root->setScrollable(true); 994 root->addChild(createScrollableLayer(1, FloatPoint(5, 5), surfaceSize)); 995 m_hostImpl->setRootLayer(root.release()); 996 m_hostImpl->setViewportSize(surfaceSize); 997 initializeLayerRendererAndDrawFrame(); 998 999 CCLayerImpl* child = m_hostImpl->rootLayer()->children()[0].get(); 1000 1001 IntSize scrollDelta(0, 10); 1002 IntSize expectedScrollDelta(scrollDelta); 1003 IntSize expectedMaxScroll(child->maxScrollPosition()); 1004 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 1005 m_hostImpl->scrollBy(scrollDelta); 1006 m_hostImpl->scrollEnd(); 1007 1008 float pageScale = 2; 1009 m_hostImpl->setPageScaleFactorAndLimits(pageScale, 1, pageScale); 1010 1011 // The scale should apply to the scroll delta. 1012 expectedScrollDelta.scale(pageScale); 1013 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 1014 expectContains(*scrollInfo.get(), 1, expectedScrollDelta); 1015 1016 // The scroll range should not have changed. 1017 EXPECT_EQ(child->maxScrollPosition(), expectedMaxScroll); 1018 1019 // The page scale delta remains constant because the impl thread did not scale. 1020 EXPECT_EQ(child->pageScaleDelta(), 1); 1021 } 1022 1023 TEST_F(CCLayerTreeHostImplTest, scrollChildBeyondLimit) 1024 { 1025 // Scroll a child layer beyond its maximum scroll range and make sure the 1026 // parent layer is scrolled on the axis on which the child was unable to 1027 // scroll. 1028 IntSize surfaceSize(10, 10); 1029 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 1030 1031 OwnPtr<CCLayerImpl> grandChild = createScrollableLayer(2, FloatPoint(5, 5), surfaceSize); 1032 grandChild->setScrollPosition(IntPoint(0, 5)); 1033 1034 OwnPtr<CCLayerImpl> child = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 1035 child->setScrollPosition(IntPoint(3, 0)); 1036 child->addChild(grandChild.release()); 1037 1038 root->addChild(child.release()); 1039 m_hostImpl->setRootLayer(root.release()); 1040 m_hostImpl->setViewportSize(surfaceSize); 1041 initializeLayerRendererAndDrawFrame(); 1042 { 1043 IntSize scrollDelta(-3, -7); 1044 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 1045 m_hostImpl->scrollBy(scrollDelta); 1046 m_hostImpl->scrollEnd(); 1047 1048 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 1049 1050 // The grand child should have scrolled up to its limit. 1051 CCLayerImpl* child = m_hostImpl->rootLayer()->children()[0].get(); 1052 CCLayerImpl* grandChild = child->children()[0].get(); 1053 expectContains(*scrollInfo.get(), grandChild->id(), IntSize(0, -5)); 1054 1055 // The child should have only scrolled on the other axis. 1056 expectContains(*scrollInfo.get(), child->id(), IntSize(-3, 0)); 1057 } 1058 } 1059 1060 TEST_F(CCLayerTreeHostImplTest, scrollEventBubbling) 1061 { 1062 // When we try to scroll a non-scrollable child layer, the scroll delta 1063 // should be applied to one of its ancestors if possible. 1064 IntSize surfaceSize(10, 10); 1065 OwnPtr<CCLayerImpl> root = createScrollableLayer(0, FloatPoint(5, 5), surfaceSize); 1066 OwnPtr<CCLayerImpl> child = createScrollableLayer(1, FloatPoint(5, 5), surfaceSize); 1067 1068 child->setScrollable(false); 1069 root->addChild(child.release()); 1070 1071 m_hostImpl->setRootLayer(root.release()); 1072 m_hostImpl->setViewportSize(surfaceSize); 1073 initializeLayerRendererAndDrawFrame(); 1074 { 1075 IntSize scrollDelta(0, 4); 1076 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 1077 m_hostImpl->scrollBy(scrollDelta); 1078 m_hostImpl->scrollEnd(); 1079 1080 OwnPtr<CCScrollAndScaleSet> scrollInfo = m_hostImpl->processScrollDeltas(); 1081 1082 // Only the root should have scrolled. 1083 ASSERT_EQ(scrollInfo->scrolls.size(), 1u); 1084 expectContains(*scrollInfo.get(), m_hostImpl->rootLayer()->id(), scrollDelta); 1085 } 1086 } 1087 1088 TEST_F(CCLayerTreeHostImplTest, scrollBeforeRedraw) 1089 { 1090 IntSize surfaceSize(10, 10); 1091 m_hostImpl->setRootLayer(createScrollableLayer(0, FloatPoint(5, 5), surfaceSize)); 1092 m_hostImpl->setViewportSize(surfaceSize); 1093 1094 // Draw one frame and then immediately rebuild the layer tree to mimic a tree synchronization. 1095 initializeLayerRendererAndDrawFrame(); 1096 m_hostImpl->detachLayerTree(); 1097 m_hostImpl->setRootLayer(createScrollableLayer(0, FloatPoint(5, 5), surfaceSize)); 1098 1099 // Scrolling should still work even though we did not draw yet. 1100 EXPECT_EQ(m_hostImpl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 658 1101 } 659 1102 -
trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
r120360 r120444 2221 2221 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerAddedWithAnimation) 2222 2222 2223 class CCLayerTreeHostTestScrollChildLayer : public CCLayerTreeHostTest, public LayerChromiumScrollDelegate { 2224 public: 2225 CCLayerTreeHostTestScrollChildLayer() 2226 : m_scrollAmount(2, 1) 2227 { 2228 } 2229 2230 virtual void beginTest() OVERRIDE 2231 { 2232 m_layerTreeHost->setViewportSize(IntSize(10, 10)); 2233 m_rootScrollLayer = ContentLayerChromium::create(&m_mockDelegate); 2234 m_rootScrollLayer->setBounds(IntSize(10, 10)); 2235 m_rootScrollLayer->setIsDrawable(true); 2236 m_rootScrollLayer->setScrollable(true); 2237 m_rootScrollLayer->setMaxScrollPosition(IntSize(100, 100)); 2238 m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer); 2239 m_childLayer = ContentLayerChromium::create(&m_mockDelegate); 2240 m_childLayer->setLayerScrollDelegate(this); 2241 m_childLayer->setBounds(IntSize(50, 50)); 2242 m_childLayer->setIsDrawable(true); 2243 m_childLayer->setScrollable(true); 2244 m_childLayer->setMaxScrollPosition(IntSize(100, 100)); 2245 m_rootScrollLayer->addChild(m_childLayer); 2246 postSetNeedsCommitToMainThread(); 2247 } 2248 2249 virtual void didScroll(const IntSize& scrollDelta) OVERRIDE 2250 { 2251 m_reportedScrollAmount = scrollDelta; 2252 } 2253 2254 virtual void applyScrollAndScale(const IntSize& scrollDelta, float) OVERRIDE 2255 { 2256 IntPoint position = m_rootScrollLayer->scrollPosition(); 2257 m_rootScrollLayer->setScrollPosition(position + scrollDelta); 2258 } 2259 2260 virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE 2261 { 2262 EXPECT_EQ(m_rootScrollLayer->scrollPosition(), IntPoint()); 2263 if (!m_layerTreeHost->frameNumber()) 2264 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint()); 2265 else 2266 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint() + m_scrollAmount); 2267 } 2268 2269 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE 2270 { 2271 if (impl->frameNumber() == 1) { 2272 EXPECT_EQ(impl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted); 2273 impl->scrollBy(m_scrollAmount); 2274 impl->scrollEnd(); 2275 } else if (impl->frameNumber() == 2) 2276 endTest(); 2277 } 2278 2279 virtual void afterTest() OVERRIDE 2280 { 2281 EXPECT_EQ(m_scrollAmount, m_reportedScrollAmount); 2282 } 2283 2284 private: 2285 const IntSize m_scrollAmount; 2286 IntSize m_reportedScrollAmount; 2287 MockContentLayerDelegate m_mockDelegate; 2288 RefPtr<LayerChromium> m_childLayer; 2289 RefPtr<LayerChromium> m_rootScrollLayer; 2290 }; 2291 2292 TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread) 2293 { 2294 runTest(true); 2295 } 2296 2223 2297 } // namespace -
trunk/Source/WebKit/chromium/tests/WebCompositorInputHandlerImplTest.cpp
r112364 r120444 203 203 } 204 204 205 TEST_F(WebCompositorInputHandlerImplTest, gestureScroll Failed)205 TEST_F(WebCompositorInputHandlerImplTest, gestureScrollOnMainThread) 206 206 { 207 207 // We should send all events to the widget for this gesture. … … 210 210 211 211 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(::testing::_, ::testing::_)) 212 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::Scroll Failed));212 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollOnMainThread)); 213 213 214 214 gesture.type = WebInputEvent::GestureScrollBegin; … … 307 307 308 308 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)) 309 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::Scroll Failed));309 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollOnMainThread)); 310 310 311 311 gesture.type = WebInputEvent::GestureFlingStart; … … 388 388 EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation()); 389 389 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)) 390 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::Scroll Failed));390 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollOnMainThread)); 391 391 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0); 392 392 EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0); … … 470 470 EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation()); 471 471 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)) 472 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::Scroll Failed));472 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollOnMainThread)); 473 473 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0); 474 474 EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0); … … 547 547 EXPECT_CALL(m_mockCCInputHandlerClient, scheduleAnimation()); 548 548 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBegin(testing::_, testing::_)) 549 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::Scroll Failed));549 .WillOnce(testing::Return(WebCore::CCInputHandlerClient::ScrollOnMainThread)); 550 550 EXPECT_CALL(m_mockCCInputHandlerClient, scrollBy(testing::_)).Times(0); 551 551 EXPECT_CALL(m_mockCCInputHandlerClient, scrollEnd()).Times(0);
Note: See TracChangeset
for help on using the changeset viewer.