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

Side by Side Diff: content/common/input/event_with_latency_info.cc

Issue 2111593003: Decouple EventWithLatencyInfo from WebInputEventTraits (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bug reference + web_contents_impl iwyu to .cc Created 4 years, 5 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "content/common/input/event_with_latency_info.h"
6
7 #include <bitset>
8 #include <limits>
9
10 using blink::WebGestureEvent;
11 using blink::WebInputEvent;
12 using blink::WebKeyboardEvent;
13 using blink::WebMouseEvent;
14 using blink::WebMouseWheelEvent;
15 using blink::WebTouchEvent;
16 using std::numeric_limits;
17
18 namespace content {
19 namespace {
20
21 const int kInvalidTouchIndex = -1;
22
23 float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) {
24 return accelerated_delta * acceleration_ratio;
25 }
26
27 float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) {
28 if (unaccelerated_delta == 0.f || accelerated_delta == 0.f)
29 return 1.f;
30 return unaccelerated_delta / accelerated_delta;
31 }
32
33 // Returns |kInvalidTouchIndex| iff |event| lacks a touch with an ID of |id|.
34 int GetIndexOfTouchID(const WebTouchEvent& event, int id) {
35 for (unsigned i = 0; i < event.touchesLength; ++i) {
36 if (event.touches[i].id == id)
37 return i;
38 }
39 return kInvalidTouchIndex;
40 }
41
42 WebInputEvent::DispatchType MergeDispatchTypes(
43 WebInputEvent::DispatchType type_1,
44 WebInputEvent::DispatchType type_2) {
45 static_assert(WebInputEvent::DispatchType::Blocking <
46 WebInputEvent::DispatchType::EventNonBlocking,
47 "Enum not ordered correctly");
48 static_assert(WebInputEvent::DispatchType::EventNonBlocking <
49 WebInputEvent::DispatchType::ListenersNonBlockingPassive,
50 "Enum not ordered correctly");
51 static_assert(
52 WebInputEvent::DispatchType::ListenersNonBlockingPassive <
53 WebInputEvent::DispatchType::ListenersForcedNonBlockingPassive,
54 "Enum not ordered correctly");
55 return static_cast<WebInputEvent::DispatchType>(
56 std::min(static_cast<int>(type_1), static_cast<int>(type_2)));
57 }
58
59 } // namespace
60
61 namespace internal {
62
63 bool CanCoalesce(const WebMouseEvent& event_to_coalesce,
64 const WebMouseEvent& event) {
65 return event.type == event_to_coalesce.type &&
66 event.type == WebInputEvent::MouseMove;
67 }
68
69 void Coalesce(const WebMouseEvent& event_to_coalesce, WebMouseEvent* event) {
70 DCHECK(CanCoalesce(event_to_coalesce, *event));
71 // Accumulate movement deltas.
72 int x = event->movementX;
73 int y = event->movementY;
74 *event = event_to_coalesce;
75 event->movementX += x;
76 event->movementY += y;
77 }
78
79 bool CanCoalesce(const WebMouseWheelEvent& event_to_coalesce,
80 const WebMouseWheelEvent& event) {
81 return event.modifiers == event_to_coalesce.modifiers &&
82 event.scrollByPage == event_to_coalesce.scrollByPage &&
83 event.phase == event_to_coalesce.phase &&
84 event.momentumPhase == event_to_coalesce.momentumPhase &&
85 event.hasPreciseScrollingDeltas ==
86 event_to_coalesce.hasPreciseScrollingDeltas;
87 }
88
89 void Coalesce(const WebMouseWheelEvent& event_to_coalesce,
90 WebMouseWheelEvent* event) {
91 DCHECK(CanCoalesce(event_to_coalesce, *event));
92 float unaccelerated_x =
93 GetUnacceleratedDelta(event->deltaX, event->accelerationRatioX) +
94 GetUnacceleratedDelta(event_to_coalesce.deltaX,
95 event_to_coalesce.accelerationRatioX);
96 float unaccelerated_y =
97 GetUnacceleratedDelta(event->deltaY, event->accelerationRatioY) +
98 GetUnacceleratedDelta(event_to_coalesce.deltaY,
99 event_to_coalesce.accelerationRatioY);
100 event->deltaX += event_to_coalesce.deltaX;
101 event->deltaY += event_to_coalesce.deltaY;
102 event->wheelTicksX += event_to_coalesce.wheelTicksX;
103 event->wheelTicksY += event_to_coalesce.wheelTicksY;
104 event->accelerationRatioX =
105 GetAccelerationRatio(event->deltaX, unaccelerated_x);
106 event->accelerationRatioY =
107 GetAccelerationRatio(event->deltaY, unaccelerated_y);
108 }
109
110 bool CanCoalesce(const WebTouchEvent& event_to_coalesce,
111 const WebTouchEvent& event) {
112 if (event.type != event_to_coalesce.type ||
113 event.type != WebInputEvent::TouchMove ||
114 event.modifiers != event_to_coalesce.modifiers ||
115 event.touchesLength != event_to_coalesce.touchesLength ||
116 event.touchesLength > WebTouchEvent::touchesLengthCap)
117 return false;
118
119 static_assert(WebTouchEvent::touchesLengthCap <= sizeof(int32_t) * 8U,
120 "suboptimal touchesLengthCap size");
121 // Ensure that we have a 1-to-1 mapping of pointer ids between touches.
122 std::bitset<WebTouchEvent::touchesLengthCap> unmatched_event_touches(
123 (1 << event.touchesLength) - 1);
124 for (unsigned i = 0; i < event_to_coalesce.touchesLength; ++i) {
125 int event_touch_index =
126 GetIndexOfTouchID(event, event_to_coalesce.touches[i].id);
127 if (event_touch_index == kInvalidTouchIndex)
128 return false;
129 if (!unmatched_event_touches[event_touch_index])
130 return false;
131 unmatched_event_touches[event_touch_index] = false;
132 }
133 return unmatched_event_touches.none();
134 }
135
136 void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) {
137 DCHECK(CanCoalesce(event_to_coalesce, *event));
138 // The WebTouchPoints include absolute position information. So it is
139 // sufficient to simply replace the previous event with the new event->
140 // However, it is necessary to make sure that all the points have the
141 // correct state, i.e. the touch-points that moved in the last event, but
142 // didn't change in the current event, will have Stationary state. It is
143 // necessary to change them back to Moved state.
144 WebTouchEvent old_event = *event;
145 *event = event_to_coalesce;
146 for (unsigned i = 0; i < event->touchesLength; ++i) {
147 int i_old = GetIndexOfTouchID(old_event, event->touches[i].id);
148 if (old_event.touches[i_old].state == blink::WebTouchPoint::StateMoved)
149 event->touches[i].state = blink::WebTouchPoint::StateMoved;
150 }
151 event->movedBeyondSlopRegion |= old_event.movedBeyondSlopRegion;
152 event->dispatchType = MergeDispatchTypes(old_event.dispatchType,
153 event_to_coalesce.dispatchType);
154 }
155
156 bool CanCoalesce(const WebGestureEvent& event_to_coalesce,
157 const WebGestureEvent& event) {
158 if (event.type != event_to_coalesce.type ||
159 event.sourceDevice != event_to_coalesce.sourceDevice ||
160 event.modifiers != event_to_coalesce.modifiers)
161 return false;
162
163 if (event.type == WebInputEvent::GestureScrollUpdate)
164 return true;
165
166 // GesturePinchUpdate scales can be combined only if they share a focal point,
167 // e.g., with double-tap drag zoom.
168 if (event.type == WebInputEvent::GesturePinchUpdate &&
169 event.x == event_to_coalesce.x && event.y == event_to_coalesce.y)
170 return true;
171
172 return false;
173 }
174
175 void Coalesce(const WebGestureEvent& event_to_coalesce,
176 WebGestureEvent* event) {
177 DCHECK(CanCoalesce(event_to_coalesce, *event));
178 if (event->type == WebInputEvent::GestureScrollUpdate) {
179 event->data.scrollUpdate.deltaX +=
180 event_to_coalesce.data.scrollUpdate.deltaX;
181 event->data.scrollUpdate.deltaY +=
182 event_to_coalesce.data.scrollUpdate.deltaY;
183 DCHECK_EQ(
184 event->data.scrollUpdate.previousUpdateInSequencePrevented,
185 event_to_coalesce.data.scrollUpdate.previousUpdateInSequencePrevented);
186 } else if (event->type == WebInputEvent::GesturePinchUpdate) {
187 event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale;
188 // Ensure the scale remains bounded above 0 and below Infinity so that
189 // we can reliably perform operations like log on the values.
190 if (event->data.pinchUpdate.scale < numeric_limits<float>::min())
191 event->data.pinchUpdate.scale = numeric_limits<float>::min();
192 else if (event->data.pinchUpdate.scale > numeric_limits<float>::max())
193 event->data.pinchUpdate.scale = numeric_limits<float>::max();
194 }
195 }
196
197 } // namespace internal
198 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698