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

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: Address issues with test and fix dchecks in debug mode 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));
32 eventsToAck_.push_back( 31 eventsToAck_.push_back(
33 WebInputEventTraits::GetUniqueTouchEventId(other.event())); 32 WebInputEventTraits::GetUniqueTouchEventId(other.event()));
34 } 33 }
35 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other); 34 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
36 } 35 }
37 36
38 MainThreadEventQueue::MainThreadEventQueue(int routing_id, 37 MainThreadEventQueue::MainThreadEventQueue(
39 MainThreadEventQueueClient* client) 38 int routing_id,
39 MainThreadEventQueueClient* client,
40 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
40 : routing_id_(routing_id), 41 : routing_id_(routing_id),
41 client_(client), 42 client_(client),
42 is_flinging_(false), 43 is_flinging_(false),
43 sent_notification_to_main_(false) {} 44 sent_notification_to_main_(false),
45 main_task_runner_(main_task_runner) {}
44 46
45 MainThreadEventQueue::~MainThreadEventQueue() {} 47 MainThreadEventQueue::~MainThreadEventQueue() {}
46 48
47 bool MainThreadEventQueue::HandleEvent( 49 bool MainThreadEventQueue::HandleEvent(
48 const blink::WebInputEvent* event, 50 const blink::WebInputEvent* event,
49 const ui::LatencyInfo& latency, 51 const ui::LatencyInfo& latency,
50 InputEventDispatchType original_dispatch_type, 52 InputEventDispatchType original_dispatch_type,
51 InputEventAckState ack_result) { 53 InputEventAckState ack_result) {
52 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || 54 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING ||
53 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); 55 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
54 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || 56 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
55 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 57 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
56 58
57 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || 59 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING ||
58 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; 60 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
59 61
60 InputEventDispatchType dispatch_type = 62 InputEventDispatchType dispatch_type =
61 non_blocking ? DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN 63 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
62 : DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
63 64
64 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel; 65 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel;
65 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type); 66 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type);
66 67
67 if (is_wheel || is_touch) { 68 std::unique_ptr<EventWithDispatchType> cloned_event(
68 std::unique_ptr<EventWithDispatchType> cloned_event( 69 new EventWithDispatchType(*event, latency, dispatch_type));
69 new EventWithDispatchType(*event, latency, dispatch_type));
70 70
71 if (is_touch) {
72 blink::WebTouchEvent& touch_event =
73 static_cast<blink::WebTouchEvent&>(cloned_event->event());
74 touch_event.dispatchedDuringFling = is_flinging_;
71 // Adjust the |dispatchType| on the event since the compositor 75 // Adjust the |dispatchType| on the event since the compositor
72 // determined all event listeners are passive. 76 // determined all event listeners are passive.
73 if (non_blocking) { 77 if (non_blocking) {
74 if (is_wheel) { 78 touch_event.dispatchType =
75 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event()) 79 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 } 80 }
81 }
82 if (is_wheel && non_blocking) {
83 // Adjust the |dispatchType| on the event since the compositor
84 // determined all event listeners are passive.
85 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event())
86 .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive;
87 }
82 88
83 if (is_touch) { 89 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 90
108 // send an ack when we are non-blocking. 91 // send an ack when we are non-blocking.
109 return non_blocking; 92 return non_blocking;
110 } 93 }
111 94
95 void MainThreadEventQueue::PopEventOnMainThread() {
96 {
97 base::AutoLock lock(event_queue_lock_);
98 if (!events_.empty())
99 in_flight_event_ = events_.Pop();
100 }
101
102 if (in_flight_event_) {
103 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
104 if (!in_flight_event_->eventsToAck().empty() &&
105 dispatch_type == DISPATCH_TYPE_BLOCKING) {
106 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
107 }
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() {
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) {
tdresser 2016/08/08 16:56:05 We aren't allowed to use && here, are we?
dtapuska 2016/08/08 20:11:24 Done.
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
« no previous file with comments | « content/renderer/input/main_thread_event_queue.h ('k') | content/renderer/input/main_thread_event_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698