Chromium Code Reviews| 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" |
| 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 Loading... | |
| 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 Loading... | |
| 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) { | |
|
tdresser
2016/11/04 16:51:03
These should probably go in the event utils file.
chongz
2016/11/08 21:59:22
Done.
| |
| 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 needs_animate_input = event_queue_->empty(); | |
| 331 event_queue_->Queue(std::move(event_with_callback)); | |
| 332 if (needs_animate_input) | |
| 333 input_handler_->SetNeedsAnimateInput(); | |
| 334 return; | |
| 335 } | |
| 336 | |
| 337 // We have to dispatch the event to know whether the gesture sequence will be | |
| 338 // handled by the compositor or not. | |
| 339 DispatchSingleInputEvent(std::move(event_with_callback)); | |
| 340 } | |
| 341 | |
| 342 void InputHandlerProxy::DispatchSingleInputEvent( | |
| 343 std::unique_ptr<EventWithCallback> event_with_callback) { | |
| 344 if (compositor_event_queue_enabled_ && | |
| 345 IsGestureScollOrPinch(event_with_callback->event().type)) { | |
| 346 // Report the coalesced count only for continuous events to avoid the noise | |
| 347 // from non-continuous events. | |
| 348 base::TimeTicks now = base::TimeTicks::Now(); | |
| 349 if (IsContinuousEvent(event_with_callback->event().type)) { | |
| 350 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 351 "Event.CompositorThreadEventQueue.Continuous.HeadQueueingTime", | |
| 352 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1, | |
| 353 kTenSeconds, 50); | |
| 354 | |
| 355 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 356 "Event.CompositorThreadEventQueue.Continuous.TailQueueingTime", | |
| 357 (now - event_with_callback->lastCoalescedTimestamp()) | |
| 358 .InMicroseconds(), | |
| 359 1, kTenSeconds, 50); | |
| 360 | |
| 361 UMA_HISTOGRAM_COUNTS_1000( | |
| 362 "Event.CompositorThreadEventQueue.CoalescedCount", | |
| 363 static_cast<int>(event_with_callback->coalescedCount())); | |
| 364 } else { | |
| 365 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 366 "Event.CompositorThreadEventQueue.NonContinuous.QueueingTime", | |
| 367 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1, | |
| 368 kTenSeconds, 50); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 ui::LatencyInfo monitored_latency_info = event_with_callback->latencyInfo(); | |
| 285 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = | 373 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = |
| 286 input_handler_->CreateLatencyInfoSwapPromiseMonitor( | 374 input_handler_->CreateLatencyInfoSwapPromiseMonitor( |
| 287 &monitored_latency_info); | 375 &monitored_latency_info); |
| 288 | 376 |
| 289 current_overscroll_params_.reset(); | 377 current_overscroll_params_.reset(); |
| 290 InputHandlerProxy::EventDisposition disposition = HandleInputEvent(*event); | 378 InputHandlerProxy::EventDisposition disposition = |
| 291 callback.Run(disposition, std::move(event), monitored_latency_info, | 379 HandleInputEvent(event_with_callback->event()); |
| 292 std::move(current_overscroll_params_)); | 380 |
| 381 switch (event_with_callback->event().type) { | |
| 382 case blink::WebGestureEvent::GestureScrollBegin: | |
| 383 case blink::WebGestureEvent::GesturePinchBegin: | |
| 384 has_ongoing_compositor_scroll_pinch_ = disposition == DID_HANDLE; | |
| 385 break; | |
| 386 | |
| 387 case blink::WebGestureEvent::GestureScrollUpdate: | |
| 388 case blink::WebGestureEvent::GesturePinchUpdate: | |
| 389 has_ongoing_compositor_scroll_pinch_ = disposition == DID_HANDLE; | |
| 390 break; | |
| 391 | |
| 392 case blink::WebGestureEvent::GestureScrollEnd: | |
| 393 case blink::WebGestureEvent::GesturePinchEnd: | |
| 394 has_ongoing_compositor_scroll_pinch_ = false; | |
| 395 break; | |
| 396 default: | |
| 397 break; | |
| 398 } | |
| 399 | |
| 400 // Will run callback for every original events. | |
| 401 event_with_callback->RunCallbacks(disposition, monitored_latency_info, | |
| 402 std::move(current_overscroll_params_)); | |
| 403 } | |
| 404 | |
| 405 void InputHandlerProxy::DispatchQueuedInputEvents() { | |
| 406 if (!compositor_event_queue_enabled_) | |
| 407 return; | |
| 408 | |
| 409 while (!event_queue_->empty()) | |
| 410 DispatchSingleInputEvent(event_queue_->Pop()); | |
| 293 } | 411 } |
| 294 | 412 |
| 295 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( | 413 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( |
| 296 const WebInputEvent& event) { | 414 const WebInputEvent& event) { |
| 297 DCHECK(input_handler_); | 415 DCHECK(input_handler_); |
| 298 | 416 |
| 299 if (FilterInputEventForFlingBoosting(event)) | 417 if (FilterInputEventForFlingBoosting(event)) |
| 300 return DID_HANDLE; | 418 return DID_HANDLE; |
| 301 | 419 |
| 302 switch (event.type) { | 420 switch (event.type) { |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1113 float page_scale_factor, | 1231 float page_scale_factor, |
| 1114 float min_page_scale_factor, | 1232 float min_page_scale_factor, |
| 1115 float max_page_scale_factor) { | 1233 float max_page_scale_factor) { |
| 1116 if (synchronous_input_handler_) { | 1234 if (synchronous_input_handler_) { |
| 1117 synchronous_input_handler_->UpdateRootLayerState( | 1235 synchronous_input_handler_->UpdateRootLayerState( |
| 1118 total_scroll_offset, max_scroll_offset, scrollable_size, | 1236 total_scroll_offset, max_scroll_offset, scrollable_size, |
| 1119 page_scale_factor, min_page_scale_factor, max_page_scale_factor); | 1237 page_scale_factor, min_page_scale_factor, max_page_scale_factor); |
| 1120 } | 1238 } |
| 1121 } | 1239 } |
| 1122 | 1240 |
| 1241 void InputHandlerProxy::DeliverInputForBeginFrame() { | |
| 1242 DispatchQueuedInputEvents(); | |
| 1243 } | |
| 1244 | |
| 1123 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( | 1245 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( |
| 1124 SynchronousInputHandler* synchronous_input_handler) { | 1246 SynchronousInputHandler* synchronous_input_handler) { |
| 1125 allow_root_animate_ = !synchronous_input_handler; | 1247 allow_root_animate_ = !synchronous_input_handler; |
| 1126 synchronous_input_handler_ = synchronous_input_handler; | 1248 synchronous_input_handler_ = synchronous_input_handler; |
| 1127 if (synchronous_input_handler_) | 1249 if (synchronous_input_handler_) |
| 1128 input_handler_->RequestUpdateForSynchronousInputHandler(); | 1250 input_handler_->RequestUpdateForSynchronousInputHandler(); |
| 1129 } | 1251 } |
| 1130 | 1252 |
| 1131 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { | 1253 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { |
| 1132 // When this function is used, SetOnlySynchronouslyAnimate() should have been | 1254 // When this function is used, SetOnlySynchronouslyAnimate() should have been |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1396 // is made asynchronously, to minimize divergence between main thread and | 1518 // is made asynchronously, to minimize divergence between main thread and |
| 1397 // impl thread event handling paths. | 1519 // impl thread event handling paths. |
| 1398 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1520 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1399 FROM_HERE, | 1521 FROM_HERE, |
| 1400 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, | 1522 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, |
| 1401 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, | 1523 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, |
| 1402 scroll_result)); | 1524 scroll_result)); |
| 1403 } | 1525 } |
| 1404 | 1526 |
| 1405 } // namespace ui | 1527 } // namespace ui |
| OLD | NEW |