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

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

Issue 2429953002: Implement compositor thread VSync aligned event queue (Closed)
Patch Set: dtapuska's review: Non-template CompositorThreadEventQueue; Added blink_features.h; UMA only when e… 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "ui/events/blink/input_handler_proxy.h" 5 #include "ui/events/blink/input_handler_proxy.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "base/auto_reset.h" 11 #include "base/auto_reset.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/ptr_util.h"
15 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
16 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
19 #include "cc/input/main_thread_scrolling_reason.h" 20 #include "cc/input/main_thread_scrolling_reason.h"
20 #include "third_party/WebKit/public/platform/WebInputEvent.h" 21 #include "third_party/WebKit/public/platform/WebInputEvent.h"
22 #include "ui/events/blink/compositor_thread_event_queue.h"
21 #include "ui/events/blink/did_overscroll_params.h" 23 #include "ui/events/blink/did_overscroll_params.h"
24 #include "ui/events/blink/event_with_callback.h"
22 #include "ui/events/blink/input_handler_proxy_client.h" 25 #include "ui/events/blink/input_handler_proxy_client.h"
23 #include "ui/events/blink/input_scroll_elasticity_controller.h" 26 #include "ui/events/blink/input_scroll_elasticity_controller.h"
24 #include "ui/events/blink/web_input_event_traits.h" 27 #include "ui/events/blink/web_input_event_traits.h"
25 #include "ui/events/latency_info.h" 28 #include "ui/events/latency_info.h"
26 #include "ui/gfx/geometry/point_conversions.h" 29 #include "ui/gfx/geometry/point_conversions.h"
27 30
28 using blink::WebFloatPoint; 31 using blink::WebFloatPoint;
29 using blink::WebFloatSize; 32 using blink::WebFloatSize;
30 using blink::WebGestureEvent; 33 using blink::WebGestureEvent;
31 using blink::WebInputEvent; 34 using blink::WebInputEvent;
(...skipping 23 matching lines...) Expand all
55 // Minimum velocity for the active touch scroll to preserve (boost) an active 58 // Minimum velocity for the active touch scroll to preserve (boost) an active
56 // fling for which cancellation has been deferred. 59 // fling for which cancellation has been deferred.
57 const double kMinBoostTouchScrollSpeedSquare = 150 * 150.; 60 const double kMinBoostTouchScrollSpeedSquare = 150 * 150.;
58 61
59 // Timeout window after which the active fling will be cancelled if no animation 62 // Timeout window after which the active fling will be cancelled if no animation
60 // ticks, scrolls or flings of sufficient velocity relative to the current fling 63 // ticks, scrolls or flings of sufficient velocity relative to the current fling
61 // are received. The default value on Android native views is 40ms, but we use a 64 // are received. The default value on Android native views is 40ms, but we use a
62 // slightly increased value to accomodate small IPC message delays. 65 // slightly increased value to accomodate small IPC message delays.
63 const double kFlingBoostTimeoutDelaySeconds = 0.05; 66 const double kFlingBoostTimeoutDelaySeconds = 0.05;
64 67
68 const size_t kTenSeconds = 10 * 1000 * 1000;
69
65 gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) { 70 gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) {
66 return gfx::Vector2dF(-increment.width, -increment.height); 71 return gfx::Vector2dF(-increment.width, -increment.height);
67 } 72 }
68 73
69 double InSecondsF(const base::TimeTicks& time) { 74 double InSecondsF(const base::TimeTicks& time) {
70 return (time - base::TimeTicks()).InSecondsF(); 75 return (time - base::TimeTicks()).InSecondsF();
71 } 76 }
72 77
73 bool ShouldSuppressScrollForFlingBoosting( 78 bool ShouldSuppressScrollForFlingBoosting(
74 const gfx::Vector2dF& current_fling_velocity, 79 const gfx::Vector2dF& current_fling_velocity,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 223 }
219 } 224 }
220 225
221 cc::InputHandler::ScrollInputType GestureScrollInputType( 226 cc::InputHandler::ScrollInputType GestureScrollInputType(
222 blink::WebGestureDevice device) { 227 blink::WebGestureDevice device) {
223 return device == blink::WebGestureDeviceTouchpad 228 return device == blink::WebGestureDeviceTouchpad
224 ? cc::InputHandler::WHEEL 229 ? cc::InputHandler::WHEEL
225 : cc::InputHandler::TOUCHSCREEN; 230 : cc::InputHandler::TOUCHSCREEN;
226 } 231 }
227 232
233 bool IsGestureScollOrPinch(WebInputEvent::Type type) {
234 switch (type) {
235 case blink::WebGestureEvent::GestureScrollBegin:
236 case blink::WebGestureEvent::GestureScrollUpdate:
237 case blink::WebGestureEvent::GestureScrollEnd:
238 case blink::WebGestureEvent::GesturePinchBegin:
239 case blink::WebGestureEvent::GesturePinchUpdate:
240 case blink::WebGestureEvent::GesturePinchEnd:
241 return true;
242 default:
243 return false;
244 }
245 }
246
247 bool IsContinuousEvent(WebInputEvent::Type type) {
248 switch (type) {
249 case blink::WebGestureEvent::GestureScrollUpdate:
250 case blink::WebGestureEvent::GesturePinchUpdate:
251 return true;
252 default:
253 return false;
254 }
255 }
256
228 } // namespace 257 } // namespace
229 258
230 namespace ui { 259 namespace ui {
231 260
232 InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler, 261 InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler,
233 InputHandlerProxyClient* client) 262 InputHandlerProxyClient* client)
234 : client_(client), 263 : client_(client),
235 input_handler_(input_handler), 264 input_handler_(input_handler),
236 deferred_fling_cancel_time_seconds_(0), 265 deferred_fling_cancel_time_seconds_(0),
237 synchronous_input_handler_(nullptr), 266 synchronous_input_handler_(nullptr),
238 allow_root_animate_(true), 267 allow_root_animate_(true),
239 #ifndef NDEBUG 268 #ifndef NDEBUG
240 expect_scroll_update_end_(false), 269 expect_scroll_update_end_(false),
241 #endif 270 #endif
242 gesture_scroll_on_impl_thread_(false), 271 gesture_scroll_on_impl_thread_(false),
243 gesture_pinch_on_impl_thread_(false), 272 gesture_pinch_on_impl_thread_(false),
244 fling_may_be_active_on_main_thread_(false), 273 fling_may_be_active_on_main_thread_(false),
245 disallow_horizontal_fling_scroll_(false), 274 disallow_horizontal_fling_scroll_(false),
246 disallow_vertical_fling_scroll_(false), 275 disallow_vertical_fling_scroll_(false),
247 has_fling_animation_started_(false), 276 has_fling_animation_started_(false),
248 smooth_scroll_enabled_(false), 277 smooth_scroll_enabled_(false),
249 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()), 278 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()),
250 touch_start_result_(kEventDispositionUndefined), 279 touch_start_result_(kEventDispositionUndefined),
251 current_overscroll_params_(nullptr) { 280 current_overscroll_params_(nullptr),
281 has_ongoing_compositor_scroll_pinch(false),
282 compositor_event_queue_enabled_(
283 base::FeatureList::IsEnabled(features::kVsyncAlignedInputEvents)) {
252 DCHECK(client); 284 DCHECK(client);
253 input_handler_->BindToClient(this); 285 input_handler_->BindToClient(this);
254 cc::ScrollElasticityHelper* scroll_elasticity_helper = 286 cc::ScrollElasticityHelper* scroll_elasticity_helper =
255 input_handler_->CreateScrollElasticityHelper(); 287 input_handler_->CreateScrollElasticityHelper();
256 if (scroll_elasticity_helper) { 288 if (scroll_elasticity_helper) {
257 scroll_elasticity_controller_.reset( 289 scroll_elasticity_controller_.reset(
258 new InputScrollElasticityController(scroll_elasticity_helper)); 290 new InputScrollElasticityController(scroll_elasticity_helper));
259 } 291 }
292 if (compositor_event_queue_enabled_) {
293 event_queue_ = base::MakeUnique<CompositorThreadEventQueue>();
294 }
260 } 295 }
261 296
262 InputHandlerProxy::~InputHandlerProxy() {} 297 InputHandlerProxy::~InputHandlerProxy() {}
263 298
264 void InputHandlerProxy::WillShutdown() { 299 void InputHandlerProxy::WillShutdown() {
265 scroll_elasticity_controller_.reset(); 300 scroll_elasticity_controller_.reset();
266 input_handler_ = NULL; 301 input_handler_ = NULL;
267 client_->WillShutdown(); 302 client_->WillShutdown();
268 } 303 }
269 304
270 void InputHandlerProxy::HandleInputEventWithLatencyInfo( 305 void InputHandlerProxy::HandleInputEventWithLatencyInfo(
271 ScopedWebInputEvent event, 306 ScopedWebInputEvent event,
272 const LatencyInfo& latency_info, 307 const LatencyInfo& latency_info,
273 const EventDispositionCallback& callback) { 308 const EventDispositionCallback& callback) {
274 DCHECK(input_handler_); 309 DCHECK(input_handler_);
275 310
276 if (uma_latency_reporting_enabled_) 311 if (uma_latency_reporting_enabled_)
277 ReportInputEventLatencyUma(*event, latency_info); 312 ReportInputEventLatencyUma(*event, latency_info);
278 313
279 TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", 314 TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow",
280 TRACE_ID_DONT_MANGLE(latency_info.trace_id()), 315 TRACE_ID_DONT_MANGLE(latency_info.trace_id()),
281 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, 316 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
282 "step", "HandleInputEventImpl"); 317 "step", "HandleInputEventImpl");
283 318
284 ui::LatencyInfo monitored_latency_info = latency_info; 319 std::unique_ptr<EventWithCallback> event_with_callback =
320 base::MakeUnique<EventWithCallback>(std::move(event), latency_info,
321 callback);
322
323 if (!compositor_event_queue_enabled_ ||
324 !IsGestureScollOrPinch(event_with_callback->event().type)) {
325 DispatchSingleInputEvent(std::move(event_with_callback));
326 return;
327 }
328
329 if (has_ongoing_compositor_scroll_pinch) {
330 bool needsAnimateInput = event_queue_->empty();
tdresser 2016/11/01 18:12:44 needs_animate_input
chongz 2016/11/02 21:29:32 Done.
331 event_queue_->Queue(std::move(event_with_callback));
332 if (needsAnimateInput)
333 input_handler_->SetNeedsAnimateInput();
334 return;
335 }
336
337 // We have to dispatch the event to know whether it's on compositor or not.
tdresser 2016/11/01 18:12:44 to know whether the gesture sequence will be handl
chongz 2016/11/02 21:29:33 Done.
338 DispatchSingleInputEvent(std::move(event_with_callback));
339 }
340
341 void InputHandlerProxy::DispatchSingleInputEvent(
342 std::unique_ptr<EventWithCallback> event_with_callback) {
343 if (compositor_event_queue_enabled_ &&
344 IsGestureScollOrPinch(event_with_callback->event().type)) {
345 // Report the coalesced count only for continuous events; otherwise
346 // the zero value would be dominated by non-continuous events.
tdresser 2016/11/01 18:12:44 I'm not convinced that this would actually be domi
chongz 2016/11/02 21:29:33 Reworded to ``` Report the coalesced count only fo
347 base::TimeTicks now = base::TimeTicks::Now();
348 if (IsContinuousEvent(event_with_callback->event().type)) {
349 UMA_HISTOGRAM_CUSTOM_COUNTS(
350 "Event.CompositorThreadEventQueue.Continuous.QueueingTime",
351 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1,
352 kTenSeconds, 50);
353
354 UMA_HISTOGRAM_CUSTOM_COUNTS(
355 "Event.CompositorThreadEventQueue.Continuous.FreshnessTime",
tdresser 2016/11/01 18:12:44 Can we use a more explicit name than "FreshnessTim
chongz 2016/11/02 21:29:33 Renamed to "HeadQueueingTime" and "TailQueueingTim
356 (now - event_with_callback->lastCoalescedTimestamp())
357 .InMicroseconds(),
358 1, kTenSeconds, 50);
359
360 UMA_HISTOGRAM_COUNTS_1000(
361 "Event.CompositorThreadEventQueue.CoalescedCount",
362 static_cast<int>(event_with_callback->coalescedCount()));
363 } else {
364 UMA_HISTOGRAM_CUSTOM_COUNTS(
365 "Event.CompositorThreadEventQueue.NonContinuous.QueueingTime",
366 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1,
367 kTenSeconds, 50);
368 }
369 }
370
371 ui::LatencyInfo monitored_latency_info = event_with_callback->latencyInfo();
285 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = 372 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor =
286 input_handler_->CreateLatencyInfoSwapPromiseMonitor( 373 input_handler_->CreateLatencyInfoSwapPromiseMonitor(
287 &monitored_latency_info); 374 &monitored_latency_info);
288 375
289 current_overscroll_params_.reset(); 376 current_overscroll_params_.reset();
290 InputHandlerProxy::EventDisposition disposition = HandleInputEvent(*event); 377 InputHandlerProxy::EventDisposition disposition =
291 callback.Run(disposition, std::move(event), monitored_latency_info, 378 HandleInputEvent(event_with_callback->event());
292 std::move(current_overscroll_params_)); 379
380 switch (event_with_callback->event().type) {
381 case blink::WebGestureEvent::GestureScrollBegin:
382 case blink::WebGestureEvent::GesturePinchBegin:
383 has_ongoing_compositor_scroll_pinch = disposition == DID_HANDLE;
384 break;
385
386 case blink::WebGestureEvent::GestureScrollUpdate:
387 case blink::WebGestureEvent::GesturePinchUpdate:
388 has_ongoing_compositor_scroll_pinch = disposition == DID_HANDLE;
389 break;
390
391 case blink::WebGestureEvent::GestureScrollEnd:
392 case blink::WebGestureEvent::GesturePinchEnd:
393 has_ongoing_compositor_scroll_pinch = false;
394 break;
395 default:
396 break;
397 }
398
399 // Will run callback for every original events.
400 event_with_callback->RunCallbacks(disposition, monitored_latency_info,
401 std::move(current_overscroll_params_));
402 }
403
404 void InputHandlerProxy::DispatchQueuedInputEvent() {
tdresser 2016/11/01 18:12:44 DispatchQueuedInputEvents?
chongz 2016/11/02 21:29:33 Done.
405 if (!compositor_event_queue_enabled_)
406 return;
407
408 while (!event_queue_->empty())
409 DispatchSingleInputEvent(event_queue_->Pop());
293 } 410 }
294 411
295 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( 412 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
296 const WebInputEvent& event) { 413 const WebInputEvent& event) {
297 DCHECK(input_handler_); 414 DCHECK(input_handler_);
298 415
299 if (FilterInputEventForFlingBoosting(event)) 416 if (FilterInputEventForFlingBoosting(event))
300 return DID_HANDLE; 417 return DID_HANDLE;
301 418
302 switch (event.type) { 419 switch (event.type) {
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 float page_scale_factor, 1230 float page_scale_factor,
1114 float min_page_scale_factor, 1231 float min_page_scale_factor,
1115 float max_page_scale_factor) { 1232 float max_page_scale_factor) {
1116 if (synchronous_input_handler_) { 1233 if (synchronous_input_handler_) {
1117 synchronous_input_handler_->UpdateRootLayerState( 1234 synchronous_input_handler_->UpdateRootLayerState(
1118 total_scroll_offset, max_scroll_offset, scrollable_size, 1235 total_scroll_offset, max_scroll_offset, scrollable_size,
1119 page_scale_factor, min_page_scale_factor, max_page_scale_factor); 1236 page_scale_factor, min_page_scale_factor, max_page_scale_factor);
1120 } 1237 }
1121 } 1238 }
1122 1239
1240 void InputHandlerProxy::DeliverInputForBeginFrame() {
1241 DispatchQueuedInputEvent();
1242 }
1243
1123 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( 1244 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings(
1124 SynchronousInputHandler* synchronous_input_handler) { 1245 SynchronousInputHandler* synchronous_input_handler) {
1125 allow_root_animate_ = !synchronous_input_handler; 1246 allow_root_animate_ = !synchronous_input_handler;
1126 synchronous_input_handler_ = synchronous_input_handler; 1247 synchronous_input_handler_ = synchronous_input_handler;
1127 if (synchronous_input_handler_) 1248 if (synchronous_input_handler_)
1128 input_handler_->RequestUpdateForSynchronousInputHandler(); 1249 input_handler_->RequestUpdateForSynchronousInputHandler();
1129 } 1250 }
1130 1251
1131 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { 1252 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) {
1132 // When this function is used, SetOnlySynchronouslyAnimate() should have been 1253 // When this function is used, SetOnlySynchronouslyAnimate() should have been
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 // is made asynchronously, to minimize divergence between main thread and 1517 // is made asynchronously, to minimize divergence between main thread and
1397 // impl thread event handling paths. 1518 // impl thread event handling paths.
1398 base::ThreadTaskRunnerHandle::Get()->PostTask( 1519 base::ThreadTaskRunnerHandle::Get()->PostTask(
1399 FROM_HERE, 1520 FROM_HERE,
1400 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, 1521 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult,
1401 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, 1522 scroll_elasticity_controller_->GetWeakPtr(), gesture_event,
1402 scroll_result)); 1523 scroll_result));
1403 } 1524 }
1404 1525
1405 } // namespace ui 1526 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698