OLD | NEW |
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" |
| 19 #include "base/time/default_tick_clock.h" |
18 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
19 #include "cc/input/main_thread_scrolling_reason.h" | 21 #include "cc/input/main_thread_scrolling_reason.h" |
20 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 22 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
| 23 #include "ui/events/blink/blink_event_util.h" |
| 24 #include "ui/events/blink/compositor_thread_event_queue.h" |
21 #include "ui/events/blink/did_overscroll_params.h" | 25 #include "ui/events/blink/did_overscroll_params.h" |
| 26 #include "ui/events/blink/event_with_callback.h" |
22 #include "ui/events/blink/input_handler_proxy_client.h" | 27 #include "ui/events/blink/input_handler_proxy_client.h" |
23 #include "ui/events/blink/input_scroll_elasticity_controller.h" | 28 #include "ui/events/blink/input_scroll_elasticity_controller.h" |
24 #include "ui/events/blink/web_input_event_traits.h" | 29 #include "ui/events/blink/web_input_event_traits.h" |
25 #include "ui/events/latency_info.h" | 30 #include "ui/events/latency_info.h" |
26 #include "ui/gfx/geometry/point_conversions.h" | 31 #include "ui/gfx/geometry/point_conversions.h" |
27 | 32 |
28 using blink::WebFloatPoint; | 33 using blink::WebFloatPoint; |
29 using blink::WebFloatSize; | 34 using blink::WebFloatSize; |
30 using blink::WebGestureEvent; | 35 using blink::WebGestureEvent; |
31 using blink::WebInputEvent; | 36 using blink::WebInputEvent; |
(...skipping 23 matching lines...) Expand all Loading... |
55 // Minimum velocity for the active touch scroll to preserve (boost) an active | 60 // Minimum velocity for the active touch scroll to preserve (boost) an active |
56 // fling for which cancellation has been deferred. | 61 // fling for which cancellation has been deferred. |
57 const double kMinBoostTouchScrollSpeedSquare = 150 * 150.; | 62 const double kMinBoostTouchScrollSpeedSquare = 150 * 150.; |
58 | 63 |
59 // Timeout window after which the active fling will be cancelled if no animation | 64 // 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 | 65 // 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 | 66 // 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. | 67 // slightly increased value to accomodate small IPC message delays. |
63 const double kFlingBoostTimeoutDelaySeconds = 0.05; | 68 const double kFlingBoostTimeoutDelaySeconds = 0.05; |
64 | 69 |
| 70 const size_t kTenSeconds = 10 * 1000 * 1000; |
| 71 |
65 gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) { | 72 gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) { |
66 return gfx::Vector2dF(-increment.width, -increment.height); | 73 return gfx::Vector2dF(-increment.width, -increment.height); |
67 } | 74 } |
68 | 75 |
69 double InSecondsF(const base::TimeTicks& time) { | 76 double InSecondsF(const base::TimeTicks& time) { |
70 return (time - base::TimeTicks()).InSecondsF(); | 77 return (time - base::TimeTicks()).InSecondsF(); |
71 } | 78 } |
72 | 79 |
73 bool ShouldSuppressScrollForFlingBoosting( | 80 bool ShouldSuppressScrollForFlingBoosting( |
74 const gfx::Vector2dF& current_fling_velocity, | 81 const gfx::Vector2dF& current_fling_velocity, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 #endif | 242 #endif |
236 gesture_scroll_on_impl_thread_(false), | 243 gesture_scroll_on_impl_thread_(false), |
237 gesture_pinch_on_impl_thread_(false), | 244 gesture_pinch_on_impl_thread_(false), |
238 fling_may_be_active_on_main_thread_(false), | 245 fling_may_be_active_on_main_thread_(false), |
239 disallow_horizontal_fling_scroll_(false), | 246 disallow_horizontal_fling_scroll_(false), |
240 disallow_vertical_fling_scroll_(false), | 247 disallow_vertical_fling_scroll_(false), |
241 has_fling_animation_started_(false), | 248 has_fling_animation_started_(false), |
242 smooth_scroll_enabled_(false), | 249 smooth_scroll_enabled_(false), |
243 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()), | 250 uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()), |
244 touch_start_result_(kEventDispositionUndefined), | 251 touch_start_result_(kEventDispositionUndefined), |
245 current_overscroll_params_(nullptr) { | 252 current_overscroll_params_(nullptr), |
| 253 has_ongoing_compositor_scroll_pinch_(false), |
| 254 tick_clock_(base::MakeUnique<base::DefaultTickClock>()) { |
246 DCHECK(client); | 255 DCHECK(client); |
247 input_handler_->BindToClient(this); | 256 input_handler_->BindToClient(this); |
248 cc::ScrollElasticityHelper* scroll_elasticity_helper = | 257 cc::ScrollElasticityHelper* scroll_elasticity_helper = |
249 input_handler_->CreateScrollElasticityHelper(); | 258 input_handler_->CreateScrollElasticityHelper(); |
250 if (scroll_elasticity_helper) { | 259 if (scroll_elasticity_helper) { |
251 scroll_elasticity_controller_.reset( | 260 scroll_elasticity_controller_.reset( |
252 new InputScrollElasticityController(scroll_elasticity_helper)); | 261 new InputScrollElasticityController(scroll_elasticity_helper)); |
253 } | 262 } |
| 263 compositor_event_queue_ = |
| 264 base::FeatureList::IsEnabled(features::kVsyncAlignedInputEvents) |
| 265 ? base::MakeUnique<CompositorThreadEventQueue>() |
| 266 : nullptr; |
254 } | 267 } |
255 | 268 |
256 InputHandlerProxy::~InputHandlerProxy() {} | 269 InputHandlerProxy::~InputHandlerProxy() {} |
257 | 270 |
258 void InputHandlerProxy::WillShutdown() { | 271 void InputHandlerProxy::WillShutdown() { |
259 scroll_elasticity_controller_.reset(); | 272 scroll_elasticity_controller_.reset(); |
260 input_handler_ = NULL; | 273 input_handler_ = NULL; |
261 client_->WillShutdown(); | 274 client_->WillShutdown(); |
262 } | 275 } |
263 | 276 |
264 void InputHandlerProxy::HandleInputEventWithLatencyInfo( | 277 void InputHandlerProxy::HandleInputEventWithLatencyInfo( |
265 ScopedWebInputEvent event, | 278 ScopedWebInputEvent event, |
266 const LatencyInfo& latency_info, | 279 const LatencyInfo& latency_info, |
267 const EventDispositionCallback& callback) { | 280 const EventDispositionCallback& callback) { |
268 DCHECK(input_handler_); | 281 DCHECK(input_handler_); |
269 | 282 |
270 if (uma_latency_reporting_enabled_) | 283 if (uma_latency_reporting_enabled_) |
271 ReportInputEventLatencyUma(*event, latency_info); | 284 ReportInputEventLatencyUma(*event, latency_info); |
272 | 285 |
273 TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", | 286 TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", |
274 TRACE_ID_DONT_MANGLE(latency_info.trace_id()), | 287 TRACE_ID_DONT_MANGLE(latency_info.trace_id()), |
275 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, | 288 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, |
276 "step", "HandleInputEventImpl"); | 289 "step", "HandleInputEventImpl"); |
277 | 290 |
278 ui::LatencyInfo monitored_latency_info = latency_info; | 291 std::unique_ptr<EventWithCallback> event_with_callback = |
| 292 base::MakeUnique<EventWithCallback>(std::move(event), latency_info, |
| 293 tick_clock_->NowTicks(), callback); |
| 294 |
| 295 // Note: Other input can race ahead of gesture input as they don't have to go |
| 296 // through the queue, but we believe it's OK to do so. |
| 297 if (!compositor_event_queue_ || |
| 298 !IsGestureScollOrPinch(event_with_callback->event().type)) { |
| 299 DispatchSingleInputEvent(std::move(event_with_callback), |
| 300 tick_clock_->NowTicks()); |
| 301 return; |
| 302 } |
| 303 |
| 304 if (has_ongoing_compositor_scroll_pinch_) { |
| 305 bool needs_animate_input = compositor_event_queue_->empty(); |
| 306 compositor_event_queue_->Queue(std::move(event_with_callback), |
| 307 tick_clock_->NowTicks()); |
| 308 if (needs_animate_input) |
| 309 input_handler_->SetNeedsAnimateInput(); |
| 310 return; |
| 311 } |
| 312 |
| 313 // We have to dispatch the event to know whether the gesture sequence will be |
| 314 // handled by the compositor or not. |
| 315 DispatchSingleInputEvent(std::move(event_with_callback), |
| 316 tick_clock_->NowTicks()); |
| 317 } |
| 318 |
| 319 void InputHandlerProxy::DispatchSingleInputEvent( |
| 320 std::unique_ptr<EventWithCallback> event_with_callback, |
| 321 const base::TimeTicks now) { |
| 322 if (compositor_event_queue_ && |
| 323 IsGestureScollOrPinch(event_with_callback->event().type)) { |
| 324 // Report the coalesced count only for continuous events to avoid the noise |
| 325 // from non-continuous events. |
| 326 if (IsContinuousGestureEvent(event_with_callback->event().type)) { |
| 327 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 328 "Event.CompositorThreadEventQueue.Continuous.HeadQueueingTime", |
| 329 (now - event_with_callback->creation_timestamp()).InMicroseconds(), 1, |
| 330 kTenSeconds, 50); |
| 331 |
| 332 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 333 "Event.CompositorThreadEventQueue.Continuous.TailQueueingTime", |
| 334 (now - event_with_callback->last_coalesced_timestamp()) |
| 335 .InMicroseconds(), |
| 336 1, kTenSeconds, 50); |
| 337 |
| 338 UMA_HISTOGRAM_COUNTS_1000( |
| 339 "Event.CompositorThreadEventQueue.CoalescedCount", |
| 340 static_cast<int>(event_with_callback->coalesced_count())); |
| 341 } else { |
| 342 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 343 "Event.CompositorThreadEventQueue.NonContinuous.QueueingTime", |
| 344 (now - event_with_callback->creation_timestamp()).InMicroseconds(), 1, |
| 345 kTenSeconds, 50); |
| 346 } |
| 347 } |
| 348 |
| 349 ui::LatencyInfo monitored_latency_info = event_with_callback->latency_info(); |
279 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = | 350 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = |
280 input_handler_->CreateLatencyInfoSwapPromiseMonitor( | 351 input_handler_->CreateLatencyInfoSwapPromiseMonitor( |
281 &monitored_latency_info); | 352 &monitored_latency_info); |
282 | 353 |
283 current_overscroll_params_.reset(); | 354 current_overscroll_params_.reset(); |
284 InputHandlerProxy::EventDisposition disposition = HandleInputEvent(*event); | 355 InputHandlerProxy::EventDisposition disposition = |
285 callback.Run(disposition, std::move(event), monitored_latency_info, | 356 HandleInputEvent(event_with_callback->event()); |
286 std::move(current_overscroll_params_)); | 357 |
| 358 switch (event_with_callback->event().type) { |
| 359 case blink::WebGestureEvent::GestureScrollBegin: |
| 360 case blink::WebGestureEvent::GesturePinchBegin: |
| 361 case blink::WebGestureEvent::GestureScrollUpdate: |
| 362 case blink::WebGestureEvent::GesturePinchUpdate: |
| 363 has_ongoing_compositor_scroll_pinch_ = disposition == DID_HANDLE; |
| 364 break; |
| 365 |
| 366 case blink::WebGestureEvent::GestureScrollEnd: |
| 367 case blink::WebGestureEvent::GesturePinchEnd: |
| 368 has_ongoing_compositor_scroll_pinch_ = false; |
| 369 break; |
| 370 default: |
| 371 break; |
| 372 } |
| 373 |
| 374 // Will run callback for every original events. |
| 375 event_with_callback->RunCallbacks(disposition, monitored_latency_info, |
| 376 std::move(current_overscroll_params_)); |
| 377 } |
| 378 |
| 379 void InputHandlerProxy::DispatchQueuedInputEvents() { |
| 380 if (!compositor_event_queue_) |
| 381 return; |
| 382 |
| 383 // Calling |NowTicks()| is expensive so we only want to do it once. |
| 384 base::TimeTicks now = tick_clock_->NowTicks(); |
| 385 while (!compositor_event_queue_->empty()) |
| 386 DispatchSingleInputEvent(compositor_event_queue_->Pop(), now); |
287 } | 387 } |
288 | 388 |
289 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( | 389 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( |
290 const WebInputEvent& event) { | 390 const WebInputEvent& event) { |
291 DCHECK(input_handler_); | 391 DCHECK(input_handler_); |
292 | 392 |
293 if (FilterInputEventForFlingBoosting(event)) | 393 if (FilterInputEventForFlingBoosting(event)) |
294 return DID_HANDLE; | 394 return DID_HANDLE; |
295 | 395 |
296 switch (event.type) { | 396 switch (event.type) { |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 float page_scale_factor, | 1231 float page_scale_factor, |
1132 float min_page_scale_factor, | 1232 float min_page_scale_factor, |
1133 float max_page_scale_factor) { | 1233 float max_page_scale_factor) { |
1134 if (synchronous_input_handler_) { | 1234 if (synchronous_input_handler_) { |
1135 synchronous_input_handler_->UpdateRootLayerState( | 1235 synchronous_input_handler_->UpdateRootLayerState( |
1136 total_scroll_offset, max_scroll_offset, scrollable_size, | 1236 total_scroll_offset, max_scroll_offset, scrollable_size, |
1137 page_scale_factor, min_page_scale_factor, max_page_scale_factor); | 1237 page_scale_factor, min_page_scale_factor, max_page_scale_factor); |
1138 } | 1238 } |
1139 } | 1239 } |
1140 | 1240 |
| 1241 void InputHandlerProxy::DeliverInputForBeginFrame() { |
| 1242 DispatchQueuedInputEvents(); |
| 1243 } |
| 1244 |
1141 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( | 1245 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( |
1142 SynchronousInputHandler* synchronous_input_handler) { | 1246 SynchronousInputHandler* synchronous_input_handler) { |
1143 allow_root_animate_ = !synchronous_input_handler; | 1247 allow_root_animate_ = !synchronous_input_handler; |
1144 synchronous_input_handler_ = synchronous_input_handler; | 1248 synchronous_input_handler_ = synchronous_input_handler; |
1145 if (synchronous_input_handler_) | 1249 if (synchronous_input_handler_) |
1146 input_handler_->RequestUpdateForSynchronousInputHandler(); | 1250 input_handler_->RequestUpdateForSynchronousInputHandler(); |
1147 } | 1251 } |
1148 | 1252 |
1149 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { | 1253 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { |
1150 // When this function is used, SetOnlySynchronouslyAnimate() should have been | 1254 // When this function is used, SetOnlySynchronouslyAnimate() should have been |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 // the over-scroll animation. Note that the call to the elasticity controller | 1519 // the over-scroll animation. Note that the call to the elasticity controller |
1416 // is made asynchronously, to minimize divergence between main thread and | 1520 // is made asynchronously, to minimize divergence between main thread and |
1417 // impl thread event handling paths. | 1521 // impl thread event handling paths. |
1418 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1522 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1419 FROM_HERE, | 1523 FROM_HERE, |
1420 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, | 1524 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, |
1421 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, | 1525 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, |
1422 scroll_result)); | 1526 scroll_result)); |
1423 } | 1527 } |
1424 | 1528 |
| 1529 void InputHandlerProxy::SetTickClockForTesting( |
| 1530 std::unique_ptr<base::TickClock> tick_clock) { |
| 1531 tick_clock_ = std::move(tick_clock); |
| 1532 } |
| 1533 |
1425 } // namespace ui | 1534 } // namespace ui |
OLD | NEW |