1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC) 29 30#import "ScrollingCoordinatorMac.h" 31 32#include "FrameView.h" 33#include "MainFrame.h" 34#include "Page.h" 35#include "PlatformWheelEvent.h" 36#include "Region.h" 37#include "ScrollingStateTree.h" 38#include "ScrollingThread.h" 39#include "ScrollingTreeFixedNode.h" 40#include "ScrollingTreeFrameScrollingNodeMac.h" 41#include "ScrollingTreeMac.h" 42#include "ScrollingTreeStickyNode.h" 43#include "TiledBacking.h" 44#include <wtf/Functional.h> 45#include <wtf/MainThread.h> 46#include <wtf/PassRefPtr.h> 47 48namespace WebCore { 49 50PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page) 51{ 52 return adoptRef(new ScrollingCoordinatorMac(page)); 53} 54 55ScrollingCoordinatorMac::ScrollingCoordinatorMac(Page* page) 56 : AsyncScrollingCoordinator(page) 57 , m_scrollingStateTreeCommitterTimer(this, &ScrollingCoordinatorMac::scrollingStateTreeCommitterTimerFired) 58{ 59 setScrollingTree(ScrollingTreeMac::create(this)); 60} 61 62ScrollingCoordinatorMac::~ScrollingCoordinatorMac() 63{ 64 ASSERT(!scrollingTree()); 65} 66 67void ScrollingCoordinatorMac::pageDestroyed() 68{ 69 AsyncScrollingCoordinator::pageDestroyed(); 70 71 m_scrollingStateTreeCommitterTimer.stop(); 72 73 // Invalidating the scrolling tree will break the reference cycle between the ScrollingCoordinator and ScrollingTree objects. 74 RefPtr<ThreadedScrollingTree> scrollingTree = static_pointer_cast<ThreadedScrollingTree>(releaseScrollingTree()); 75 ScrollingThread::dispatch(bind(&ThreadedScrollingTree::invalidate, scrollingTree)); 76} 77 78void ScrollingCoordinatorMac::commitTreeStateIfNeeded() 79{ 80 if (!scrollingStateTree()->hasChangedProperties()) 81 return; 82 83 commitTreeState(); 84 m_scrollingStateTreeCommitterTimer.stop(); 85} 86 87bool ScrollingCoordinatorMac::handleWheelEvent(FrameView*, const PlatformWheelEvent& wheelEvent) 88{ 89 ASSERT(isMainThread()); 90 ASSERT(m_page); 91 92 if (scrollingTree()->willWheelEventStartSwipeGesture(wheelEvent)) 93 return false; 94 95 ScrollingThread::dispatch(bind(&ThreadedScrollingTree::handleWheelEvent, toThreadedScrollingTree(scrollingTree()), wheelEvent)); 96 return true; 97} 98 99void ScrollingCoordinatorMac::scheduleTreeStateCommit() 100{ 101 ASSERT(scrollingStateTree()->hasChangedProperties()); 102 103 if (m_scrollingStateTreeCommitterTimer.isActive()) 104 return; 105 106 m_scrollingStateTreeCommitterTimer.startOneShot(0); 107} 108 109void ScrollingCoordinatorMac::scrollingStateTreeCommitterTimerFired(Timer<ScrollingCoordinatorMac>*) 110{ 111 commitTreeState(); 112} 113 114void ScrollingCoordinatorMac::commitTreeState() 115{ 116 ASSERT(scrollingStateTree()->hasChangedProperties()); 117 118 OwnPtr<ScrollingStateTree> treeState = scrollingStateTree()->commit(LayerRepresentation::PlatformLayerRepresentation); 119 ScrollingThread::dispatch(bind(&ThreadedScrollingTree::commitNewTreeState, toThreadedScrollingTree(scrollingTree()), treeState.release())); 120 121 updateTiledScrollingIndicator(); 122} 123 124void ScrollingCoordinatorMac::updateTiledScrollingIndicator() 125{ 126 FrameView* frameView = m_page->mainFrame().view(); 127 if (!frameView) 128 return; 129 130 TiledBacking* tiledBacking = frameView->tiledBacking(); 131 if (!tiledBacking) 132 return; 133 134 ScrollingModeIndication indicatorMode; 135 if (shouldUpdateScrollLayerPositionSynchronously()) 136 indicatorMode = SynchronousScrollingBecauseOfStyleIndication; 137 else if (scrollingStateTree()->rootStateNode() && scrollingStateTree()->rootStateNode()->wheelEventHandlerCount()) 138 indicatorMode = SynchronousScrollingBecauseOfEventHandlersIndication; 139 else 140 indicatorMode = AsyncScrollingIndication; 141 142 tiledBacking->setScrollingModeIndication(indicatorMode); 143} 144 145} // namespace WebCore 146 147#endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC) 148