Chromium Code Reviews| 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 6581056c741f3c8ca622af3a1f7ba26c09db127c..0793f7c1217e8a095a29b944d42f3449e6522fe5 100644 |
| --- a/content/renderer/input/main_thread_event_queue.cc |
| +++ b/content/renderer/input/main_thread_event_queue.cc |
| @@ -3,12 +3,46 @@ |
| // found in the LICENSE file. |
| #include "content/renderer/input/main_thread_event_queue.h" |
| +#include "content/common/input/event_with_latency_info.h" |
| +#include "content/common/input_messages.h" |
| namespace content { |
| -MainThreadEventQueue::MainThreadEventQueue(int routing_id, |
| - MainThreadEventQueueClient* client) |
| - : routing_id_(routing_id), client_(client), is_flinging_(false) {} |
| +EventWithDispatchType::EventWithDispatchType( |
| + const blink::WebInputEvent& event, |
| + const ui::LatencyInfo& latency, |
| + InputEventDispatchType dispatch_type) |
| + : ScopedWebInputEventWithLatencyInfo(event, latency), |
| + dispatch_type_(dispatch_type) {} |
| + |
| +EventWithDispatchType::~EventWithDispatchType() {} |
| + |
| +bool EventWithDispatchType::CanCoalesceWith( |
| + const EventWithDispatchType& other) const { |
| + return other.dispatch_type_ == dispatch_type_ && |
| + ScopedWebInputEventWithLatencyInfo::CanCoalesceWith(other); |
| +} |
| + |
| +void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { |
| + // If we are blocking and are coalescing touch, make sure to keep |
| + // the touch ids that need to be acked. |
| + if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) { |
| + // We should only have blocking touch events that need coalescing. |
| + DCHECK(blink::WebInputEvent::isTouchEventType(other.event().type)); |
| + eventsToAck_.push_back( |
| + WebInputEventTraits::GetUniqueTouchEventId(other.event())); |
| + } |
| + ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); |
| +} |
| + |
| +MainThreadEventQueue::MainThreadEventQueue( |
| + int routing_id, |
| + MainThreadEventQueueClient* client, |
| + const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) |
| + : routing_id_(routing_id), |
| + client_(client), |
| + is_flinging_(false), |
| + main_task_runner_(main_task_runner) {} |
| MainThreadEventQueue::~MainThreadEventQueue() {} |
| @@ -26,113 +60,81 @@ bool MainThreadEventQueue::HandleEvent( |
| ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; |
| InputEventDispatchType dispatch_type = |
| - non_blocking ? DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN |
| - : DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN; |
| - |
| - if (event->type == blink::WebInputEvent::MouseWheel) { |
| - PendingMouseWheelEvent modified_dispatch_type_event = |
| - PendingMouseWheelEvent( |
| - *static_cast<const blink::WebMouseWheelEvent*>(event), latency, |
| - dispatch_type); |
| - |
| - // Adjust the |dispatchType| on the event since the compositor |
| - // determined all event listeners are passive. |
| - if (non_blocking) { |
| - modified_dispatch_type_event.event.dispatchType = |
| + non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING; |
| + |
| + std::unique_ptr<EventWithDispatchType> cloned_event( |
| + new EventWithDispatchType(*event, latency, dispatch_type)); |
| + |
| + // Adjust the |dispatchType| on the event since the compositor |
| + // determined all event listeners are passive. |
| + if (non_blocking) { |
| + if (event->type == blink::WebInputEvent::MouseWheel) { |
| + static_cast<blink::WebMouseWheelEvent&>(cloned_event->event()) |
| + .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; |
| + } else if (blink::WebInputEvent::isTouchEventType(event->type)) { |
| + static_cast<blink::WebTouchEvent&>(cloned_event->event()).dispatchType = |
| blink::WebInputEvent::ListenersNonBlockingPassive; |
| } |
| - |
| - if (wheel_events_.state() == WebInputEventQueueState::ITEM_PENDING) { |
| - wheel_events_.Queue(modified_dispatch_type_event); |
| - } else { |
| - if (non_blocking) { |
| - wheel_events_.set_state(WebInputEventQueueState::ITEM_PENDING); |
| - client_->SendEventToMainThread(routing_id_, |
| - &modified_dispatch_type_event.event, |
| - latency, dispatch_type); |
| - } else { |
| - // If there is nothing in the event queue and the event is |
| - // blocking pass the |original_dispatch_type| to avoid |
| - // having the main thread call us back as an optimization. |
| - client_->SendEventToMainThread(routing_id_, |
| - &modified_dispatch_type_event.event, |
| - latency, original_dispatch_type); |
| - } |
| - } |
| - } else if (blink::WebInputEvent::isTouchEventType(event->type)) { |
| - PendingTouchEvent modified_dispatch_type_event = |
| - PendingTouchEvent(*static_cast<const blink::WebTouchEvent*>(event), |
| - latency, dispatch_type); |
| - modified_dispatch_type_event.event.dispatchedDuringFling = is_flinging_; |
| - |
| - // Adjust the |dispatchType| on the event since the compositor |
| - // determined all event listeners are passive. |
| - if (non_blocking) { |
| - modified_dispatch_type_event.event.dispatchType = |
| - blink::WebInputEvent::ListenersNonBlockingPassive; |
| - } |
| - |
| - if (touch_events_.state() == WebInputEventQueueState::ITEM_PENDING) { |
| - touch_events_.Queue(modified_dispatch_type_event); |
| - } else { |
| - if (non_blocking) { |
| - touch_events_.set_state(WebInputEventQueueState::ITEM_PENDING); |
| - client_->SendEventToMainThread(routing_id_, |
| - &modified_dispatch_type_event.event, |
| - latency, dispatch_type); |
| - } else { |
| - // If there is nothing in the event queue and the event is |
| - // blocking pass the |original_dispatch_type| to avoid |
| - // having the main thread call us back as an optimization. |
| - client_->SendEventToMainThread(routing_id_, |
| - &modified_dispatch_type_event.event, |
| - latency, original_dispatch_type); |
| - } |
| - } |
| - } else { |
| - client_->SendEventToMainThread(routing_id_, event, latency, |
| - original_dispatch_type); |
| } |
| + QueueEvent(std::move(cloned_event)); |
| // send an ack when we are non-blocking. |
| return non_blocking; |
| } |
| +void MainThreadEventQueue::PopEventOnMainThread() { |
| + { |
| + base::AutoLock lock(event_queue_mutex_); |
| + if (!events_.empty()) |
| + in_flight_event_ = events_.Pop(); |
| + } |
| + |
| + if (in_flight_event_) { |
| + InputEventDispatchType dispatch_type = in_flight_event_->dispatchType(); |
| + if (!in_flight_event_->eventsToAck().empty() && |
| + dispatch_type == DISPATCH_TYPE_BLOCKING) |
| + dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN; |
| + |
| + client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(), |
| + in_flight_event_->latencyInfo(), |
| + dispatch_type); |
| + } |
| + |
| + in_flight_event_.reset(); |
| + { |
| + base::AutoLock lock(event_queue_mutex_); |
| + if (!events_.empty()) { |
| + SendEventNotificationToMainThread(); |
| + } |
| + } |
| +} |
| + |
| void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, |
| InputEventAckState ack_result) { |
| - if (type == blink::WebInputEvent::MouseWheel) { |
| - // There should not be two blocking wheel events in flight. |
| - DCHECK(!in_flight_wheel_event_ || |
| - in_flight_wheel_event_->eventsToAck.size() == 0); |
| - |
| - if (!wheel_events_.empty()) { |
| - in_flight_wheel_event_ = wheel_events_.Pop(); |
| - client_->SendEventToMainThread( |
| - routing_id_, &in_flight_wheel_event_->event, |
| - in_flight_wheel_event_->latency, in_flight_wheel_event_->type); |
| - } else { |
| - in_flight_wheel_event_.reset(); |
| - wheel_events_.set_state(WebInputEventQueueState::ITEM_NOT_PENDING); |
| - } |
| - } else if (blink::WebInputEvent::isTouchEventType(type)) { |
| - if (in_flight_touch_event_) { |
| - // Send acks for blocking touch events. |
| - for (const auto id : in_flight_touch_event_->eventsToAck) |
| - client_->SendInputEventAck(routing_id_, type, ack_result, id); |
| + if (in_flight_event_) { |
| + DCHECK_EQ(in_flight_event_->event().type, type); |
| + // Send acks for blocking touch events. |
| + for (const auto id : in_flight_event_->eventsToAck()) |
|
tdresser
2016/07/20 20:52:27
I don't think we should use auto here.
dtapuska
2016/07/27 05:29:00
Is there a reason why?
tdresser
2016/07/27 13:51:50
From the style guide:
"auto is permitted ... when
|
| + client_->SendInputEventAck(routing_id_, type, ack_result, id); |
| } |
| +} |
| - if (!touch_events_.empty()) { |
| - in_flight_touch_event_ = touch_events_.Pop(); |
| - client_->SendEventToMainThread( |
| - routing_id_, &in_flight_touch_event_->event, |
| - in_flight_touch_event_->latency, in_flight_touch_event_->type); |
| - } else { |
| - in_flight_touch_event_.reset(); |
| - touch_events_.set_state(WebInputEventQueueState::ITEM_NOT_PENDING); |
| - } |
| - } else { |
| - NOTREACHED() << "Invalid passive event type"; |
| +void MainThreadEventQueue::SendEventNotificationToMainThread() { |
| + main_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread, |
| + base::Unretained(this))); |
| +} |
| + |
| +void MainThreadEventQueue::QueueEvent( |
| + std::unique_ptr<EventWithDispatchType>&& event) { |
| + size_t pending; |
| + { |
| + base::AutoLock lock(event_queue_mutex_); |
| + pending = events_.size(); |
| + events_.Queue(std::move(event)); |
| } |
| + if (pending == 0) |
| + SendEventNotificationToMainThread(); |
| } |
| } // namespace content |