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 |