Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: content/renderer/input/main_thread_event_queue.cc

Issue 2166703003: Implement Main Thread RAF Aligned Input (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master_main_thread_queue
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698