Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / page / scrolling / ThreadedScrollingTree.cpp
1 /*
2  * Copyright (C) 2014-2015 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 #include "ThreadedScrollingTree.h"
28
29 #if ENABLE(ASYNC_SCROLLING)
30
31 #include "AsyncScrollingCoordinator.h"
32 #include "PlatformWheelEvent.h"
33 #include "ScrollingThread.h"
34 #include "ScrollingTreeFixedNode.h"
35 #include "ScrollingTreeNode.h"
36 #include "ScrollingTreeScrollingNode.h"
37 #include "ScrollingTreeStickyNode.h"
38 #include <wtf/RunLoop.h>
39 #include <wtf/TemporaryChange.h>
40
41 namespace WebCore {
42
43 ThreadedScrollingTree::ThreadedScrollingTree(AsyncScrollingCoordinator* scrollingCoordinator)
44     : m_scrollingCoordinator(scrollingCoordinator)
45 {
46 }
47
48 ThreadedScrollingTree::~ThreadedScrollingTree()
49 {
50     // invalidate() should have cleared m_scrollingCoordinator.
51     ASSERT(!m_scrollingCoordinator);
52 }
53
54 ScrollingTree::EventResult ThreadedScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent)
55 {
56     if (shouldHandleWheelEventSynchronously(wheelEvent))
57         return SendToMainThread;
58
59     if (willWheelEventStartSwipeGesture(wheelEvent))
60         return DidNotHandleEvent;
61
62     RefPtr<ThreadedScrollingTree> threadedScrollingTree(this);
63     ScrollingThread::dispatch([threadedScrollingTree, wheelEvent] {
64         threadedScrollingTree->handleWheelEvent(wheelEvent);
65     });
66     
67     return DidHandleEvent;
68 }
69
70 void ThreadedScrollingTree::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
71 {
72     ASSERT(ScrollingThread::isCurrentThread());
73     ScrollingTree::handleWheelEvent(wheelEvent);
74 }
75
76 void ThreadedScrollingTree::invalidate()
77 {
78     // Invalidate is dispatched by the ScrollingCoordinator class on the ScrollingThread
79     // to break the reference cycle between ScrollingTree and ScrollingCoordinator when the
80     // ScrollingCoordinator's page is destroyed.
81     ASSERT(ScrollingThread::isCurrentThread());
82
83     // Since this can potentially be the last reference to the scrolling coordinator,
84     // we need to release it on the main thread since it has member variables (such as timers)
85     // that expect to be destroyed from the main thread.
86     ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinator.release().leakRef();
87     RunLoop::main().dispatch([scrollingCoordinator] {
88         scrollingCoordinator->deref();
89     });
90 }
91
92 void ThreadedScrollingTree::commitNewTreeState(std::unique_ptr<ScrollingStateTree> scrollingStateTree)
93 {
94     ASSERT(ScrollingThread::isCurrentThread());
95     ScrollingTree::commitNewTreeState(WTFMove(scrollingStateTree));
96 }
97
98 void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
99 {
100     if (!m_scrollingCoordinator)
101         return;
102
103     if (nodeID == rootNode()->scrollingNodeID())
104         setMainFrameScrollPosition(scrollPosition);
105
106     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
107     bool localIsHandlingProgrammaticScroll = isHandlingProgrammaticScroll();
108     
109     RunLoop::main().dispatch([scrollingCoordinator, nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction] {
110         scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, localIsHandlingProgrammaticScroll, scrollingLayerPositionAction);
111     });
112 }
113
114 void ThreadedScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical)
115 {
116     if (!m_scrollingCoordinator)
117         return;
118
119     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
120     RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontal, vertical] {
121         scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontal, vertical);
122     });
123 }
124
125 #if PLATFORM(MAC)
126 void ThreadedScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase)
127 {
128     if (!m_scrollingCoordinator)
129         return;
130
131     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
132     RunLoop::main().dispatch([scrollingCoordinator, phase] {
133         scrollingCoordinator->handleWheelEventPhase(phase);
134     });
135 }
136
137 void ThreadedScrollingTree::setActiveScrollSnapIndices(ScrollingNodeID nodeID, unsigned horizontalIndex, unsigned verticalIndex)
138 {
139     if (!m_scrollingCoordinator)
140         return;
141     
142     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
143     RunLoop::main().dispatch([scrollingCoordinator, nodeID, horizontalIndex, verticalIndex] {
144         scrollingCoordinator->setActiveScrollSnapIndices(nodeID, horizontalIndex, verticalIndex);
145     });
146 }
147
148 void ThreadedScrollingTree::deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
149 {
150     if (!m_scrollingCoordinator)
151         return;
152
153     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
154     RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
155         scrollingCoordinator->deferTestsForReason(identifier, reason);
156     });
157 }
158
159 void ThreadedScrollingTree::removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier identifier, WheelEventTestTrigger::DeferTestTriggerReason reason)
160 {
161     if (!m_scrollingCoordinator)
162         return;
163     
164     RefPtr<AsyncScrollingCoordinator> scrollingCoordinator = m_scrollingCoordinator;
165     RunLoop::main().dispatch([scrollingCoordinator, identifier, reason] {
166         scrollingCoordinator->removeTestDeferralForReason(identifier, reason);
167     });
168 }
169
170 #endif
171
172 } // namespace WebCore
173
174 #endif // ENABLE(ASYNC_SCROLLING)