| Index: content/renderer/input/main_thread_event_queue.cc
|
| diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc
|
| index 45ee0814ff84418deb0e5bddfcc98afc7bde581f..35005e6ab4d0df0844ba7d07e6a448df57694d12 100644
|
| --- a/content/renderer/input/main_thread_event_queue.cc
|
| +++ b/content/renderer/input/main_thread_event_queue.cc
|
| @@ -38,20 +38,19 @@ EventWithDispatchType::EventWithDispatchType(
|
| InputEventDispatchType dispatch_type)
|
| : ScopedWebInputEventWithLatencyInfo(std::move(event), latency),
|
| dispatch_type_(dispatch_type),
|
| + non_blocking_coalesced_count_(0),
|
| creation_timestamp_(base::TimeTicks::Now()),
|
| last_coalesced_timestamp_(creation_timestamp_) {}
|
|
|
| EventWithDispatchType::~EventWithDispatchType() {}
|
|
|
| -bool EventWithDispatchType::CanCoalesceWith(
|
| - const EventWithDispatchType& other) const {
|
| - return other.dispatch_type_ == dispatch_type_ &&
|
| - ScopedWebInputEventWithLatencyInfo::CanCoalesceWith(other);
|
| -}
|
| -
|
| void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) {
|
| - coalesced_event_ids_.push_back(
|
| - ui::WebInputEventTraits::GetUniqueTouchEventId(other.event()));
|
| + if (other.dispatch_type_ == DISPATCH_TYPE_BLOCKING) {
|
| + blocking_coalesced_event_ids_.push_back(
|
| + ui::WebInputEventTraits::GetUniqueTouchEventId(other.event()));
|
| + } else {
|
| + non_blocking_coalesced_count_++;
|
| + }
|
| ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
|
| last_coalesced_timestamp_ = base::TimeTicks::Now();
|
| }
|
| @@ -122,6 +121,10 @@ bool MainThreadEventQueue::HandleEvent(
|
| last_touch_start_forced_nonblocking_due_to_fling_ = true;
|
| }
|
| }
|
| + // If handling rAF aligned touch input ACK non-cancelable events right
|
| + // away.
|
| + if (!non_blocking && IsRafAlignedEvent(*touch_event))
|
| + non_blocking = true;
|
| }
|
| if (is_wheel && non_blocking) {
|
| // Adjust the |dispatchType| on the event since the compositor
|
| @@ -132,6 +135,7 @@ bool MainThreadEventQueue::HandleEvent(
|
|
|
| InputEventDispatchType dispatch_type =
|
| non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
|
| +
|
| std::unique_ptr<EventWithDispatchType> event_with_dispatch_type(
|
| new EventWithDispatchType(std::move(event), latency, dispatch_type));
|
|
|
| @@ -158,7 +162,7 @@ void MainThreadEventQueue::DispatchInFlightEvent() {
|
| 1, kTenSeconds, 50);
|
|
|
| UMA_HISTOGRAM_COUNTS_1000("Event.MainThreadEventQueue.CoalescedCount",
|
| - in_flight_event_->coalescedEventIds().size());
|
| + in_flight_event_->coalescedCount());
|
| } else {
|
| UMA_HISTOGRAM_CUSTOM_COUNTS(
|
| "Event.MainThreadEventQueue.NonContinuous.QueueingTime",
|
| @@ -167,11 +171,18 @@ void MainThreadEventQueue::DispatchInFlightEvent() {
|
| }
|
|
|
| InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
|
| - if (!in_flight_event_->coalescedEventIds().empty() &&
|
| - dispatch_type == DISPATCH_TYPE_BLOCKING) {
|
| - dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
|
| + if (!in_flight_event_->blockingCoalescedEventIds().empty()) {
|
| + switch (dispatch_type) {
|
| + case DISPATCH_TYPE_BLOCKING:
|
| + dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
|
| + break;
|
| + case DISPATCH_TYPE_NON_BLOCKING:
|
| + dispatch_type = DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN;
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| }
|
| -
|
| client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(),
|
| in_flight_event_->latencyInfo(),
|
| dispatch_type);
|
| @@ -188,7 +199,7 @@ void MainThreadEventQueue::PossiblyScheduleMainFrame() {
|
| base::AutoLock lock(shared_state_lock_);
|
| if (!shared_state_.sent_main_frame_request_ &&
|
| !shared_state_.events_.empty() &&
|
| - IsRafAlignedEvent(shared_state_.events_.front())) {
|
| + IsRafAlignedEvent(shared_state_.events_.front()->event())) {
|
| needs_main_frame = !shared_state_.sent_main_frame_request_;
|
| shared_state_.sent_main_frame_request_ = false;
|
| }
|
| @@ -211,9 +222,8 @@ void MainThreadEventQueue::DispatchSingleEvent() {
|
|
|
| void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
|
| InputEventAckState ack_result) {
|
| - if (in_flight_event_ &&
|
| - in_flight_event_->dispatchType() == DISPATCH_TYPE_BLOCKING) {
|
| - for (const auto id : in_flight_event_->coalescedEventIds()) {
|
| + if (in_flight_event_) {
|
| + for (const auto id : in_flight_event_->blockingCoalescedEventIds()) {
|
| client_->SendInputEventAck(routing_id_, type, ack_result, id);
|
| if (renderer_scheduler_) {
|
| renderer_scheduler_->DidHandleInputEventOnMainThread(
|
| @@ -233,7 +243,7 @@ void MainThreadEventQueue::DispatchRafAlignedInput() {
|
| shared_state_.sent_main_frame_request_ = false;
|
|
|
| while(!shared_state_.events_.empty()) {
|
| - if (!IsRafAlignedEvent(shared_state_.events_.front()))
|
| + if (!IsRafAlignedEvent(shared_state_.events_.front()->event()))
|
| break;
|
| events_to_process.emplace_back(shared_state_.events_.Pop());
|
| }
|
| @@ -254,12 +264,19 @@ void MainThreadEventQueue::SendEventNotificationToMainThread() {
|
|
|
| void MainThreadEventQueue::QueueEvent(
|
| std::unique_ptr<EventWithDispatchType> event) {
|
| - bool is_raf_aligned = IsRafAlignedEvent(event);
|
| + bool is_raf_aligned = IsRafAlignedEvent(event->event());
|
| size_t send_notification_count = 0;
|
| bool needs_main_frame = false;
|
| {
|
| base::AutoLock lock(shared_state_lock_);
|
| size_t size_before = shared_state_.events_.size();
|
| +
|
| + // Stash if the tail of the queue was rAF aligned.
|
| + bool was_raf_aligned = false;
|
| + if (size_before > 0) {
|
| + was_raf_aligned =
|
| + IsRafAlignedEvent(shared_state_.events_.at(size_before - 1)->event());
|
| + }
|
| shared_state_.events_.Queue(std::move(event));
|
| size_t size_after = shared_state_.events_.size();
|
|
|
| @@ -271,7 +288,7 @@ void MainThreadEventQueue::QueueEvent(
|
| // If we had just enqueued a non-rAF input event we will send a series
|
| // of normal post messages to ensure they are all handled right away.
|
| for (size_t pos = size_after - 1; pos >= 1; --pos) {
|
| - if (IsRafAlignedEvent(shared_state_.events_.at(pos - 1)))
|
| + if (IsRafAlignedEvent(shared_state_.events_.at(pos - 1)->event()))
|
| send_notification_count++;
|
| else
|
| break;
|
| @@ -280,8 +297,17 @@ void MainThreadEventQueue::QueueEvent(
|
| needs_main_frame = !shared_state_.sent_main_frame_request_;
|
| shared_state_.sent_main_frame_request_ = true;
|
| }
|
| + } else if (size_before > 0) {
|
| + // The event was coalesced. The queue size didn't change but
|
| + // the rAF alignment of the event may have and we need to schedule
|
| + // a notification.
|
| + bool is_coalesced_raf_aligned =
|
| + IsRafAlignedEvent(shared_state_.events_.at(size_before - 1)->event());
|
| + if (was_raf_aligned != is_coalesced_raf_aligned)
|
| + send_notification_count = 1;
|
| }
|
| }
|
| +
|
| for (size_t i = 0; i < send_notification_count; ++i)
|
| SendEventNotificationToMainThread();
|
| if (needs_main_frame)
|
| @@ -293,8 +319,8 @@ bool MainThreadEventQueue::IsRafAlignedInputDisabled() {
|
| }
|
|
|
| bool MainThreadEventQueue::IsRafAlignedEvent(
|
| - const std::unique_ptr<EventWithDispatchType>& event) {
|
| - switch (event->event().type) {
|
| + const blink::WebInputEvent& event) {
|
| + switch (event.type) {
|
| case blink::WebInputEvent::MouseMove:
|
| case blink::WebInputEvent::MouseWheel:
|
| return handle_raf_aligned_mouse_input_;
|
| @@ -302,8 +328,8 @@ bool MainThreadEventQueue::IsRafAlignedEvent(
|
| // TouchMoves that are blocking end up blocking scroll. Do not treat
|
| // them as continuous events otherwise we will end up waiting up to an
|
| // additional frame.
|
| - return static_cast<const blink::WebTouchEvent&>(event->event())
|
| - .dispatchType != blink::WebInputEvent::Blocking &&
|
| + return static_cast<const blink::WebTouchEvent&>(event).dispatchType !=
|
| + blink::WebInputEvent::Blocking &&
|
| handle_raf_aligned_touch_input_;
|
| default:
|
| return false;
|
|
|