Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: webkit/compositor/WebCompositorInputHandlerImpl.cpp

Issue 10920056: Make cc_unittests and webkit_compositor_unittests executable always (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename to webkit_compositor_bindings Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6
7 #include "WebCompositorInputHandlerImpl.h"
8
9 #include "CCActiveGestureAnimation.h"
10 #include "CCProxy.h"
11 #include "PlatformGestureCurveTarget.h"
12 #include "TouchpadFlingPlatformGestureCurve.h"
13 #include "TraceEvent.h"
14 #include "WebCompositorImpl.h"
15 #include "WebCompositorInputHandlerClient.h"
16 #include "WebInputEvent.h"
17 #include <wtf/ThreadingPrimitives.h>
18
19 using namespace WebCore;
20
21 namespace WebCore {
22
23 PassOwnPtr<CCInputHandler> CCInputHandler::create(CCInputHandlerClient* inputHan dlerClient)
24 {
25 return WebKit::WebCompositorInputHandlerImpl::create(inputHandlerClient);
26 }
27
28 class PlatformGestureToCCGestureAdapter : public CCGestureCurve, public Platform GestureCurveTarget {
29 public:
30 static PassOwnPtr<CCGestureCurve> create(PassOwnPtr<PlatformGestureCurve> pl atformCurve)
31 {
32 return adoptPtr(new PlatformGestureToCCGestureAdapter(platformCurve));
33 }
34
35 virtual const char* debugName() const
36 {
37 return m_curve->debugName();
38 }
39
40 virtual bool apply(double time, CCGestureCurveTarget* target)
41 {
42 ASSERT(target);
43 m_target = target;
44 return m_curve->apply(time, this);
45 }
46
47 virtual void scrollBy(const IntPoint& scrollDelta)
48 {
49 ASSERT(m_target);
50 m_target->scrollBy(scrollDelta);
51 }
52
53 private:
54 PlatformGestureToCCGestureAdapter(PassOwnPtr<PlatformGestureCurve> curve)
55 : m_curve(curve)
56 , m_target(0)
57 {
58 }
59
60 OwnPtr<PlatformGestureCurve> m_curve;
61 CCGestureCurveTarget* m_target;
62 };
63
64 }
65
66 namespace WebKit {
67
68 // These statics may only be accessed from the compositor thread.
69 int WebCompositorInputHandlerImpl::s_nextAvailableIdentifier = 1;
70 HashSet<WebCompositorInputHandlerImpl*>* WebCompositorInputHandlerImpl::s_compos itors = 0;
71
72 WebCompositorInputHandler* WebCompositorInputHandler::fromIdentifier(int identif ier)
73 {
74 return WebCompositorInputHandlerImpl::fromIdentifier(identifier);
75 }
76
77 PassOwnPtr<WebCompositorInputHandlerImpl> WebCompositorInputHandlerImpl::create( WebCore::CCInputHandlerClient* inputHandlerClient)
78 {
79 return adoptPtr(new WebCompositorInputHandlerImpl(inputHandlerClient));
80 }
81
82 WebCompositorInputHandler* WebCompositorInputHandlerImpl::fromIdentifier(int ide ntifier)
83 {
84 ASSERT(WebCompositorImpl::initialized());
85 ASSERT(CCProxy::isImplThread());
86
87 if (!s_compositors)
88 return 0;
89
90 for (HashSet<WebCompositorInputHandlerImpl*>::iterator it = s_compositors->b egin(); it != s_compositors->end(); ++it) {
91 if ((*it)->identifier() == identifier)
92 return *it;
93 }
94 return 0;
95 }
96
97 WebCompositorInputHandlerImpl::WebCompositorInputHandlerImpl(CCInputHandlerClien t* inputHandlerClient)
98 : m_client(0)
99 , m_identifier(s_nextAvailableIdentifier++)
100 , m_inputHandlerClient(inputHandlerClient)
101 #ifndef NDEBUG
102 , m_expectScrollUpdateEnd(false)
103 , m_expectPinchUpdateEnd(false)
104 #endif
105 , m_gestureScrollStarted(false)
106 {
107 ASSERT(CCProxy::isImplThread());
108
109 if (!s_compositors)
110 s_compositors = new HashSet<WebCompositorInputHandlerImpl*>;
111 s_compositors->add(this);
112 }
113
114 WebCompositorInputHandlerImpl::~WebCompositorInputHandlerImpl()
115 {
116 ASSERT(CCProxy::isImplThread());
117 if (m_client)
118 m_client->willShutdown();
119
120 ASSERT(s_compositors);
121 s_compositors->remove(this);
122 if (!s_compositors->size()) {
123 delete s_compositors;
124 s_compositors = 0;
125 }
126 }
127
128 void WebCompositorInputHandlerImpl::setClient(WebCompositorInputHandlerClient* c lient)
129 {
130 ASSERT(CCProxy::isImplThread());
131 // It's valid to set a new client if we've never had one or to clear the cli ent, but it's not valid to change from having one client to a different one.
132 ASSERT(!m_client || !client);
133 m_client = client;
134 }
135
136 void WebCompositorInputHandlerImpl::handleInputEvent(const WebInputEvent& event)
137 {
138 ASSERT(CCProxy::isImplThread());
139 ASSERT(m_client);
140
141 WebCompositorInputHandlerImpl::EventDisposition disposition = handleInputEve ntInternal(event);
142 switch (disposition) {
143 case DidHandle:
144 m_client->didHandleInputEvent();
145 break;
146 case DidNotHandle:
147 m_client->didNotHandleInputEvent(true /* sendToWidget */);
148 break;
149 case DropEvent:
150 m_client->didNotHandleInputEvent(false /* sendToWidget */);
151 break;
152 }
153 }
154
155 WebCompositorInputHandlerImpl::EventDisposition WebCompositorInputHandlerImpl::h andleInputEventInternal(const WebInputEvent& event)
156 {
157 if (event.type == WebInputEvent::MouseWheel) {
158 const WebMouseWheelEvent& wheelEvent = *static_cast<const WebMouseWheelE vent*>(&event);
159 CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient-> scrollBegin(IntPoint(wheelEvent.x, wheelEvent.y), CCInputHandlerClient::Wheel);
160 switch (scrollStatus) {
161 case CCInputHandlerClient::ScrollStarted: {
162 TRACE_EVENT_INSTANT2("cc", "WebCompositorInputHandlerImpl::handleInp ut wheel scroll", "deltaX", -wheelEvent.deltaX, "deltaY", -wheelEvent.deltaY);
163 m_inputHandlerClient->scrollBy(IntPoint(wheelEvent.x, wheelEvent.y), IntSize(-wheelEvent.deltaX, -wheelEvent.deltaY));
164 m_inputHandlerClient->scrollEnd();
165 return DidHandle;
166 }
167 case CCInputHandlerClient::ScrollIgnored:
168 // FIXME: This should be DropEvent, but in cases where we fail to pr operly sync scrollability it's safer to send the
169 // event to the main thread. Change back to DropEvent once we have s ynchronization bugs sorted out.
170 return DidNotHandle;
171 case CCInputHandlerClient::ScrollOnMainThread:
172 return DidNotHandle;
173 }
174 } else if (event.type == WebInputEvent::GestureScrollBegin) {
175 ASSERT(!m_gestureScrollStarted);
176 ASSERT(!m_expectScrollUpdateEnd);
177 #ifndef NDEBUG
178 m_expectScrollUpdateEnd = true;
179 #endif
180 const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent *>(&event);
181 CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient-> scrollBegin(IntPoint(gestureEvent.x, gestureEvent.y), CCInputHandlerClient::Gest ure);
182 switch (scrollStatus) {
183 case CCInputHandlerClient::ScrollStarted:
184 m_gestureScrollStarted = true;
185 return DidHandle;
186 case CCInputHandlerClient::ScrollOnMainThread:
187 return DidNotHandle;
188 case CCInputHandlerClient::ScrollIgnored:
189 return DropEvent;
190 }
191 } else if (event.type == WebInputEvent::GestureScrollUpdate) {
192 ASSERT(m_expectScrollUpdateEnd);
193
194 if (!m_gestureScrollStarted)
195 return DidNotHandle;
196
197 const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent *>(&event);
198 m_inputHandlerClient->scrollBy(IntPoint(gestureEvent.x, gestureEvent.y), IntSize(-gestureEvent.deltaX, -gestureEvent.deltaY));
199 return DidHandle;
200 } else if (event.type == WebInputEvent::GestureScrollEnd) {
201 ASSERT(m_expectScrollUpdateEnd);
202 #ifndef NDEBUG
203 m_expectScrollUpdateEnd = false;
204 #endif
205 if (!m_gestureScrollStarted)
206 return DidNotHandle;
207
208 m_inputHandlerClient->scrollEnd();
209 m_gestureScrollStarted = false;
210 return DidHandle;
211 } else if (event.type == WebInputEvent::GesturePinchBegin) {
212 ASSERT(!m_expectPinchUpdateEnd);
213 #ifndef NDEBUG
214 m_expectPinchUpdateEnd = true;
215 #endif
216 m_inputHandlerClient->pinchGestureBegin();
217 return DidHandle;
218 } else if (event.type == WebInputEvent::GesturePinchEnd) {
219 ASSERT(m_expectPinchUpdateEnd);
220 #ifndef NDEBUG
221 m_expectPinchUpdateEnd = false;
222 #endif
223 m_inputHandlerClient->pinchGestureEnd();
224 return DidHandle;
225 } else if (event.type == WebInputEvent::GesturePinchUpdate) {
226 ASSERT(m_expectPinchUpdateEnd);
227 const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent *>(&event);
228 m_inputHandlerClient->pinchGestureUpdate(gestureEvent.deltaX, IntPoint(g estureEvent.x, gestureEvent.y));
229 return DidHandle;
230 } else if (event.type == WebInputEvent::GestureFlingStart) {
231 const WebGestureEvent& gestureEvent = *static_cast<const WebGestureEvent *>(&event);
232 return handleGestureFling(gestureEvent);
233 } else if (event.type == WebInputEvent::GestureFlingCancel) {
234 if (cancelCurrentFling())
235 return DidHandle;
236 } else if (WebInputEvent::isKeyboardEventType(event.type)) {
237 cancelCurrentFling();
238 }
239
240 return DidNotHandle;
241 }
242
243 WebCompositorInputHandlerImpl::EventDisposition WebCompositorInputHandlerImpl::h andleGestureFling(const WebGestureEvent& gestureEvent)
244 {
245 CCInputHandlerClient::ScrollStatus scrollStatus = m_inputHandlerClient->scro llBegin(IntPoint(gestureEvent.x, gestureEvent.y), CCInputHandlerClient::Gesture) ;
246 switch (scrollStatus) {
247 case CCInputHandlerClient::ScrollStarted: {
248 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGesture Fling::started");
249 OwnPtr<PlatformGestureCurve> flingCurve = TouchpadFlingPlatformGestureCu rve::create(FloatPoint(gestureEvent.deltaX, gestureEvent.deltaY));
250 m_wheelFlingAnimation = CCActiveGestureAnimation::create(PlatformGesture ToCCGestureAdapter::create(flingCurve.release()), this);
251 m_wheelFlingParameters.delta = WebFloatPoint(gestureEvent.deltaX, gestur eEvent.deltaY);
252 m_wheelFlingParameters.point = WebPoint(gestureEvent.x, gestureEvent.y);
253 m_wheelFlingParameters.globalPoint = WebPoint(gestureEvent.globalX, gest ureEvent.globalY);
254 m_wheelFlingParameters.modifiers = gestureEvent.modifiers;
255 m_inputHandlerClient->scheduleAnimation();
256 return DidHandle;
257 }
258 case CCInputHandlerClient::ScrollOnMainThread: {
259 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGesture Fling::scrollOnMainThread");
260 return DidNotHandle;
261 }
262 case CCInputHandlerClient::ScrollIgnored: {
263 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::handleGesture Fling::ignored");
264 // We still pass the curve to the main thread if there's nothing scrolla ble, in case something
265 // registers a handler before the curve is over.
266 return DidNotHandle;
267 }
268 }
269 return DidNotHandle;
270 }
271
272 int WebCompositorInputHandlerImpl::identifier() const
273 {
274 ASSERT(CCProxy::isImplThread());
275 return m_identifier;
276 }
277
278 void WebCompositorInputHandlerImpl::animate(double monotonicTime)
279 {
280 if (!m_wheelFlingAnimation)
281 return;
282
283 if (!m_wheelFlingParameters.startTime)
284 m_wheelFlingParameters.startTime = monotonicTime;
285
286 if (m_wheelFlingAnimation->animate(monotonicTime))
287 m_inputHandlerClient->scheduleAnimation();
288 else {
289 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::animate::flin gOver");
290 cancelCurrentFling();
291 }
292 }
293
294 bool WebCompositorInputHandlerImpl::cancelCurrentFling()
295 {
296 bool hadFlingAnimation = m_wheelFlingAnimation;
297 TRACE_EVENT_INSTANT1("cc", "WebCompositorInputHandlerImpl::cancelCurrentFlin g", "hadFlingAnimation", hadFlingAnimation);
298 m_wheelFlingAnimation.clear();
299 m_wheelFlingParameters = WebActiveWheelFlingParameters();
300 return hadFlingAnimation;
301 }
302
303 void WebCompositorInputHandlerImpl::scrollBy(const IntPoint& increment)
304 {
305 if (increment == IntPoint::zero())
306 return;
307
308 TRACE_EVENT2("cc", "WebCompositorInputHandlerImpl::scrollBy", "x", increment .x(), "y", increment.y());
309 WebMouseWheelEvent syntheticWheel;
310 syntheticWheel.type = WebInputEvent::MouseWheel;
311 syntheticWheel.deltaX = increment.x();
312 syntheticWheel.deltaY = increment.y();
313 syntheticWheel.hasPreciseScrollingDeltas = true;
314 syntheticWheel.x = m_wheelFlingParameters.point.x;
315 syntheticWheel.y = m_wheelFlingParameters.point.y;
316 syntheticWheel.globalX = m_wheelFlingParameters.globalPoint.x;
317 syntheticWheel.globalY = m_wheelFlingParameters.globalPoint.y;
318 syntheticWheel.modifiers = m_wheelFlingParameters.modifiers;
319
320 WebCompositorInputHandlerImpl::EventDisposition disposition = handleInputEve ntInternal(syntheticWheel);
321 switch (disposition) {
322 case DidHandle:
323 m_wheelFlingParameters.cumulativeScroll.width += increment.x();
324 m_wheelFlingParameters.cumulativeScroll.height += increment.y();
325 case DropEvent:
326 break;
327 case DidNotHandle:
328 TRACE_EVENT_INSTANT0("cc", "WebCompositorInputHandlerImpl::scrollBy::Abo rtFling");
329 // If we got a DidNotHandle, that means we need to deliver wheels on the main thread.
330 // In this case we need to schedule a commit and transfer the fling curv e over to the main
331 // thread and run the rest of the wheels from there.
332 // This can happen when flinging a page that contains a scrollable subar ea that we can't
333 // scroll on the thread if the fling starts outside the subarea but then is flung "under" the
334 // pointer.
335 m_client->transferActiveWheelFlingAnimation(m_wheelFlingParameters);
336 cancelCurrentFling();
337 break;
338 }
339 }
340
341 }
OLDNEW
« no previous file with comments | « webkit/compositor/WebCompositorInputHandlerImpl.h ('k') | webkit/compositor/WebContentLayerImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698