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

Side by Side Diff: ui/events/blink/blink_event_util.cc

Issue 2429953002: Implement compositor thread VSync aligned event queue (Closed)
Patch Set: dtapuska&enne's review: Call |Now()| once per loop; Chromium style; Remove parameterized test Created 4 years, 1 month 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
« no previous file with comments | « ui/events/blink/blink_event_util.h ('k') | ui/events/blink/blink_features.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "ui/events/blink/blink_event_util.h" 8 #include "ui/events/blink/blink_event_util.h"
9 9
10 #include <stddef.h> 10 #include <stddef.h>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <bitset>
13 #include <cmath> 14 #include <cmath>
15 #include <limits>
14 16
15 #include "base/time/time.h" 17 #include "base/time/time.h"
16 #include "build/build_config.h" 18 #include "build/build_config.h"
17 #include "third_party/WebKit/public/platform/WebGestureEvent.h" 19 #include "third_party/WebKit/public/platform/WebGestureEvent.h"
18 #include "third_party/WebKit/public/platform/WebInputEvent.h" 20 #include "third_party/WebKit/public/platform/WebInputEvent.h"
19 #include "ui/events/base_event_utils.h" 21 #include "ui/events/base_event_utils.h"
20 #include "ui/events/event_constants.h" 22 #include "ui/events/event_constants.h"
21 #include "ui/events/gesture_detection/gesture_event_data.h" 23 #include "ui/events/gesture_detection/gesture_event_data.h"
22 #include "ui/events/gesture_detection/motion_event.h" 24 #include "ui/events/gesture_detection/motion_event.h"
23 #include "ui/events/gesture_event_details.h" 25 #include "ui/events/gesture_event_details.h"
24 #include "ui/events/keycodes/dom/keycode_converter.h" 26 #include "ui/events/keycodes/dom/keycode_converter.h"
25 #include "ui/gfx/geometry/safe_integer_conversions.h" 27 #include "ui/gfx/geometry/safe_integer_conversions.h"
26 #include "ui/gfx/geometry/vector2d.h" 28 #include "ui/gfx/geometry/vector2d.h"
27 29
28 using blink::WebGestureEvent; 30 using blink::WebGestureEvent;
29 using blink::WebInputEvent; 31 using blink::WebInputEvent;
32 using blink::WebMouseEvent;
33 using blink::WebMouseWheelEvent;
30 using blink::WebPointerProperties; 34 using blink::WebPointerProperties;
31 using blink::WebTouchEvent; 35 using blink::WebTouchEvent;
32 using blink::WebTouchPoint; 36 using blink::WebTouchPoint;
37 using std::numeric_limits;
33 38
34 namespace ui { 39 namespace ui {
35 namespace { 40 namespace {
36 41
42 const int kInvalidTouchIndex = -1;
43
37 WebInputEvent::Type ToWebTouchEventType(MotionEvent::Action action) { 44 WebInputEvent::Type ToWebTouchEventType(MotionEvent::Action action) {
38 switch (action) { 45 switch (action) {
39 case MotionEvent::ACTION_DOWN: 46 case MotionEvent::ACTION_DOWN:
40 return WebInputEvent::TouchStart; 47 return WebInputEvent::TouchStart;
41 case MotionEvent::ACTION_MOVE: 48 case MotionEvent::ACTION_MOVE:
42 return WebInputEvent::TouchMove; 49 return WebInputEvent::TouchMove;
43 case MotionEvent::ACTION_UP: 50 case MotionEvent::ACTION_UP:
44 return WebInputEvent::TouchEnd; 51 return WebInputEvent::TouchEnd;
45 case MotionEvent::ACTION_CANCEL: 52 case MotionEvent::ACTION_CANCEL:
46 return WebInputEvent::TouchCancel; 53 return WebInputEvent::TouchCancel;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 touch.rotationAngle = orientation_deg; 195 touch.rotationAngle = orientation_deg;
189 } else { 196 } else {
190 touch.radiusX = major_radius; 197 touch.radiusX = major_radius;
191 touch.radiusY = minor_radius; 198 touch.radiusY = minor_radius;
192 touch.rotationAngle = orientation_deg + 90; 199 touch.rotationAngle = orientation_deg + 90;
193 } 200 }
194 201
195 return touch; 202 return touch;
196 } 203 }
197 204
205 float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) {
206 return accelerated_delta * acceleration_ratio;
207 }
208
209 float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) {
210 if (unaccelerated_delta == 0.f || accelerated_delta == 0.f)
211 return 1.f;
212 return unaccelerated_delta / accelerated_delta;
213 }
214
215 // Returns |kInvalidTouchIndex| iff |event| lacks a touch with an ID of |id|.
216 int GetIndexOfTouchID(const WebTouchEvent& event, int id) {
217 for (unsigned i = 0; i < event.touchesLength; ++i) {
218 if (event.touches[i].id == id)
219 return i;
220 }
221 return kInvalidTouchIndex;
222 }
223
224 WebInputEvent::DispatchType MergeDispatchTypes(
225 WebInputEvent::DispatchType type_1,
226 WebInputEvent::DispatchType type_2) {
227 static_assert(WebInputEvent::DispatchType::Blocking <
228 WebInputEvent::DispatchType::EventNonBlocking,
229 "Enum not ordered correctly");
230 static_assert(WebInputEvent::DispatchType::EventNonBlocking <
231 WebInputEvent::DispatchType::ListenersNonBlockingPassive,
232 "Enum not ordered correctly");
233 static_assert(
234 WebInputEvent::DispatchType::ListenersNonBlockingPassive <
235 WebInputEvent::DispatchType::ListenersForcedNonBlockingDueToFling,
236 "Enum not ordered correctly");
237 return static_cast<WebInputEvent::DispatchType>(
238 std::min(static_cast<int>(type_1), static_cast<int>(type_2)));
239 }
240
241 bool CanCoalesce(const WebMouseEvent& event_to_coalesce,
242 const WebMouseEvent& event) {
243 return event.type == event_to_coalesce.type &&
244 event.type == WebInputEvent::MouseMove;
245 }
246
247 void Coalesce(const WebMouseEvent& event_to_coalesce, WebMouseEvent* event) {
248 DCHECK(CanCoalesce(event_to_coalesce, *event));
249 // Accumulate movement deltas.
250 int x = event->movementX;
251 int y = event->movementY;
252 *event = event_to_coalesce;
253 event->movementX += x;
254 event->movementY += y;
255 }
256
257 bool CanCoalesce(const WebMouseWheelEvent& event_to_coalesce,
258 const WebMouseWheelEvent& event) {
259 return event.modifiers == event_to_coalesce.modifiers &&
260 event.scrollByPage == event_to_coalesce.scrollByPage &&
261 event.phase == event_to_coalesce.phase &&
262 event.momentumPhase == event_to_coalesce.momentumPhase &&
263 event.hasPreciseScrollingDeltas ==
264 event_to_coalesce.hasPreciseScrollingDeltas;
265 }
266
267 void Coalesce(const WebMouseWheelEvent& event_to_coalesce,
268 WebMouseWheelEvent* event) {
269 DCHECK(CanCoalesce(event_to_coalesce, *event));
270 float unaccelerated_x =
271 GetUnacceleratedDelta(event->deltaX, event->accelerationRatioX) +
272 GetUnacceleratedDelta(event_to_coalesce.deltaX,
273 event_to_coalesce.accelerationRatioX);
274 float unaccelerated_y =
275 GetUnacceleratedDelta(event->deltaY, event->accelerationRatioY) +
276 GetUnacceleratedDelta(event_to_coalesce.deltaY,
277 event_to_coalesce.accelerationRatioY);
278 float old_deltaX = event->deltaX;
279 float old_deltaY = event->deltaY;
280 float old_wheelTicksX = event->wheelTicksX;
281 float old_wheelTicksY = event->wheelTicksY;
282 float old_movementX = event->movementX;
283 float old_movementY = event->movementY;
284 *event = event_to_coalesce;
285 event->deltaX += old_deltaX;
286 event->deltaY += old_deltaY;
287 event->wheelTicksX += old_wheelTicksX;
288 event->wheelTicksY += old_wheelTicksY;
289 event->movementX += old_movementX;
290 event->movementY += old_movementY;
291 event->accelerationRatioX =
292 GetAccelerationRatio(event->deltaX, unaccelerated_x);
293 event->accelerationRatioY =
294 GetAccelerationRatio(event->deltaY, unaccelerated_y);
295 }
296
297 bool CanCoalesce(const WebTouchEvent& event_to_coalesce,
298 const WebTouchEvent& event) {
299 if (event.type != event_to_coalesce.type ||
300 event.type != WebInputEvent::TouchMove ||
301 event.modifiers != event_to_coalesce.modifiers ||
302 event.touchesLength != event_to_coalesce.touchesLength ||
303 event.touchesLength > WebTouchEvent::kTouchesLengthCap)
304 return false;
305
306 static_assert(WebTouchEvent::kTouchesLengthCap <= sizeof(int32_t) * 8U,
307 "suboptimal kTouchesLengthCap size");
308 // Ensure that we have a 1-to-1 mapping of pointer ids between touches.
309 std::bitset<WebTouchEvent::kTouchesLengthCap> unmatched_event_touches(
310 (1 << event.touchesLength) - 1);
311 for (unsigned i = 0; i < event_to_coalesce.touchesLength; ++i) {
312 int event_touch_index =
313 GetIndexOfTouchID(event, event_to_coalesce.touches[i].id);
314 if (event_touch_index == kInvalidTouchIndex)
315 return false;
316 if (!unmatched_event_touches[event_touch_index])
317 return false;
318 unmatched_event_touches[event_touch_index] = false;
319 }
320 return unmatched_event_touches.none();
321 }
322
323 void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) {
324 DCHECK(CanCoalesce(event_to_coalesce, *event));
325 // The WebTouchPoints include absolute position information. So it is
326 // sufficient to simply replace the previous event with the new event->
327 // However, it is necessary to make sure that all the points have the
328 // correct state, i.e. the touch-points that moved in the last event, but
329 // didn't change in the current event, will have Stationary state. It is
330 // necessary to change them back to Moved state.
331 WebTouchEvent old_event = *event;
332 *event = event_to_coalesce;
333 for (unsigned i = 0; i < event->touchesLength; ++i) {
334 int i_old = GetIndexOfTouchID(old_event, event->touches[i].id);
335 if (old_event.touches[i_old].state == blink::WebTouchPoint::StateMoved)
336 event->touches[i].state = blink::WebTouchPoint::StateMoved;
337 }
338 event->movedBeyondSlopRegion |= old_event.movedBeyondSlopRegion;
339 event->dispatchType = MergeDispatchTypes(old_event.dispatchType,
340 event_to_coalesce.dispatchType);
341 }
342
343 bool CanCoalesce(const WebGestureEvent& event_to_coalesce,
344 const WebGestureEvent& event) {
345 if (event.type != event_to_coalesce.type ||
346 event.sourceDevice != event_to_coalesce.sourceDevice ||
347 event.modifiers != event_to_coalesce.modifiers)
348 return false;
349
350 if (event.type == WebInputEvent::GestureScrollUpdate)
351 return true;
352
353 // GesturePinchUpdate scales can be combined only if they share a focal point,
354 // e.g., with double-tap drag zoom.
355 if (event.type == WebInputEvent::GesturePinchUpdate &&
356 event.x == event_to_coalesce.x && event.y == event_to_coalesce.y)
357 return true;
358
359 return false;
360 }
361
362 void Coalesce(const WebGestureEvent& event_to_coalesce,
363 WebGestureEvent* event) {
364 DCHECK(CanCoalesce(event_to_coalesce, *event));
365 if (event->type == WebInputEvent::GestureScrollUpdate) {
366 event->data.scrollUpdate.deltaX +=
367 event_to_coalesce.data.scrollUpdate.deltaX;
368 event->data.scrollUpdate.deltaY +=
369 event_to_coalesce.data.scrollUpdate.deltaY;
370 DCHECK_EQ(
371 event->data.scrollUpdate.previousUpdateInSequencePrevented,
372 event_to_coalesce.data.scrollUpdate.previousUpdateInSequencePrevented);
373 } else if (event->type == WebInputEvent::GesturePinchUpdate) {
374 event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale;
375 // Ensure the scale remains bounded above 0 and below Infinity so that
376 // we can reliably perform operations like log on the values.
377 if (event->data.pinchUpdate.scale < numeric_limits<float>::min())
378 event->data.pinchUpdate.scale = numeric_limits<float>::min();
379 else if (event->data.pinchUpdate.scale > numeric_limits<float>::max())
380 event->data.pinchUpdate.scale = numeric_limits<float>::max();
381 }
382 }
383
198 } // namespace 384 } // namespace
199 385
386 bool CanCoalesce(const blink::WebInputEvent& event_to_coalesce,
387 const blink::WebInputEvent& event) {
388 if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) &&
389 blink::WebInputEvent::isGestureEventType(event.type)) {
390 return CanCoalesce(
391 static_cast<const blink::WebGestureEvent&>(event_to_coalesce),
392 static_cast<const blink::WebGestureEvent&>(event));
393 }
394 if (blink::WebInputEvent::isMouseEventType(event_to_coalesce.type) &&
395 blink::WebInputEvent::isMouseEventType(event.type)) {
396 return CanCoalesce(
397 static_cast<const blink::WebMouseEvent&>(event_to_coalesce),
398 static_cast<const blink::WebMouseEvent&>(event));
399 }
400 if (blink::WebInputEvent::isTouchEventType(event_to_coalesce.type) &&
401 blink::WebInputEvent::isTouchEventType(event.type)) {
402 return CanCoalesce(
403 static_cast<const blink::WebTouchEvent&>(event_to_coalesce),
404 static_cast<const blink::WebTouchEvent&>(event));
405 }
406 if (event_to_coalesce.type == blink::WebInputEvent::MouseWheel &&
407 event.type == blink::WebInputEvent::MouseWheel) {
408 return CanCoalesce(
409 static_cast<const blink::WebMouseWheelEvent&>(event_to_coalesce),
410 static_cast<const blink::WebMouseWheelEvent&>(event));
411 }
412 return false;
413 }
414
415 void Coalesce(const blink::WebInputEvent& event_to_coalesce,
416 blink::WebInputEvent* event) {
417 if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) &&
418 blink::WebInputEvent::isGestureEventType(event->type)) {
419 Coalesce(static_cast<const blink::WebGestureEvent&>(event_to_coalesce),
420 static_cast<blink::WebGestureEvent*>(event));
421 return;
422 }
423 if (blink::WebInputEvent::isMouseEventType(event_to_coalesce.type) &&
424 blink::WebInputEvent::isMouseEventType(event->type)) {
425 Coalesce(static_cast<const blink::WebMouseEvent&>(event_to_coalesce),
426 static_cast<blink::WebMouseEvent*>(event));
427 return;
428 }
429 if (blink::WebInputEvent::isTouchEventType(event_to_coalesce.type) &&
430 blink::WebInputEvent::isTouchEventType(event->type)) {
431 Coalesce(static_cast<const blink::WebTouchEvent&>(event_to_coalesce),
432 static_cast<blink::WebTouchEvent*>(event));
433 return;
434 }
435 if (event_to_coalesce.type == blink::WebInputEvent::MouseWheel &&
436 event->type == blink::WebInputEvent::MouseWheel) {
437 Coalesce(static_cast<const blink::WebMouseWheelEvent&>(event_to_coalesce),
438 static_cast<blink::WebMouseWheelEvent*>(event));
439 }
440 }
441
200 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( 442 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent(
201 const MotionEvent& event, 443 const MotionEvent& event,
202 bool moved_beyond_slop_region) { 444 bool moved_beyond_slop_region) {
203 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) == 445 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) ==
204 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap), 446 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap),
205 "inconsistent maximum number of active touch points"); 447 "inconsistent maximum number of active touch points");
206 448
207 blink::WebTouchEvent result; 449 blink::WebTouchEvent result;
208 450
209 result.type = ToWebTouchEventType(event.GetAction()); 451 result.type = ToWebTouchEventType(event.GetAction());
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 case DomKeyLocation::RIGHT: 851 case DomKeyLocation::RIGHT:
610 return blink::WebInputEvent::IsRight; 852 return blink::WebInputEvent::IsRight;
611 case DomKeyLocation::NUMPAD: 853 case DomKeyLocation::NUMPAD:
612 return blink::WebInputEvent::IsKeyPad; 854 return blink::WebInputEvent::IsKeyPad;
613 case DomKeyLocation::STANDARD: 855 case DomKeyLocation::STANDARD:
614 break; 856 break;
615 } 857 }
616 return static_cast<blink::WebInputEvent::Modifiers>(0); 858 return static_cast<blink::WebInputEvent::Modifiers>(0);
617 } 859 }
618 860
861 bool IsGestureScollOrPinch(WebInputEvent::Type type) {
862 switch (type) {
863 case blink::WebGestureEvent::GestureScrollBegin:
864 case blink::WebGestureEvent::GestureScrollUpdate:
865 case blink::WebGestureEvent::GestureScrollEnd:
866 case blink::WebGestureEvent::GesturePinchBegin:
867 case blink::WebGestureEvent::GesturePinchUpdate:
868 case blink::WebGestureEvent::GesturePinchEnd:
869 return true;
870 default:
871 return false;
872 }
873 }
874
875 bool IsContinuousGestureEvent(WebInputEvent::Type type) {
876 switch (type) {
877 case blink::WebGestureEvent::GestureScrollUpdate:
878 case blink::WebGestureEvent::GesturePinchUpdate:
879 return true;
880 default:
881 return false;
882 }
883 }
884
619 } // namespace ui 885 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/blink/blink_event_util.h ('k') | ui/events/blink/blink_features.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698