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

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

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

Powered by Google App Engine
This is Rietveld 408576698