OLD | NEW |
(Empty) | |
| 1 |
| 2 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. |
| 5 |
| 6 #include "content/browser/renderer_host/input/wheel_event_queue.h" |
| 7 |
| 8 #include "base/auto_reset.h" |
| 9 #include "base/metrics/histogram.h" |
| 10 |
| 11 namespace content { |
| 12 |
| 13 WheelEventQueue::WheelEventQueue(WheelEventQueueClient* client, |
| 14 bool buffer_until_flush) |
| 15 : client_(client), |
| 16 buffer_until_flush_(buffer_until_flush), |
| 17 mouse_wheel_pending_(false), |
| 18 flushing_(false) {} |
| 19 |
| 20 WheelEventQueue::~WheelEventQueue() {} |
| 21 |
| 22 void WheelEventQueue::QueueEvent( |
| 23 const MouseWheelEventWithLatencyInfo& wheel_event) { |
| 24 if (mouse_wheel_pending_ || buffer_until_flush_) { |
| 25 // If there's already a mouse wheel event waiting to be sent to the |
| 26 // renderer, add the new deltas to that event. Not doing so (e.g., by |
| 27 // dropping the old event, as for mouse moves) results in very slow |
| 28 // scrolling on the Mac. |
| 29 DCHECK_IMPLIES(wheel_event.event.hasPreciseScrollingDeltas, |
| 30 wheel_event.event.canScroll); |
| 31 if (!coalesced_wheel_events_.empty() && |
| 32 coalesced_wheel_events_.back().CanCoalesceWith(wheel_event)) { |
| 33 coalesced_wheel_events_.back().CoalesceWith(wheel_event); |
| 34 TRACE_EVENT_INSTANT2("input", "InputRouterImpl::CoalescedWheelEvent", |
| 35 TRACE_EVENT_SCOPE_THREAD, "total_dx", |
| 36 coalesced_wheel_events_.back().event.deltaX, |
| 37 "total_dy", |
| 38 coalesced_wheel_events_.back().event.deltaY); |
| 39 } else { |
| 40 coalesced_wheel_events_.push_back(wheel_event); |
| 41 } |
| 42 if (buffer_until_flush_) |
| 43 client_->SetNeedsFlush(); |
| 44 return; |
| 45 } |
| 46 |
| 47 SendEvent(wheel_event); |
| 48 } |
| 49 |
| 50 void WheelEventQueue::ProcessWheelAck(InputEventAckState ack_result, |
| 51 const ui::LatencyInfo& latency) { |
| 52 DCHECK(mouse_wheel_pending_); |
| 53 // TODO(miletus): Add renderer side latency to each uncoalesced mouse |
| 54 // wheel event and add terminal component to each of them. |
| 55 current_wheel_event_.latency.AddNewLatencyFrom(latency); |
| 56 |
| 57 // Process the unhandled wheel event here before calling |SendEvent()| |
| 58 // since it will mutate current_wheel_event_. |
| 59 client_->OnWheelEventAck(current_wheel_event_, ack_result); |
| 60 |
| 61 // Mark the wheel event complete only after the ACKs have been handled above. |
| 62 // ACKing the event could cause another event to be enqueued, and that |
| 63 // event's sending should be deferred. |
| 64 mouse_wheel_pending_ = false; |
| 65 |
| 66 // Send the next (coalesced or synthetic) mouse wheel event. |
| 67 if (coalesced_wheel_events_.empty()) |
| 68 return; |
| 69 |
| 70 if (buffer_until_flush_ && !flushing_) { |
| 71 client_->SetNeedsFlush(); |
| 72 return; |
| 73 } |
| 74 |
| 75 MouseWheelEventWithLatencyInfo next_wheel_event = |
| 76 coalesced_wheel_events_.front(); |
| 77 coalesced_wheel_events_.pop_front(); |
| 78 SendEvent(next_wheel_event); |
| 79 } |
| 80 |
| 81 void WheelEventQueue::Flush() { |
| 82 if (!buffer_until_flush_) |
| 83 return; |
| 84 |
| 85 if (mouse_wheel_pending_) |
| 86 return; |
| 87 |
| 88 if (coalesced_wheel_events_.empty()) |
| 89 return; |
| 90 |
| 91 base::AutoReset<bool> flushing(&flushing_, false); |
| 92 MouseWheelEventWithLatencyInfo next_wheel_event = |
| 93 coalesced_wheel_events_.front(); |
| 94 coalesced_wheel_events_.pop_front(); |
| 95 SendEvent(next_wheel_event); |
| 96 DCHECK(mouse_wheel_pending_); |
| 97 } |
| 98 |
| 99 void WheelEventQueue::SendEvent( |
| 100 const MouseWheelEventWithLatencyInfo& wheel_event) { |
| 101 DCHECK(!mouse_wheel_pending_); |
| 102 mouse_wheel_pending_ = true; |
| 103 current_wheel_event_ = wheel_event; |
| 104 |
| 105 LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", |
| 106 coalesced_wheel_events_.size()); |
| 107 |
| 108 client_->SendWheelEventImmediately(wheel_event); |
| 109 } |
| 110 |
| 111 } // namespace content |
OLD | NEW |