| Index: content/browser/renderer_host/input/touch_event_queue.cc
|
| diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
|
| index d98655a1668f58f6aea392e15ad41341997c943d..8b03c889980329715a5e70dd6a9c9b07788a865d 100644
|
| --- a/content/browser/renderer_host/input/touch_event_queue.cc
|
| +++ b/content/browser/renderer_host/input/touch_event_queue.cc
|
| @@ -253,15 +253,9 @@ class TouchEventQueue::TouchMoveSlopSuppressor {
|
| // the Client receives the event with their original timestamp.
|
| class CoalescedWebTouchEvent {
|
| public:
|
| - // Events for which |async| is true will not be ack'ed to the client after the
|
| - // corresponding ack is received following dispatch.
|
| - CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, bool async)
|
| - : coalesced_event_(event) {
|
| - if (async)
|
| - coalesced_event_.event.cancelable = false;
|
| - else
|
| - events_to_ack_.push_back(event);
|
| -
|
| + CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event,
|
| + bool suppress_client_ack)
|
| + : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) {
|
| TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventQueue::QueueEvent", this);
|
| }
|
|
|
| @@ -273,42 +267,48 @@ class CoalescedWebTouchEvent {
|
| // the event was coalesced.
|
| bool CoalesceEventIfPossible(
|
| const TouchEventWithLatencyInfo& event_with_latency) {
|
| - if (!WillDispatchAckToClient())
|
| + if (suppress_client_ack_)
|
| return false;
|
|
|
| if (!coalesced_event_.CanCoalesceWith(event_with_latency))
|
| return false;
|
|
|
| + // Addition of the first event to |uncoaleseced_events_to_ack_| is deferred
|
| + // until the first coalesced event, optimizing the (common) case where the
|
| + // event is not coalesced at all.
|
| + if (uncoaleseced_events_to_ack_.empty())
|
| + uncoaleseced_events_to_ack_.push_back(coalesced_event_);
|
| +
|
| TRACE_EVENT_INSTANT0(
|
| "input", "TouchEventQueue::MoveCoalesced", TRACE_EVENT_SCOPE_THREAD);
|
| coalesced_event_.CoalesceWith(event_with_latency);
|
| - events_to_ack_.push_back(event_with_latency);
|
| + uncoaleseced_events_to_ack_.push_back(event_with_latency);
|
| + DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U);
|
| return true;
|
| }
|
|
|
| - void UpdateLatencyInfoForAck(const ui::LatencyInfo& renderer_latency_info) {
|
| - if (!WillDispatchAckToClient())
|
| - return;
|
| -
|
| - for (WebTouchEventWithLatencyList::iterator iter = events_to_ack_.begin(),
|
| - end = events_to_ack_.end();
|
| - iter != end;
|
| - ++iter) {
|
| - iter->latency.AddNewLatencyFrom(renderer_latency_info);
|
| - }
|
| - }
|
| -
|
| void DispatchAckToClient(InputEventAckState ack_result,
|
| + const ui::LatencyInfo* optional_latency_info,
|
| TouchEventQueueClient* client) {
|
| DCHECK(client);
|
| - if (!WillDispatchAckToClient())
|
| + if (suppress_client_ack_)
|
| return;
|
|
|
| - for (WebTouchEventWithLatencyList::const_iterator
|
| - iter = events_to_ack_.begin(),
|
| - end = events_to_ack_.end();
|
| + if (uncoaleseced_events_to_ack_.empty()) {
|
| + if (optional_latency_info)
|
| + coalesced_event_.latency.AddNewLatencyFrom(*optional_latency_info);
|
| + client->OnTouchEventAck(coalesced_event_, ack_result);
|
| + return;
|
| + }
|
| +
|
| + DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U);
|
| + for (WebTouchEventWithLatencyList::iterator
|
| + iter = uncoaleseced_events_to_ack_.begin(),
|
| + end = uncoaleseced_events_to_ack_.end();
|
| iter != end;
|
| ++iter) {
|
| + if (optional_latency_info)
|
| + iter->latency.AddNewLatencyFrom(*optional_latency_info);
|
| client->OnTouchEventAck(*iter, ack_result);
|
| }
|
| }
|
| @@ -318,15 +318,16 @@ class CoalescedWebTouchEvent {
|
| }
|
|
|
| private:
|
| - bool WillDispatchAckToClient() const { return !events_to_ack_.empty(); }
|
| -
|
| // This is the event that is forwarded to the renderer.
|
| TouchEventWithLatencyInfo coalesced_event_;
|
|
|
| // This is the list of the original events that were coalesced, each requiring
|
| // future ack dispatch to the client.
|
| + // Note that this will be empty if no coalescing has occurred.
|
| typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
|
| - WebTouchEventWithLatencyList events_to_ack_;
|
| + WebTouchEventWithLatencyList uncoaleseced_events_to_ack_;
|
| +
|
| + bool suppress_client_ack_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
|
| };
|
| @@ -695,20 +696,19 @@ void TouchEventQueue::FlushQueue() {
|
| }
|
|
|
| void TouchEventQueue::PopTouchEventToClient(InputEventAckState ack_result) {
|
| - AckTouchEventToClient(ack_result, PopTouchEvent());
|
| + AckTouchEventToClient(ack_result, PopTouchEvent(), NULL);
|
| }
|
|
|
| void TouchEventQueue::PopTouchEventToClient(
|
| InputEventAckState ack_result,
|
| const LatencyInfo& renderer_latency_info) {
|
| - scoped_ptr<CoalescedWebTouchEvent> acked_event = PopTouchEvent();
|
| - acked_event->UpdateLatencyInfoForAck(renderer_latency_info);
|
| - AckTouchEventToClient(ack_result, acked_event.Pass());
|
| + AckTouchEventToClient(ack_result, PopTouchEvent(), &renderer_latency_info);
|
| }
|
|
|
| void TouchEventQueue::AckTouchEventToClient(
|
| InputEventAckState ack_result,
|
| - scoped_ptr<CoalescedWebTouchEvent> acked_event) {
|
| + scoped_ptr<CoalescedWebTouchEvent> acked_event,
|
| + const ui::LatencyInfo* optional_latency_info) {
|
| DCHECK(acked_event);
|
| DCHECK(!dispatching_touch_ack_);
|
| UpdateTouchAckStates(acked_event->coalesced_event().event, ack_result);
|
| @@ -717,7 +717,7 @@ void TouchEventQueue::AckTouchEventToClient(
|
| // to the renderer, or touch-events being queued.
|
| base::AutoReset<const CoalescedWebTouchEvent*> dispatching_touch_ack(
|
| &dispatching_touch_ack_, acked_event.get());
|
| - acked_event->DispatchAckToClient(ack_result, client_);
|
| + acked_event->DispatchAckToClient(ack_result, optional_latency_info, client_);
|
| }
|
|
|
| scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() {
|
|
|