Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/input/main_thread_event_queue.h" | 5 #include "content/renderer/input/main_thread_event_queue.h" |
| 6 #include "content/common/input/event_with_latency_info.h" | 6 #include "content/common/input/event_with_latency_info.h" |
| 7 #include "content/common/input_messages.h" | 7 #include "content/common/input_messages.h" |
| 8 | 8 |
| 9 namespace content { | 9 namespace content { |
| 10 | 10 |
| 11 namespace { | |
| 12 const size_t kMaxEventsPerVSyncEvent = 10; | |
|
tdresser
2016/07/20 21:43:09
Add a comment about this constant - why do we need
| |
| 13 bool isVSyncAlignedEvent(const std::unique_ptr<EventWithDispatchType>& event) { | |
|
tdresser
2016/07/20 21:43:09
I'd name this something like eventCanBeRafAligned.
| |
| 14 switch (event->event().type) { | |
| 15 case blink::WebInputEvent::MouseMove: | |
| 16 case blink::WebInputEvent::TouchMove: | |
| 17 case blink::WebInputEvent::MouseWheel: | |
| 18 return true; | |
| 19 default: | |
| 20 return false; | |
| 21 } | |
| 22 } | |
| 23 } // namespace | |
| 24 | |
| 11 EventWithDispatchType::EventWithDispatchType( | 25 EventWithDispatchType::EventWithDispatchType( |
| 12 const blink::WebInputEvent& event, | 26 const blink::WebInputEvent& event, |
| 13 const ui::LatencyInfo& latency, | 27 const ui::LatencyInfo& latency, |
| 14 InputEventDispatchType dispatch_type) | 28 InputEventDispatchType dispatch_type) |
| 15 : ScopedWebInputEventWithLatencyInfo(event, latency), | 29 : ScopedWebInputEventWithLatencyInfo(event, latency), |
| 16 dispatch_type_(dispatch_type) {} | 30 dispatch_type_(dispatch_type) {} |
| 17 | 31 |
| 18 EventWithDispatchType::~EventWithDispatchType() {} | 32 EventWithDispatchType::~EventWithDispatchType() {} |
| 19 | 33 |
| 20 bool EventWithDispatchType::CanCoalesceWith( | 34 bool EventWithDispatchType::CanCoalesceWith( |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 35 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); | 49 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); |
| 36 } | 50 } |
| 37 | 51 |
| 38 MainThreadEventQueue::MainThreadEventQueue( | 52 MainThreadEventQueue::MainThreadEventQueue( |
| 39 int routing_id, | 53 int routing_id, |
| 40 MainThreadEventQueueClient* client, | 54 MainThreadEventQueueClient* client, |
| 41 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) | 55 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner) |
| 42 : routing_id_(routing_id), | 56 : routing_id_(routing_id), |
| 43 client_(client), | 57 client_(client), |
| 44 is_flinging_(false), | 58 is_flinging_(false), |
| 59 notification_sent_to_main_(false), | |
| 45 main_task_runner_(main_task_runner) {} | 60 main_task_runner_(main_task_runner) {} |
| 46 | 61 |
| 47 MainThreadEventQueue::~MainThreadEventQueue() {} | 62 MainThreadEventQueue::~MainThreadEventQueue() {} |
| 48 | 63 |
| 49 bool MainThreadEventQueue::HandleEvent( | 64 bool MainThreadEventQueue::HandleEvent( |
| 50 const blink::WebInputEvent* event, | 65 const blink::WebInputEvent* event, |
| 51 const ui::LatencyInfo& latency, | 66 const ui::LatencyInfo& latency, |
| 52 InputEventDispatchType original_dispatch_type, | 67 InputEventDispatchType original_dispatch_type, |
| 53 InputEventAckState ack_result) { | 68 InputEventAckState ack_result) { |
| 54 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || | 69 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 76 static_cast<blink::WebTouchEvent&>(cloned_event->event()).dispatchType = | 91 static_cast<blink::WebTouchEvent&>(cloned_event->event()).dispatchType = |
| 77 blink::WebInputEvent::ListenersNonBlockingPassive; | 92 blink::WebInputEvent::ListenersNonBlockingPassive; |
| 78 } | 93 } |
| 79 } | 94 } |
| 80 QueueEvent(std::move(cloned_event)); | 95 QueueEvent(std::move(cloned_event)); |
| 81 | 96 |
| 82 // send an ack when we are non-blocking. | 97 // send an ack when we are non-blocking. |
| 83 return non_blocking; | 98 return non_blocking; |
| 84 } | 99 } |
| 85 | 100 |
| 86 void MainThreadEventQueue::PopEventOnMainThread() { | 101 void MainThreadEventQueue::DispatchInFlightEvent() { |
| 87 { | |
| 88 base::AutoLock lock(event_queue_mutex_); | |
| 89 if (!events_.empty()) | |
| 90 in_flight_event_ = events_.Pop(); | |
| 91 } | |
| 92 | |
| 93 if (in_flight_event_) { | 102 if (in_flight_event_) { |
| 94 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType(); | 103 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType(); |
| 95 if (!in_flight_event_->eventsToAck().empty() && | 104 if (!in_flight_event_->eventsToAck().empty() && |
| 96 dispatch_type == DISPATCH_TYPE_BLOCKING) | 105 dispatch_type == DISPATCH_TYPE_BLOCKING) |
| 97 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN; | 106 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN; |
| 98 | 107 |
| 99 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(), | 108 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(), |
| 100 in_flight_event_->latencyInfo(), | 109 in_flight_event_->latencyInfo(), |
| 101 dispatch_type); | 110 dispatch_type); |
| 102 } | 111 } |
| 103 | 112 |
| 104 in_flight_event_.reset(); | 113 in_flight_event_.reset(); |
| 114 } | |
| 115 | |
| 116 void MainThreadEventQueue::PopEventOnMainThread() { | |
| 105 { | 117 { |
| 106 base::AutoLock lock(event_queue_mutex_); | 118 base::AutoLock lock(event_queue_mutex_); |
| 107 if (!events_.empty()) { | 119 if (!events_.empty()) |
| 120 in_flight_event_ = events_.Pop(); | |
| 121 } | |
| 122 | |
| 123 DispatchInFlightEvent(); | |
| 124 | |
| 125 { | |
| 126 base::AutoLock lock(event_queue_mutex_); | |
| 127 if (!events_.empty()) | |
| 108 SendEventNotificationToMainThread(); | 128 SendEventNotificationToMainThread(); |
| 109 } | 129 else |
| 130 notification_sent_to_main_ = false; | |
| 110 } | 131 } |
| 111 } | 132 } |
| 112 | 133 |
| 113 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, | 134 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, |
| 114 InputEventAckState ack_result) { | 135 InputEventAckState ack_result) { |
| 115 if (in_flight_event_) { | 136 if (in_flight_event_) { |
| 116 DCHECK_EQ(in_flight_event_->event().type, type); | 137 DCHECK_EQ(in_flight_event_->event().type, type); |
| 117 // Send acks for blocking touch events. | 138 // Send acks for blocking touch events. |
| 118 for (const auto id : in_flight_event_->eventsToAck()) | 139 for (const auto id : in_flight_event_->eventsToAck()) |
| 119 client_->SendInputEventAck(routing_id_, type, ack_result, id); | 140 client_->SendInputEventAck(routing_id_, type, ack_result, id); |
| 120 } | 141 } |
| 121 } | 142 } |
| 122 | 143 |
| 144 void MainThreadEventQueue::DispatchVSyncAlignedInput() { | |
| 145 size_t i = 0; | |
| 146 for (; i < kMaxEventsPerVSyncEvent; ++i) { | |
| 147 { | |
| 148 base::AutoLock lock(event_queue_mutex_); | |
| 149 if (events_.empty()) | |
| 150 break; | |
| 151 if (!isVSyncAlignedEvent(events_.Top())) | |
| 152 break; | |
| 153 in_flight_event_ = events_.Pop(); | |
| 154 } | |
| 155 DispatchInFlightEvent(); | |
| 156 } | |
| 157 LOG(ERROR) << "Processed " << i << " events in RAF"; | |
|
tdresser
2016/07/20 21:43:08
Remember to remove this before landing (and make t
| |
| 158 } | |
| 159 | |
| 123 void MainThreadEventQueue::SendEventNotificationToMainThread() { | 160 void MainThreadEventQueue::SendEventNotificationToMainThread() { |
| 124 main_task_runner_->PostTask( | 161 main_task_runner_->PostTask( |
| 125 FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread, | 162 FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread, |
| 126 base::Unretained(this))); | 163 base::Unretained(this))); |
| 127 } | 164 } |
| 128 | 165 |
| 129 void MainThreadEventQueue::QueueEvent( | 166 void MainThreadEventQueue::QueueEvent( |
| 130 std::unique_ptr<EventWithDispatchType>&& event) { | 167 std::unique_ptr<EventWithDispatchType>&& event) { |
| 131 size_t pending; | 168 bool isVsynced = isVSyncAlignedEvent(event); |
|
tdresser
2016/07/20 21:43:08
Inconsistent casing here.
| |
| 169 bool send_notification = false; | |
| 132 { | 170 { |
| 133 base::AutoLock lock(event_queue_mutex_); | 171 base::AutoLock lock(event_queue_mutex_); |
| 134 pending = events_.size(); | |
| 135 events_.Queue(std::move(event)); | 172 events_.Queue(std::move(event)); |
| 173 if (!isVsynced && !notification_sent_to_main_) { | |
| 174 send_notification = true; | |
| 175 notification_sent_to_main_ = true; | |
| 176 } | |
| 136 } | 177 } |
| 137 if (pending == 0) | 178 if (send_notification) |
| 138 SendEventNotificationToMainThread(); | 179 SendEventNotificationToMainThread(); |
| 139 } | 180 } |
| 140 | 181 |
| 141 } // namespace content | 182 } // namespace content |
| OLD | NEW |