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

Unified 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: Clean prototype up 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/input/main_thread_event_queue.cc
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc
index 8c1b8675cfafb469d36ae1841c51a4d9256fe32e..65aeb1951d01ceec925646cdb52891005e2fefdd 100644
--- a/content/renderer/input/main_thread_event_queue.cc
+++ b/content/renderer/input/main_thread_event_queue.cc
@@ -4,17 +4,37 @@
#include "content/renderer/input/main_thread_event_queue.h"
+#include "base/metrics/histogram_macros.h"
#include "content/common/input/event_with_latency_info.h"
#include "content/common/input_messages.h"
namespace content {
+namespace {
+
+// The maximum number of events processed per RAF task.
+const size_t kMaxEventsPerRafTask = 10;
tdresser 2016/08/24 13:42:59 I don't completely understand this constant. Supp
dtapuska 2016/08/24 17:10:06 So you want to send them all to the main thread at
+
+bool isContiniousEvent(const std::unique_ptr<EventWithDispatchType>& event) {
tdresser 2016/08/24 13:42:59 Continuous
dtapuska 2016/08/24 17:10:06 done; face palm.
+ switch (event->event().type) {
+ case blink::WebInputEvent::MouseMove:
+ case blink::WebInputEvent::TouchMove:
+ case blink::WebInputEvent::MouseWheel:
+ return true;
+ default:
+ return false;
+ }
+}
+} // namespace
+
EventWithDispatchType::EventWithDispatchType(
ui::ScopedWebInputEvent event,
const ui::LatencyInfo& latency,
InputEventDispatchType dispatch_type)
: ScopedWebInputEventWithLatencyInfo(std::move(event), latency),
- dispatch_type_(dispatch_type) {}
+ dispatch_type_(dispatch_type),
+ creation_timestamp_(base::TimeTicks::Now()),
+ coalesced_timestamp_(creation_timestamp_) {}
EventWithDispatchType::~EventWithDispatchType() {}
@@ -25,27 +45,26 @@ bool EventWithDispatchType::CanCoalesceWith(
}
void EventWithDispatchType::CoalesceWith(const EventWithDispatchType& other) {
- // If we are blocking and are coalescing touch, make sure to keep
- // the touch ids that need to be acked.
- if (dispatch_type_ == DISPATCH_TYPE_BLOCKING) {
- // We should only have blocking touch events that need coalescing.
- eventsToAck_.push_back(
- ui::WebInputEventTraits::GetUniqueTouchEventId(other.event()));
- }
+ coalesced_event_ids_.push_back(
+ ui::WebInputEventTraits::GetUniqueTouchEventId(other.event()));
ScopedWebInputEventWithLatencyInfo::CoalesceWith(other);
+ coalesced_timestamp_ = base::TimeTicks::Now();
}
MainThreadEventQueue::MainThreadEventQueue(
int routing_id,
MainThreadEventQueueClient* client,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
- blink::scheduler::RendererScheduler* renderer_scheduler)
+ blink::scheduler::RendererScheduler* renderer_scheduler,
+ bool handle_raf_aligned_input)
: routing_id_(routing_id),
client_(client),
is_flinging_(false),
last_touch_start_forced_nonblocking_due_to_fling_(false),
enable_fling_passive_listener_flag_(base::FeatureList::IsEnabled(
features::kPassiveEventListenersDueToFling)),
+ handle_raf_aligned_input_(handle_raf_aligned_input),
+ sent_main_frame_request_(false),
main_task_runner_(main_task_runner),
renderer_scheduler_(renderer_scheduler) {}
@@ -110,16 +129,35 @@ bool MainThreadEventQueue::HandleEvent(
return non_blocking;
}
-void MainThreadEventQueue::PopEventOnMainThread() {
- {
- base::AutoLock lock(event_queue_lock_);
- if (!events_.empty())
- in_flight_event_ = events_.Pop();
- }
-
+void MainThreadEventQueue::DispatchInFlightEvent() {
if (in_flight_event_) {
+ // Report the coalesced count only for continious events; otherwise
+ // the zero value would be dominated by non-continious events.
+ if (isContiniousEvent(in_flight_event_)) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.MainThreadEventQueue.Continious.QueueingTime",
+ (base::TimeTicks::Now() - in_flight_event_->creationTimestamp())
+ .ToInternalValue(),
+ 1, 10000000, 100);
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.MainThreadEventQueue.Continious.FreshnessTime",
+ (base::TimeTicks::Now() - in_flight_event_->coalescedTimestamp())
+ .ToInternalValue(),
+ 1, 10000000, 100);
+
+ UMA_HISTOGRAM_COUNTS_100("Event.MainThreadEventQueue.CoalescedCount",
+ in_flight_event_->coalescedEventIds().size());
+ } else {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.MainThreadEventQueue.NonContinious.QueueingTime",
+ (base::TimeTicks::Now() - in_flight_event_->creationTimestamp())
+ .ToInternalValue(),
+ 1, 10000000, 100);
+ }
+
InputEventDispatchType dispatch_type = in_flight_event_->dispatchType();
- if (!in_flight_event_->eventsToAck().empty() &&
+ if (!in_flight_event_->coalescedEventIds().empty() &&
dispatch_type == DISPATCH_TYPE_BLOCKING) {
dispatch_type = DISPATCH_TYPE_BLOCKING_NOTIFY_MAIN;
}
@@ -132,11 +170,40 @@ void MainThreadEventQueue::PopEventOnMainThread() {
in_flight_event_.reset();
}
+void MainThreadEventQueue::PossiblyScheduleMainFrame() {
+ if (!handle_raf_aligned_input_)
+ return;
+ bool needs_main_frame = false;
+ {
+ base::AutoLock lock(event_queue_lock_);
+ if (!sent_main_frame_request_ && !events_.empty() &&
+ isContiniousEvent(events_.front())) {
+ needs_main_frame = !sent_main_frame_request_;
+ sent_main_frame_request_ = false;
+ }
+ }
+ if (needs_main_frame)
+ client_->NeedsMainFrame(routing_id_);
+}
+
+void MainThreadEventQueue::DispatchSingleEvent() {
+ {
+ base::AutoLock lock(event_queue_lock_);
+ if (events_.empty())
+ return;
+
+ in_flight_event_ = events_.Pop();
+ }
+ DispatchInFlightEvent();
+ PossiblyScheduleMainFrame();
+}
+
void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
InputEventAckState ack_result) {
- if (in_flight_event_) {
- // Send acks for blocking touch events.
- for (const auto id : in_flight_event_->eventsToAck()) {
+ if (in_flight_event_ &&
+ in_flight_event_->dispatchType() == DISPATCH_TYPE_BLOCKING) {
+ // We should only have blocking touch events that need coalescing.
+ for (const auto id : in_flight_event_->coalescedEventIds()) {
client_->SendInputEventAck(routing_id_, type, ack_result, id);
if (renderer_scheduler_) {
renderer_scheduler_->DidHandleInputEventOnMainThread(
@@ -146,23 +213,68 @@ void MainThreadEventQueue::EventHandled(blink::WebInputEvent::Type type,
}
}
+void MainThreadEventQueue::DispatchRafAlignedInput() {
+ if (!handle_raf_aligned_input_)
+ return;
+
+ {
+ base::AutoLock lock(event_queue_lock_);
+ sent_main_frame_request_ = false;
+ }
+
+ for (size_t i = 0; i < kMaxEventsPerRafTask; ++i) {
+ {
+ base::AutoLock lock(event_queue_lock_);
+ if (events_.empty())
+ break;
+
+ if (!isContiniousEvent(events_.front()))
+ break;
+ in_flight_event_ = events_.Pop();
+ }
+ DispatchInFlightEvent();
+ }
+ PossiblyScheduleMainFrame();
+}
+
void MainThreadEventQueue::SendEventNotificationToMainThread() {
main_task_runner_->PostTask(
- FROM_HERE, base::Bind(&MainThreadEventQueue::PopEventOnMainThread,
- this));
+ FROM_HERE, base::Bind(&MainThreadEventQueue::DispatchSingleEvent, this));
}
void MainThreadEventQueue::QueueEvent(
std::unique_ptr<EventWithDispatchType> event) {
- bool send_notification = false;
+ bool isContinious = isContiniousEvent(event);
tdresser 2016/08/24 13:42:59 is_continuous
dtapuska 2016/08/24 17:10:06 done
+ size_t send_notification_count = 0;
+ bool needs_main_frame = false;
{
base::AutoLock lock(event_queue_lock_);
size_t size_before = events_.size();
events_.Queue(std::move(event));
- send_notification = events_.size() != size_before;
+ size_t size_after = events_.size();
+ if (size_before != size_after) {
+ if (!handle_raf_aligned_input_) {
+ send_notification_count = 1;
+ } else if (!isContinious) {
+ send_notification_count = 1;
+ // If we had just enqueued a non-RAF input event we will send a series
+ // of normal post messages to ensure they are all handled right away.
+ for (size_t pos = size_after - 1; pos >= 1; --pos) {
+ if (isContiniousEvent(events_.at(pos - 1)))
+ send_notification_count++;
+ else
+ break;
+ }
+ } else {
+ needs_main_frame = !sent_main_frame_request_;
+ sent_main_frame_request_ = true;
+ }
+ }
}
- if (send_notification)
+ for (size_t i = 0; i < send_notification_count; ++i)
SendEventNotificationToMainThread();
+ if (needs_main_frame)
+ client_->NeedsMainFrame(routing_id_);
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698