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 |