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" |
| 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 if (!compositor_event_queue_ || | |
| 296 !IsGestureScollOrPinch(event_with_callback->event().type)) { | |
|
dtapuska
2016/11/14 18:18:45
This might need a comment. I look at this line and
chongz
2016/11/17 21:36:13
Done.
| |
| 297 DispatchSingleInputEvent(std::move(event_with_callback)); | |
| 298 return; | |
| 299 } | |
| 300 | |
| 301 if (has_ongoing_compositor_scroll_pinch_) { | |
| 302 bool needs_animate_input = compositor_event_queue_->empty(); | |
| 303 compositor_event_queue_->Queue(std::move(event_with_callback), | |
| 304 tick_clock_->NowTicks()); | |
| 305 if (needs_animate_input) | |
| 306 input_handler_->SetNeedsAnimateInput(); | |
| 307 return; | |
| 308 } | |
| 309 | |
| 310 // We have to dispatch the event to know whether the gesture sequence will be | |
| 311 // handled by the compositor or not. | |
| 312 DispatchSingleInputEvent(std::move(event_with_callback)); | |
| 313 } | |
| 314 | |
| 315 void InputHandlerProxy::DispatchSingleInputEvent( | |
| 316 std::unique_ptr<EventWithCallback> event_with_callback) { | |
| 317 if (compositor_event_queue_ && | |
| 318 IsGestureScollOrPinch(event_with_callback->event().type)) { | |
| 319 // Report the coalesced count only for continuous events to avoid the noise | |
| 320 // from non-continuous events. | |
| 321 base::TimeTicks now = tick_clock_->NowTicks(); | |
|
enne (OOO)
2016/11/14 23:59:46
For what it's worth, I know brianderson has mentio
tdresser
2016/11/15 00:09:22
I think this is worth doing.
chongz
2016/11/17 21:36:13
Done.
| |
| 322 if (IsContinuousGestureEvent(event_with_callback->event().type)) { | |
| 323 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 324 "Event.CompositorThreadEventQueue.Continuous.HeadQueueingTime", | |
| 325 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1, | |
| 326 kTenSeconds, 50); | |
| 327 | |
| 328 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 329 "Event.CompositorThreadEventQueue.Continuous.TailQueueingTime", | |
| 330 (now - event_with_callback->lastCoalescedTimestamp()) | |
| 331 .InMicroseconds(), | |
| 332 1, kTenSeconds, 50); | |
| 333 | |
| 334 UMA_HISTOGRAM_COUNTS_1000( | |
| 335 "Event.CompositorThreadEventQueue.CoalescedCount", | |
| 336 static_cast<int>(event_with_callback->coalescedCount())); | |
| 337 } else { | |
| 338 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 339 "Event.CompositorThreadEventQueue.NonContinuous.QueueingTime", | |
| 340 (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1, | |
| 341 kTenSeconds, 50); | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 ui::LatencyInfo monitored_latency_info = event_with_callback->latencyInfo(); | |
| 279 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = | 346 std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor = |
| 280 input_handler_->CreateLatencyInfoSwapPromiseMonitor( | 347 input_handler_->CreateLatencyInfoSwapPromiseMonitor( |
| 281 &monitored_latency_info); | 348 &monitored_latency_info); |
| 282 | 349 |
| 283 current_overscroll_params_.reset(); | 350 current_overscroll_params_.reset(); |
| 284 InputHandlerProxy::EventDisposition disposition = HandleInputEvent(*event); | 351 InputHandlerProxy::EventDisposition disposition = |
| 285 callback.Run(disposition, std::move(event), monitored_latency_info, | 352 HandleInputEvent(event_with_callback->event()); |
| 286 std::move(current_overscroll_params_)); | 353 |
| 354 switch (event_with_callback->event().type) { | |
| 355 case blink::WebGestureEvent::GestureScrollBegin: | |
| 356 case blink::WebGestureEvent::GesturePinchBegin: | |
| 357 case blink::WebGestureEvent::GestureScrollUpdate: | |
| 358 case blink::WebGestureEvent::GesturePinchUpdate: | |
| 359 has_ongoing_compositor_scroll_pinch_ = disposition == DID_HANDLE; | |
| 360 break; | |
| 361 | |
| 362 case blink::WebGestureEvent::GestureScrollEnd: | |
| 363 case blink::WebGestureEvent::GesturePinchEnd: | |
| 364 has_ongoing_compositor_scroll_pinch_ = false; | |
| 365 break; | |
| 366 default: | |
| 367 break; | |
| 368 } | |
| 369 | |
| 370 // Will run callback for every original events. | |
| 371 event_with_callback->RunCallbacks(disposition, monitored_latency_info, | |
| 372 std::move(current_overscroll_params_)); | |
| 373 } | |
| 374 | |
| 375 void InputHandlerProxy::DispatchQueuedInputEvents() { | |
| 376 if (!compositor_event_queue_) | |
| 377 return; | |
| 378 | |
| 379 while (!compositor_event_queue_->empty()) | |
| 380 DispatchSingleInputEvent(compositor_event_queue_->Pop()); | |
| 287 } | 381 } |
| 288 | 382 |
| 289 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( | 383 InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent( |
| 290 const WebInputEvent& event) { | 384 const WebInputEvent& event) { |
| 291 DCHECK(input_handler_); | 385 DCHECK(input_handler_); |
| 292 | 386 |
| 293 if (FilterInputEventForFlingBoosting(event)) | 387 if (FilterInputEventForFlingBoosting(event)) |
| 294 return DID_HANDLE; | 388 return DID_HANDLE; |
| 295 | 389 |
| 296 switch (event.type) { | 390 switch (event.type) { |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 float page_scale_factor, | 1225 float page_scale_factor, |
| 1132 float min_page_scale_factor, | 1226 float min_page_scale_factor, |
| 1133 float max_page_scale_factor) { | 1227 float max_page_scale_factor) { |
| 1134 if (synchronous_input_handler_) { | 1228 if (synchronous_input_handler_) { |
| 1135 synchronous_input_handler_->UpdateRootLayerState( | 1229 synchronous_input_handler_->UpdateRootLayerState( |
| 1136 total_scroll_offset, max_scroll_offset, scrollable_size, | 1230 total_scroll_offset, max_scroll_offset, scrollable_size, |
| 1137 page_scale_factor, min_page_scale_factor, max_page_scale_factor); | 1231 page_scale_factor, min_page_scale_factor, max_page_scale_factor); |
| 1138 } | 1232 } |
| 1139 } | 1233 } |
| 1140 | 1234 |
| 1235 void InputHandlerProxy::DeliverInputForBeginFrame() { | |
| 1236 DispatchQueuedInputEvents(); | |
| 1237 } | |
| 1238 | |
| 1141 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( | 1239 void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings( |
| 1142 SynchronousInputHandler* synchronous_input_handler) { | 1240 SynchronousInputHandler* synchronous_input_handler) { |
| 1143 allow_root_animate_ = !synchronous_input_handler; | 1241 allow_root_animate_ = !synchronous_input_handler; |
| 1144 synchronous_input_handler_ = synchronous_input_handler; | 1242 synchronous_input_handler_ = synchronous_input_handler; |
| 1145 if (synchronous_input_handler_) | 1243 if (synchronous_input_handler_) |
| 1146 input_handler_->RequestUpdateForSynchronousInputHandler(); | 1244 input_handler_->RequestUpdateForSynchronousInputHandler(); |
| 1147 } | 1245 } |
| 1148 | 1246 |
| 1149 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { | 1247 void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) { |
| 1150 // When this function is used, SetOnlySynchronouslyAnimate() should have been | 1248 // 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 | 1513 // the over-scroll animation. Note that the call to the elasticity controller |
| 1416 // is made asynchronously, to minimize divergence between main thread and | 1514 // is made asynchronously, to minimize divergence between main thread and |
| 1417 // impl thread event handling paths. | 1515 // impl thread event handling paths. |
| 1418 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1516 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1419 FROM_HERE, | 1517 FROM_HERE, |
| 1420 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, | 1518 base::Bind(&InputScrollElasticityController::ObserveGestureEventAndResult, |
| 1421 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, | 1519 scroll_elasticity_controller_->GetWeakPtr(), gesture_event, |
| 1422 scroll_result)); | 1520 scroll_result)); |
| 1423 } | 1521 } |
| 1424 | 1522 |
| 1523 void InputHandlerProxy::SetTickClockForTesting( | |
| 1524 std::unique_ptr<base::TickClock> tick_clock) { | |
| 1525 tick_clock_ = std::move(tick_clock); | |
| 1526 } | |
| 1527 | |
| 1425 } // namespace ui | 1528 } // namespace ui |
| OLD | NEW |