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

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: Don't ack mouse move right away send them unthrottled 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"
7 #include "content/common/input_messages.h"
6 8
7 namespace content { 9 namespace content {
8 10
9 MainThreadEventQueue::MainThreadEventQueue(int routing_id, 11 EventWithDispatchType::EventWithDispatchType(
10 MainThreadEventQueueClient* client) 12 const blink::WebInputEvent& event,
11 : routing_id_(routing_id), client_(client), is_flinging_(false) {} 13 const ui::LatencyInfo& latency,
14 InputEventDispatchType dispatch_type)
15 : ScopedWebInputEventWithLatencyInfo(event, latency),
16 dispatch_type_(dispatch_type) {}
17
18 EventWithDispatchType::~EventWithDispatchType() {}
19
20 bool EventWithDispatchType::CanCoalesceWith(
21 const EventWithDispatchType& other) const {
22 return other.dispatch_type_ == dispatch_type_ &&
23 ScopedWebInputEventWithLatencyInfo::CanCoalesceWith(other);
24 }
25
26 void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) {
27 // If we are blocking and are coalescing touch, make sure to keep
28 // the touch ids that need to be acked.
29 if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) {
30 // We should only have blocking touch events that need coalescing.
31 DCHECK(blink::WebInputEvent::isTouchEventType(other.event().type));
32 eventsToAck_.push_back(
33 WebInputEventTraits::GetUniqueTouchEventId(other.event()));
34 }
35 ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
36 }
37
38 MainThreadEventQueue::MainThreadEventQueue(
39 int routing_id,
40 MainThreadEventQueueClient* client,
41 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
42 : routing_id_(routing_id),
43 client_(client),
44 is_flinging_(false),
45 main_task_runner_(main_task_runner) {}
12 46
13 MainThreadEventQueue::~MainThreadEventQueue() {} 47 MainThreadEventQueue::~MainThreadEventQueue() {}
14 48
15 bool MainThreadEventQueue::HandleEvent( 49 bool MainThreadEventQueue::HandleEvent(
16 const blink::WebInputEvent* event, 50 const blink::WebInputEvent* event,
17 const ui::LatencyInfo& latency, 51 const ui::LatencyInfo& latency,
18 InputEventDispatchType original_dispatch_type, 52 InputEventDispatchType original_dispatch_type,
19 InputEventAckState ack_result) { 53 InputEventAckState ack_result) {
20 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING || 54 DCHECK(original_dispatch_type == DISPATCH_TYPE_BLOCKING ||
21 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING); 55 original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING);
22 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || 56 DCHECK(ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
23 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 57 ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
24 58
25 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING || 59 bool non_blocking = original_dispatch_type == DISPATCH_TYPE_NON_BLOCKING ||
26 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING; 60 ack_result == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING;
27 61
28 InputEventDispatchType dispatch_type = 62 InputEventDispatchType dispatch_type =
29 non_blocking ? DISPATCH_TYPE_NON_BLOCKING_NOTIFY_MAIN 63 non_blocking ? DISPATCH_TYPE_NON_BLOCKING : DISPATCH_TYPE_BLOCKING;
30 : DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
31 64
32 if (event->type == blink::WebInputEvent::MouseWheel) { 65 std::unique_ptr<EventWithDispatchType> cloned_event(
33 PendingMouseWheelEvent modified_dispatch_type_event = 66 new EventWithDispatchType(*event, latency, dispatch_type));
34 PendingMouseWheelEvent(
35 *static_cast<const blink::WebMouseWheelEvent*>(event), latency,
36 dispatch_type);
37 67
38 // Adjust the |dispatchType| on the event since the compositor 68 // Adjust the |dispatchType| on the event since the compositor
39 // determined all event listeners are passive. 69 // determined all event listeners are passive.
40 if (non_blocking) { 70 if (non_blocking) {
41 modified_dispatch_type_event.event.dispatchType = 71 if (event->type == blink::WebInputEvent::MouseWheel) {
72 static_cast<blink::WebMouseWheelEvent&>(cloned_event->event())
73 .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive;
74 } else if (blink::WebInputEvent::isTouchEventType(event->type)) {
75 static_cast<blink::WebTouchEvent&>(cloned_event->event()).dispatchType =
42 blink::WebInputEvent::ListenersNonBlockingPassive; 76 blink::WebInputEvent::ListenersNonBlockingPassive;
43 } 77 }
44
45 if (wheel_events_.state() == WebInputEventQueueState::ITEM_PENDING) {
46 wheel_events_.Queue(modified_dispatch_type_event);
47 } else {
48 if (non_blocking) {
49 wheel_events_.set_state(WebInputEventQueueState::ITEM_PENDING);
50 client_->SendEventToMainThread(routing_id_,
51 &modified_dispatch_type_event.event,
52 latency, dispatch_type);
53 } else {
54 // If there is nothing in the event queue and the event is
55 // blocking pass the |original_dispatch_type| to avoid
56 // having the main thread call us back as an optimization.
57 client_->SendEventToMainThread(routing_id_,
58 &modified_dispatch_type_event.event,
59 latency, original_dispatch_type);
60 }
61 }
62 } else if (blink::WebInputEvent::isTouchEventType(event->type)) {
63 PendingTouchEvent modified_dispatch_type_event =
64 PendingTouchEvent(*static_cast<const blink::WebTouchEvent*>(event),
65 latency, dispatch_type);
66 modified_dispatch_type_event.event.dispatchedDuringFling = is_flinging_;
67
68 // Adjust the |dispatchType| on the event since the compositor
69 // determined all event listeners are passive.
70 if (non_blocking) {
71 modified_dispatch_type_event.event.dispatchType =
72 blink::WebInputEvent::ListenersNonBlockingPassive;
73 }
74
75 if (touch_events_.state() == WebInputEventQueueState::ITEM_PENDING) {
76 touch_events_.Queue(modified_dispatch_type_event);
77 } else {
78 if (non_blocking) {
79 touch_events_.set_state(WebInputEventQueueState::ITEM_PENDING);
80 client_->SendEventToMainThread(routing_id_,
81 &modified_dispatch_type_event.event,
82 latency, dispatch_type);
83 } else {
84 // If there is nothing in the event queue and the event is
85 // blocking pass the |original_dispatch_type| to avoid
86 // having the main thread call us back as an optimization.
87 client_->SendEventToMainThread(routing_id_,
88 &modified_dispatch_type_event.event,
89 latency, original_dispatch_type);
90 }
91 }
92 } else {
93 client_->SendEventToMainThread(routing_id_, event, latency,
94 original_dispatch_type);
95 } 78 }
79 QueueEvent(std::move(cloned_event));
96 80
97 // send an ack when we are non-blocking. 81 // send an ack when we are non-blocking.
98 return non_blocking; 82 return non_blocking;
99 } 83 }
100 84
101 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type, 85 void MainThreadEventQueue::PopEventOnMainThread() {
102 InputEventAckState ack_result) { 86 {
103 if (type == blink::WebInputEvent::MouseWheel) { 87 base::AutoLock lock(event_queue_mutex_);
104 // There should not be two blocking wheel events in flight. 88 if (!events_.empty())
105 DCHECK(!in_flight_wheel_event_ || 89 in_flight_event_ = events_.Pop();
106 in_flight_wheel_event_->eventsToAck.size() == 0); 90 }
107 91
108 if (!wheel_events_.empty()) { 92 if (in_flight_event_) {
109 in_flight_wheel_event_ = wheel_events_.Pop(); 93 InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
110 client_->SendEventToMainThread( 94 if (!in_flight_event_->eventsToAck().empty() &&
111 routing_id_, &in_flight_wheel_event_->event, 95 dispatch_type == DISPATCH_TYPE_BLOCKING)
112 in_flight_wheel_event_->latency, in_flight_wheel_event_->type); 96 dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
113 } else { 97
114 in_flight_wheel_event_.reset(); 98 client_->HandleEventOnMainThread(routing_id_, &in_flight_event_->event(),
115 wheel_events_.set_state(WebInputEventQueueState::ITEM_NOT_PENDING); 99 in_flight_event_->latencyInfo(),
100 dispatch_type);
101 }
102
103 in_flight_event_.reset();
104 {
105 base::AutoLock lock(event_queue_mutex_);
106 if (!events_.empty()) {
107 SendEventNotificationToMainThread();
116 } 108 }
117 } else if (blink::WebInputEvent::isTouchEventType(type)) {
118 if (in_flight_touch_event_) {
119 // Send acks for blocking touch events.
120 for (const auto id : in_flight_touch_event_->eventsToAck)
121 client_->SendInputEventAck(routing_id_, type, ack_result, id);
122 }
123
124 if (!touch_events_.empty()) {
125 in_flight_touch_event_ = touch_events_.Pop();
126 client_->SendEventToMainThread(
127 routing_id_, &in_flight_touch_event_->event,
128 in_flight_touch_event_->latency, in_flight_touch_event_->type);
129 } else {
130 in_flight_touch_event_.reset();
131 touch_events_.set_state(WebInputEventQueueState::ITEM_NOT_PENDING);
132 }
133 } else {
134 NOTREACHED() << "Invalid passive event type";
135 } 109 }
136 } 110 }
137 111
112 void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
113 InputEventAckState ack_result) {
114 if (in_flight_event_) {
115 DCHECK_EQ(in_flight_event_->event().type, type);
116 // Send acks for blocking touch events.
117 for (const auto id : in_flight_event_->eventsToAck())
tdresser 2016/07/20 20:52:27 I don't think we should use auto here.
dtapuska 2016/07/27 05:29:00 Is there a reason why?
tdresser 2016/07/27 13:51:50 From the style guide: "auto is permitted ... when
118 client_->SendInputEventAck(routing_id_, type, ack_result, id);
119 }
120 }
121
122 void MainThreadEventQueue::SendEventNotificationToMainThread() {
123 main_task_runner_->PostTask(
124 FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread,
125 base::Unretained(this)));
126 }
127
128 void MainThreadEventQueue::QueueEvent(
129 std::unique_ptr<EventWithDispatchType>&& event) {
130 size_t pending;
131 {
132 base::AutoLock lock(event_queue_mutex_);
133 pending = events_.size();
134 events_.Queue(std::move(event));
135 }
136 if (pending == 0)
137 SendEventNotificationToMainThread();
138 }
139
138 } // namespace content 140 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698