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

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: Fix fairness of post tasks it was causing some tests to fail 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 main_task_runner_(main_task_runner) {}
44 45
45 MainThreadEventQueue::~MainThreadEventQueue() {} 46 MainThreadEventQueue::~MainThreadEventQueue() {}
46 47
47 bool MainThreadEventQueue::HandleEvent( 48 bool MainThreadEventQueue::HandleEvent(
48 const blink::WebInputEvent* event, 49 const blink::WebInputEvent* event,
49 const ui::LatencyInfo& latency, 50 const ui::LatencyInfo& latency,
50 InputEventDispatchType original_dispatch_type, 51 InputEventDispatchType original_dispatch_type,
51 InputEventAckState ack_result) { 52 InputEventAckState ack_result) {
52 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || 53 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING ||
53 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); 54 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
54 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || 55 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
55 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 56 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
56 57
57 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || 58 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING ||
58 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; 59 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
59 60
60 InputEventDispatchType dispatch_type = 61 InputEventDispatchType dispatch_type =
61 non_blocking ? DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN 62 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
62 : DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
63 63
64 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel; 64 bool is_wheel = event->type == blink::WebInputEvent::MouseWheel;
65 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type); 65 bool is_touch = blink::WebInputEvent::isTouchEventType(event->type);
66 66
67 if (is_wheel || is_touch) { 67 std::unique_ptr<EventWithDispatchType> cloned_event(
68 std::unique_ptr<EventWithDispatchType> cloned_event( 68 new EventWithDispatchType(*event, latency, dispatch_type));
69 new EventWithDispatchType(*event, latency, dispatch_type));
70 69
70 if (is_touch) {
71 blink::WebTouchEvent& touch_event =
72 static_cast<blink::WebTouchEvent&>(cloned_event->event());
73 touch_event.dispatchedDuringFling = is_flinging_;
71 // Adjust the |dispatchType| on the event since the compositor 74 // Adjust the |dispatchType| on the event since the compositor
72 // determined all event listeners are passive. 75 // determined all event listeners are passive.
73 if (non_blocking) { 76 if (non_blocking) {
74 if (is_wheel) { 77 touch_event.dispatchType =
75 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event()) 78 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 } 79 }
80 }
81 if (is_wheel && non_blocking) {
82 // Adjust the |dispatchType| on the event since the compositor
83 // determined all event listeners are passive.
84 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event())
85 .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive;
86 }
82 87
83 if (is_touch) { 88 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 89
108 // send an ack when we are non-blocking. 90 // send an ack when we are non-blocking.
109 return non_blocking; 91 return non_blocking;
110 } 92 }
111 93
94 void MainThreadEventQueue::PopEventOnMainThread() {
95 {
96 base::AutoLock lock(event_queue_lock_);
97 if (!events_.empty())
98 in_flight_event_ = events_.Pop();
99 }
100
101 if (in_flight_event_) {
102 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
103 if (!in_flight_event_->eventsToAck().empty() &&
104 dispatch_type == DISPATCH_TYPE_BLOCKING) {
105 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
106 }
107
108 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(),
109 in_flight_event_->latencyInfo(),
110 dispatch_type);
111 }
112
113 in_flight_event_.reset();
114 }
115
112 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, 116 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
113 InputEventAckState ack_result) { 117 InputEventAckState ack_result) {
114 if (in_flight_event_) { 118 if (in_flight_event_) {
115 // Send acks for blocking touch events. 119 // Send acks for blocking touch events.
116 for (const auto id : in_flight_event_->eventsToAck()) 120 for (const auto id : in_flight_event_->eventsToAck())
117 client_->SendInputEventAck(routing_id_, type, ack_result, id); 121 client_->SendInputEventAck(routing_id_, type, ack_result, id);
118 } 122 }
119 if (!events_.empty()) { 123 }
120 in_flight_event_ = events_.Pop(); 124
121 client_->SendEventToMainThread(routing_id_, &in_flight_event_->event(), 125 void MainThreadEventQueue::SendEventNotificationToMainThread() {
122 in_flight_event_->latencyInfo(), 126 main_task_runner_->PostTask(
123 in_flight_event_->dispatchType()); 127 FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread,
124 } else { 128 base::Unretained(this)));
125 in_flight_event_.reset(); 129 }
126 sent_notification_to_main_ = false; 130
127 } 131 void MainThreadEventQueue::QueueEvent(
132 std::unique_ptr<EventWithDispatchType> event) {
133 bool send_notification = false;
134 {
135 base::AutoLock lock(event_queue_lock_);
136 size_t size_before = events_.size();
137 events_.Queue(std::move(event));
138 send_notification = events_.size() != size_before;
139 }
140 if (send_notification)
141 SendEventNotificationToMainThread();
128 } 142 }
129 143
130 } // namespace content 144 } // 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