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

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

Issue 2162143002: Don't use PostTask queueing between compositor and main thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add browser test, fix comments from #4 Created 4 years, 4 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 EventWithDispatchType::EventWithDispatchType( 11 EventWithDispatchType::EventWithDispatchType(
12 const blink::WebInputEvent& event, 12 const blink::WebInputEvent& event,
13 const ui::LatencyInfo& latency, 13 const ui::LatencyInfo& latency,
14 InputEventDispatchType dispatch_type) 14 InputEventDispatchType dispatch_type)
15 : ScopedWebInputEventWithLatencyInfo(event, latency), 15 : ScopedWebInputEventWithLatencyInfo(event, latency),
16 dispatch_type_(dispatch_type) {} 16 dispatch_type_(dispatch_type) {}
17 17
18 EventWithDispatchType::~EventWithDispatchType() {} 18 EventWithDispatchType::~EventWithDispatchType() {}
19 19
20 bool EventWithDispatchType::CanCoalesceWith( 20 bool EventWithDispatchType::CanCoalesceWith(
21 const EventWithDispatchType& other) const { 21 const EventWithDispatchType& other) const {
22 return other.dispatch_type_ == dispatch_type_ && 22 return other.dispatch_type_ == dispatch_type_ &&
23 ScopedWebInputEventWithLatencyInfo::CanCoalesceWith(other); 23 ScopedWebInputEventWithLatencyInfo::CanCoalesceWith(other);
24 } 24 }
25 25
26 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) { 26 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) {
27 // If we are blocking and are coalescing touch, make sure to keep 27 // If we are blocking and are coalescing touch, make sure to keep
28 // the touch ids that need to be acked. 28 // the touch ids that need to be acked.
29 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN) { 29 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) {
30 // We should only have blocking touch events that need coalescing. 30 // We should only have blocking touch events that need coalescing.
31 DCHECK(blink::WebInputEvent::isTouchEventType(other.event().type)); 31 DCHECK(blink::WebInputEvent::isTouchEventType(other.event().type));
32 eventsToAck_.push_back( 32 eventsToAck_.push_back(
33 WebInputEventTraits::GetUniqueTouchEventId(other.event())); 33 WebInputEventTraits::GetUniqueTouchEventId(other.event()));
34 } 34 }
35 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); 35 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
36 } 36 }
37 37
38 MainThreadEventQueue::MainThreadEventQueue(int routing_id, 38 MainThreadEventQueue::MainThreadEventQueue(
39 MainThreadEventQueueClient* client) 39 int routing_id,
40 MainThreadEventQueueClient* client,
41 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
40 : routing_id_(routing_id), 42 : routing_id_(routing_id),
41 client_(client), 43 client_(client),
42 is_flinging_(false), 44 is_flinging_(false),
43 sent_notification_to_main_(false) {} 45 sent_notification_to_main_(false),
46 main_task_runner_(main_task_runner) {}
44 47
45 MainThreadEventQueue::~MainThreadEventQueue() {} 48 MainThreadEventQueue::~MainThreadEventQueue() {}
46 49
47 bool MainThreadEventQueue::HandleEvent( 50 bool MainThreadEventQueue::HandleEvent(
48 const blink::WebInputEvent* event, 51 const blink::WebInputEvent* event,
49 const ui::LatencyInfo& latency, 52 const ui::LatencyInfo& latency,
50 InputEventDispatchType original_dispatch_type, 53 InputEventDispatchType original_dispatch_type,
51 InputEventAckState ack_result) { 54 InputEventAckState ack_result) {
52 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || 55 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING ||
53 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); 56 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
54 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || 57 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
55 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 58 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
56 59
57 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || 60 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING ||
58 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; 61 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
59 62
60 InputEventDispatchType dispatch_type = 63 InputEventDispatchType dispatch_type =
61 non_blocking ? DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN 64 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
62 : DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
63 65
64 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel; 66 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel;
65 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type); 67 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type);
66 68
67 if (is_wheel || is_touch) { 69 std::unique_ptr<EventWithDispatchType> cloned_event(
68 std::unique_ptr<EventWithDispatchType> cloned_event( 70 new EventWithDispatchType(*event, latency, dispatch_type));
69 new EventWithDispatchType(*event, latency, dispatch_type));
70 71
72 if (is_touch) {
73 blink::WebTouchEvent& touch_event =
74 static_cast<blink::WebTouchEvent&>(cloned_event->event());
75 touch_event.dispatchedDuringFling = is_flinging_;
71 // Adjust the |dispatchType| on the event since the compositor 76 // Adjust the |dispatchType| on the event since the compositor
72 // determined all event listeners are passive. 77 // determined all event listeners are passive.
73 if (non_blocking) { 78 if (non_blocking) {
74 if (is_wheel) { 79 touch_event.dispatchType =
75 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event()) 80 blink::WebInputEvent::ListenersNonBlockingPassive;
76 .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive;
77 } else if (is_touch) {
78 static_cast<blink::WebTouchEvent&>(cloned_event->event()).dispatchType =
79 blink::WebInputEvent::ListenersNonBlockingPassive;
80 }
81 } 81 }
82 }
83 if (is_wheel && non_blocking) {
84 // Adjust the |dispatchType| on the event since the compositor
85 // determined all event listeners are passive.
86 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event())
87 .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive;
88 }
82 89
83 if (is_touch) { 90 QueueEvent(std::move(cloned_event));
84 static_cast<blink::WebTouchEvent&>(cloned_event->event())
85 .dispatchedDuringFling = is_flinging_;
86 }
87
88 if (sent_notification_to_main_) {
89 events_.Queue(std::move(cloned_event));
90 } else {
91 if (non_blocking) {
92 sent_notification_to_main_ = true;
93 client_->SendEventToMainThread(routing_id_, &cloned_event->event(),
94 latency, dispatch_type);
95 } else {
96 // If there is nothing in the event queue and the event is
97 // blocking pass the |original_dispatch_type| to avoid
98 // having the main thread call us back as an optimization.
99 client_->SendEventToMainThread(routing_id_, &cloned_event->event(),
100 latency, original_dispatch_type);
101 }
102 }
103 } else {
104 client_->SendEventToMainThread(routing_id_, event, latency,
105 original_dispatch_type);
106 }
107 91
108 // send an ack when we are non-blocking. 92 // send an ack when we are non-blocking.
109 return non_blocking; 93 return non_blocking;
110 } 94 }
111 95
96 void MainThreadEventQueue::PopEventOnMainThread() {
97 {
98 base::AutoLock lock(event_queue_lock_);
99 if (!events_.empty())
100 in_flight_event_ = events_.Pop();
101 }
102
103 if (in_flight_event_) {
104 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
105 if (!in_flight_event_->eventsToAck().empty() &&
106 dispatch_type == DISPATCH_TYPE_BLOCKING)
tdresser 2016/08/04 18:02:22 I prefer {} when the condition or the body is mult
dtapuska 2016/08/08 15:34:03 Done.
107 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
108
109 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(),
110 in_flight_event_->latencyInfo(),
111 dispatch_type);
112 }
113
114 in_flight_event_.reset();
115 bool send_notification = false;
116 {
117 base::AutoLock lock(event_queue_lock_);
118 if (!events_.empty())
119 send_notification = true;
120 else
121 sent_notification_to_main_ = false;
122 }
123
124 if (send_notification)
125 SendEventNotificationToMainThread();
126 }
127
112 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, 128 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
113 InputEventAckState ack_result) { 129 InputEventAckState ack_result) {
114 if (in_flight_event_) { 130 if (in_flight_event_) {
115 // Send acks for blocking touch events. 131 // Send acks for blocking touch events.
116 for (const auto id : in_flight_event_->eventsToAck()) 132 for (const auto id : in_flight_event_->eventsToAck())
117 client_->SendInputEventAck(routing_id_, type, ack_result, id); 133 client_->SendInputEventAck(routing_id_, type, ack_result, id);
118 } 134 }
119 if (!events_.empty()) { 135 }
120 in_flight_event_ = events_.Pop(); 136
121 client_->SendEventToMainThread(routing_id_, &in_flight_event_->event(), 137 void MainThreadEventQueue::SendEventNotificationToMainThread() {
tdresser 2016/08/04 18:02:22 I'm a bit confused here. SendEventNotificationToM
dtapuska 2016/08/08 15:34:03 In the currently (ToT) event processing we only pr
tdresser 2016/08/08 16:56:05 Thanks. Maybe add a comment indicating in what con
122 in_flight_event_->latencyInfo(), 138 main_task_runner_->PostTask(
123 in_flight_event_->dispatchType()); 139 FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread,
124 } else { 140 base::Unretained(this)));
125 in_flight_event_.reset(); 141 }
126 sent_notification_to_main_ = false; 142
127 } 143 void MainThreadEventQueue::QueueEvent(
144 std::unique_ptr<EventWithDispatchType>&& event) {
145 bool send_notification = false;
146 {
147 base::AutoLock lock(event_queue_lock_);
148 send_notification = events_.empty();
149 events_.Queue(std::move(event));
150 sent_notification_to_main_ |= send_notification;
151 }
152 if (send_notification)
153 SendEventNotificationToMainThread();
128 } 154 }
129 155
130 } // namespace content 156 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698