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

Side by Side Diff: content/renderer/input/main_thread_event_queue.cc

Issue 2450833003: Separate rAF aligned Touch and Mouse Input settings (Closed)
Patch Set: Fix 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 2016 The Chromium Authors. All rights reserved. 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 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 #include "content/renderer/input/main_thread_event_queue.h" 5 #include "content/renderer/input/main_thread_event_queue.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "content/common/input/event_with_latency_info.h" 8 #include "content/common/input/event_with_latency_info.h"
9 #include "content/common/input_messages.h" 9 #include "content/common/input_messages.h"
10 10
11 namespace content { 11 namespace content {
12 12
13 namespace { 13 namespace {
14 14
15 const size_t kTenSeconds = 10 * 1000 * 1000; 15 const size_t kTenSeconds = 10 * 1000 * 1000;
16 16
17 bool isContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) { 17 bool IsContinuousEvent(const std::unique_ptr<EventWithDispatchType>& event) {
18 switch (event->event().type) { 18 switch (event->event().type) {
19 case blink::WebInputEvent::MouseMove: 19 case blink::WebInputEvent::MouseMove:
20 case blink::WebInputEvent::MouseWheel: 20 case blink::WebInputEvent::MouseWheel:
21 return true; 21 return true;
22 case blink::WebInputEvent::TouchMove: 22 case blink::WebInputEvent::TouchMove:
23 // TouchMoves that are blocking end up blocking scroll. Do not treat 23 // TouchMoves that are blocking end up blocking scroll. Do not treat
24 // them as continuous events otherwise we will end up waiting up to an 24 // them as continuous events otherwise we will end up waiting up to an
25 // additional frame. 25 // additional frame.
26 return static_cast<const blink::WebTouchEvent&>(event->event()) 26 return static_cast<const blink::WebTouchEvent&>(event->event())
27 .dispatchType != blink::WebInputEvent::Blocking; 27 .dispatchType != blink::WebInputEvent::Blocking;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 int routing_id, 65 int routing_id,
66 MainThreadEventQueueClient* client, 66 MainThreadEventQueueClient* client,
67 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner, 67 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
68 blink::scheduler::RendererScheduler* renderer_scheduler) 68 blink::scheduler::RendererScheduler* renderer_scheduler)
69 : routing_id_(routing_id), 69 : routing_id_(routing_id),
70 client_(client), 70 client_(client),
71 is_flinging_(false), 71 is_flinging_(false),
72 last_touch_start_forced_nonblocking_due_to_fling_(false), 72 last_touch_start_forced_nonblocking_due_to_fling_(false),
73 enable_fling_passive_listener_flag_(base::FeatureList::IsEnabled( 73 enable_fling_passive_listener_flag_(base::FeatureList::IsEnabled(
74 features::kPassiveEventListenersDueToFling)), 74 features::kPassiveEventListenersDueToFling)),
75 handle_raf_aligned_input_( 75 handle_raf_aligned_touch_input_(
76 base::FeatureList::IsEnabled(features::kRafAlignedInputEvents)), 76 base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents)),
77 handle_raf_aligned_mouse_input_(
78 base::FeatureList::IsEnabled(features::kRafAlignedMouseInputEvents)),
77 main_task_runner_(main_task_runner), 79 main_task_runner_(main_task_runner),
78 renderer_scheduler_(renderer_scheduler) {} 80 renderer_scheduler_(renderer_scheduler) {}
79 81
80 MainThreadEventQueue::~MainThreadEventQueue() {} 82 MainThreadEventQueue::~MainThreadEventQueue() {}
81 83
82 bool MainThreadEventQueue::HandleEvent( 84 bool MainThreadEventQueue::HandleEvent(
83 ui::ScopedWebInputEvent event, 85 ui::ScopedWebInputEvent event,
84 const ui::LatencyInfo& latency, 86 const ui::LatencyInfo& latency,
85 InputEventDispatchType original_dispatch_type, 87 InputEventDispatchType original_dispatch_type,
86 InputEventAckState ack_result) { 88 InputEventAckState ack_result) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 138
137 // send an ack when we are non-blocking. 139 // send an ack when we are non-blocking.
138 return non_blocking; 140 return non_blocking;
139 } 141 }
140 142
141 void MainThreadEventQueue::DispatchInFlightEvent() { 143 void MainThreadEventQueue::DispatchInFlightEvent() {
142 if (in_flight_event_) { 144 if (in_flight_event_) {
143 // Report the coalesced count only for continuous events; otherwise 145 // Report the coalesced count only for continuous events; otherwise
144 // the zero value would be dominated by non-continuous events. 146 // the zero value would be dominated by non-continuous events.
145 base::TimeTicks now = base::TimeTicks::Now(); 147 base::TimeTicks now = base::TimeTicks::Now();
146 if (isContinuousEvent(in_flight_event_)) { 148 if (IsContinuousEvent(in_flight_event_)) {
147 UMA_HISTOGRAM_CUSTOM_COUNTS( 149 UMA_HISTOGRAM_CUSTOM_COUNTS(
148 "Event.MainThreadEventQueue.Continuous.QueueingTime", 150 "Event.MainThreadEventQueue.Continuous.QueueingTime",
149 (now - in_flight_event_->creationTimestamp()).InMicroseconds(), 1, 151 (now - in_flight_event_->creationTimestamp()).InMicroseconds(), 1,
150 kTenSeconds, 50); 152 kTenSeconds, 50);
151 153
152 UMA_HISTOGRAM_CUSTOM_COUNTS( 154 UMA_HISTOGRAM_CUSTOM_COUNTS(
153 "Event.MainThreadEventQueue.Continuous.FreshnessTime", 155 "Event.MainThreadEventQueue.Continuous.FreshnessTime",
154 (now - in_flight_event_->lastCoalescedTimestamp()).InMicroseconds(), 156 (now - in_flight_event_->lastCoalescedTimestamp()).InMicroseconds(),
155 1, kTenSeconds, 50); 157 1, kTenSeconds, 50);
156 158
(...skipping 14 matching lines...) Expand all
171 173
172 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(), 174 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(),
173 in_flight_event_->latencyInfo(), 175 in_flight_event_->latencyInfo(),
174 dispatch_type); 176 dispatch_type);
175 } 177 }
176 178
177 in_flight_event_.reset(); 179 in_flight_event_.reset();
178 } 180 }
179 181
180 void MainThreadEventQueue::PossiblyScheduleMainFrame() { 182 void MainThreadEventQueue::PossiblyScheduleMainFrame() {
181 if (!handle_raf_aligned_input_) 183 if (IsRafAlignedInputDisabled())
182 return; 184 return;
183 bool needs_main_frame = false; 185 bool needs_main_frame = false;
184 { 186 {
185 base::AutoLock lock(shared_state_lock_); 187 base::AutoLock lock(shared_state_lock_);
186 if (!shared_state_.sent_main_frame_request_ && 188 if (!shared_state_.sent_main_frame_request_ &&
187 !shared_state_.events_.empty() && 189 !shared_state_.events_.empty() &&
188 isContinuousEvent(shared_state_.events_.front())) { 190 IsRafAlignedEvent(shared_state_.events_.front())) {
189 needs_main_frame = !shared_state_.sent_main_frame_request_; 191 needs_main_frame = !shared_state_.sent_main_frame_request_;
190 shared_state_.sent_main_frame_request_ = false; 192 shared_state_.sent_main_frame_request_ = false;
191 } 193 }
192 } 194 }
193 if (needs_main_frame) 195 if (needs_main_frame)
194 client_->NeedsMainFrame(routing_id_); 196 client_->NeedsMainFrame(routing_id_);
195 } 197 }
196 198
197 void MainThreadEventQueue::DispatchSingleEvent() { 199 void MainThreadEventQueue::DispatchSingleEvent() {
198 { 200 {
(...skipping 15 matching lines...) Expand all
214 client_->SendInputEventAck(routing_id_, type, ack_result, id); 216 client_->SendInputEventAck(routing_id_, type, ack_result, id);
215 if (renderer_scheduler_) { 217 if (renderer_scheduler_) {
216 renderer_scheduler_->DidHandleInputEventOnMainThread( 218 renderer_scheduler_->DidHandleInputEventOnMainThread(
217 in_flight_event_->event()); 219 in_flight_event_->event());
218 } 220 }
219 } 221 }
220 } 222 }
221 } 223 }
222 224
223 void MainThreadEventQueue::DispatchRafAlignedInput() { 225 void MainThreadEventQueue::DispatchRafAlignedInput() {
224 if (!handle_raf_aligned_input_) 226 if (IsRafAlignedInputDisabled())
225 return; 227 return;
226 228
227 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process; 229 std::deque<std::unique_ptr<EventWithDispatchType>> events_to_process;
228 { 230 {
229 base::AutoLock lock(shared_state_lock_); 231 base::AutoLock lock(shared_state_lock_);
230 shared_state_.sent_main_frame_request_ = false; 232 shared_state_.sent_main_frame_request_ = false;
231 233
232 while(!shared_state_.events_.empty()) { 234 while(!shared_state_.events_.empty()) {
233 if (!isContinuousEvent(shared_state_.events_.front())) 235 if (!IsRafAlignedEvent(shared_state_.events_.front()))
234 break; 236 break;
235 events_to_process.emplace_back(shared_state_.events_.Pop()); 237 events_to_process.emplace_back(shared_state_.events_.Pop());
236 } 238 }
237 } 239 }
238 240
239 while(!events_to_process.empty()) { 241 while(!events_to_process.empty()) {
240 in_flight_event_ = std::move(events_to_process.front()); 242 in_flight_event_ = std::move(events_to_process.front());
241 events_to_process.pop_front(); 243 events_to_process.pop_front();
242 DispatchInFlightEvent(); 244 DispatchInFlightEvent();
243 } 245 }
244 PossiblyScheduleMainFrame(); 246 PossiblyScheduleMainFrame();
245 } 247 }
246 248
247 void MainThreadEventQueue::SendEventNotificationToMainThread() { 249 void MainThreadEventQueue::SendEventNotificationToMainThread() {
248 main_task_runner_->PostTask( 250 main_task_runner_->PostTask(
249 FROM_HERE, base::Bind(&MainThreadEventQueue::DispatchSingleEvent, this)); 251 FROM_HERE, base::Bind(&MainThreadEventQueue::DispatchSingleEvent, this));
250 } 252 }
251 253
252 void MainThreadEventQueue::QueueEvent( 254 void MainThreadEventQueue::QueueEvent(
253 std::unique_ptr<EventWithDispatchType> event) { 255 std::unique_ptr<EventWithDispatchType> event) {
254 bool is_continuous = isContinuousEvent(event); 256 bool is_raf_aligned = IsRafAlignedEvent(event);
255 size_t send_notification_count = 0; 257 size_t send_notification_count = 0;
256 bool needs_main_frame = false; 258 bool needs_main_frame = false;
257 { 259 {
258 base::AutoLock lock(shared_state_lock_); 260 base::AutoLock lock(shared_state_lock_);
259 size_t size_before = shared_state_.events_.size(); 261 size_t size_before = shared_state_.events_.size();
260 shared_state_.events_.Queue(std::move(event)); 262 shared_state_.events_.Queue(std::move(event));
261 size_t size_after = shared_state_.events_.size(); 263 size_t size_after = shared_state_.events_.size();
264
262 if (size_before != size_after) { 265 if (size_before != size_after) {
263 if (!handle_raf_aligned_input_) { 266 if (IsRafAlignedInputDisabled()) {
264 send_notification_count = 1; 267 send_notification_count = 1;
265 } else if (!is_continuous) { 268 } else if (!is_raf_aligned) {
266 send_notification_count = 1; 269 send_notification_count = 1;
267 // If we had just enqueued a non-rAF input event we will send a series 270 // If we had just enqueued a non-rAF input event we will send a series
268 // of normal post messages to ensure they are all handled right away. 271 // of normal post messages to ensure they are all handled right away.
269 for (size_t pos = size_after - 1; pos >= 1; --pos) { 272 for (size_t pos = size_after - 1; pos >= 1; --pos) {
270 if (isContinuousEvent(shared_state_.events_.at(pos - 1))) 273 if (IsRafAlignedEvent(shared_state_.events_.at(pos - 1)))
271 send_notification_count++; 274 send_notification_count++;
272 else 275 else
273 break; 276 break;
274 } 277 }
275 } else { 278 } else {
276 needs_main_frame = !shared_state_.sent_main_frame_request_; 279 needs_main_frame = !shared_state_.sent_main_frame_request_;
277 shared_state_.sent_main_frame_request_ = true; 280 shared_state_.sent_main_frame_request_ = true;
278 } 281 }
279 } 282 }
280 } 283 }
281 for (size_t i = 0; i < send_notification_count; ++i) 284 for (size_t i = 0; i < send_notification_count; ++i)
282 SendEventNotificationToMainThread(); 285 SendEventNotificationToMainThread();
283 if (needs_main_frame) 286 if (needs_main_frame)
284 client_->NeedsMainFrame(routing_id_); 287 client_->NeedsMainFrame(routing_id_);
285 } 288 }
286 289
290 bool MainThreadEventQueue::IsRafAlignedInputDisabled() {
291 return !handle_raf_aligned_mouse_input_ && !handle_raf_aligned_touch_input_;
292 }
293
294 bool MainThreadEventQueue::IsRafAlignedEvent(
295 const std::unique_ptr<EventWithDispatchType>& event) {
296 switch (event->event().type) {
297 case blink::WebInputEvent::MouseMove:
298 case blink::WebInputEvent::MouseWheel:
299 return handle_raf_aligned_mouse_input_;
300 case blink::WebInputEvent::TouchMove:
301 // TouchMoves that are blocking end up blocking scroll. Do not treat
302 // them as continuous events otherwise we will end up waiting up to an
303 // additional frame.
304 return static_cast<const blink::WebTouchEvent&>(event->event())
305 .dispatchType != blink::WebInputEvent::Blocking &&
306 handle_raf_aligned_touch_input_;
307 default:
308 return false;
309 }
310 }
311
287 } // namespace content 312 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/input/main_thread_event_queue.h ('k') | content/renderer/input/main_thread_event_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698