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

Unified Diff: ui/events/blink/input_handler_proxy.cc

Issue 2429953002: Implement compositor thread VSync aligned event queue (Closed)
Patch Set: dtapuska's review: Non-template CompositorThreadEventQueue; Added blink_features.h; UMA only when e… Created 4 years, 1 month 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: ui/events/blink/input_handler_proxy.cc
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index 01d2544ceebb997e47f6822a2eea07fb510480f0..f6112cdda97203393cf51a532b332d90920dc49c 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -12,13 +12,16 @@
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
+#include "ui/events/blink/compositor_thread_event_queue.h"
#include "ui/events/blink/did_overscroll_params.h"
+#include "ui/events/blink/event_with_callback.h"
#include "ui/events/blink/input_handler_proxy_client.h"
#include "ui/events/blink/input_scroll_elasticity_controller.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -62,6 +65,8 @@ const double kMinBoostTouchScrollSpeedSquare = 150 * 150.;
// slightly increased value to accomodate small IPC message delays.
const double kFlingBoostTimeoutDelaySeconds = 0.05;
+const size_t kTenSeconds = 10 * 1000 * 1000;
+
gfx::Vector2dF ToClientScrollIncrement(const WebFloatSize& increment) {
return gfx::Vector2dF(-increment.width, -increment.height);
}
@@ -225,6 +230,30 @@ cc::InputHandler::ScrollInputType GestureScrollInputType(
: cc::InputHandler::TOUCHSCREEN;
}
+bool IsGestureScollOrPinch(WebInputEvent::Type type) {
+ switch (type) {
+ case blink::WebGestureEvent::GestureScrollBegin:
+ case blink::WebGestureEvent::GestureScrollUpdate:
+ case blink::WebGestureEvent::GestureScrollEnd:
+ case blink::WebGestureEvent::GesturePinchBegin:
+ case blink::WebGestureEvent::GesturePinchUpdate:
+ case blink::WebGestureEvent::GesturePinchEnd:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsContinuousEvent(WebInputEvent::Type type) {
+ switch (type) {
+ case blink::WebGestureEvent::GestureScrollUpdate:
+ case blink::WebGestureEvent::GesturePinchUpdate:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace
namespace ui {
@@ -248,7 +277,10 @@ InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler,
smooth_scroll_enabled_(false),
uma_latency_reporting_enabled_(base::TimeTicks::IsHighResolution()),
touch_start_result_(kEventDispositionUndefined),
- current_overscroll_params_(nullptr) {
+ current_overscroll_params_(nullptr),
+ has_ongoing_compositor_scroll_pinch(false),
+ compositor_event_queue_enabled_(
+ base::FeatureList::IsEnabled(features::kVsyncAlignedInputEvents)) {
DCHECK(client);
input_handler_->BindToClient(this);
cc::ScrollElasticityHelper* scroll_elasticity_helper =
@@ -257,6 +289,9 @@ InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler,
scroll_elasticity_controller_.reset(
new InputScrollElasticityController(scroll_elasticity_helper));
}
+ if (compositor_event_queue_enabled_) {
+ event_queue_ = base::MakeUnique<CompositorThreadEventQueue>();
+ }
}
InputHandlerProxy::~InputHandlerProxy() {}
@@ -281,15 +316,97 @@ void InputHandlerProxy::HandleInputEventWithLatencyInfo(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"step", "HandleInputEventImpl");
- ui::LatencyInfo monitored_latency_info = latency_info;
+ std::unique_ptr<EventWithCallback> event_with_callback =
+ base::MakeUnique<EventWithCallback>(std::move(event), latency_info,
+ callback);
+
+ if (!compositor_event_queue_enabled_ ||
+ !IsGestureScollOrPinch(event_with_callback->event().type)) {
+ DispatchSingleInputEvent(std::move(event_with_callback));
+ return;
+ }
+
+ if (has_ongoing_compositor_scroll_pinch) {
+ bool needsAnimateInput = event_queue_->empty();
tdresser 2016/11/01 18:12:44 needs_animate_input
chongz 2016/11/02 21:29:32 Done.
+ event_queue_->Queue(std::move(event_with_callback));
+ if (needsAnimateInput)
+ input_handler_->SetNeedsAnimateInput();
+ return;
+ }
+
+ // We have to dispatch the event to know whether it's on compositor or not.
tdresser 2016/11/01 18:12:44 to know whether the gesture sequence will be handl
chongz 2016/11/02 21:29:33 Done.
+ DispatchSingleInputEvent(std::move(event_with_callback));
+}
+
+void InputHandlerProxy::DispatchSingleInputEvent(
+ std::unique_ptr<EventWithCallback> event_with_callback) {
+ if (compositor_event_queue_enabled_ &&
+ IsGestureScollOrPinch(event_with_callback->event().type)) {
+ // Report the coalesced count only for continuous events; otherwise
+ // the zero value would be dominated by non-continuous events.
tdresser 2016/11/01 18:12:44 I'm not convinced that this would actually be domi
chongz 2016/11/02 21:29:33 Reworded to ``` Report the coalesced count only fo
+ base::TimeTicks now = base::TimeTicks::Now();
+ if (IsContinuousEvent(event_with_callback->event().type)) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.CompositorThreadEventQueue.Continuous.QueueingTime",
+ (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1,
+ kTenSeconds, 50);
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.CompositorThreadEventQueue.Continuous.FreshnessTime",
tdresser 2016/11/01 18:12:44 Can we use a more explicit name than "FreshnessTim
chongz 2016/11/02 21:29:33 Renamed to "HeadQueueingTime" and "TailQueueingTim
+ (now - event_with_callback->lastCoalescedTimestamp())
+ .InMicroseconds(),
+ 1, kTenSeconds, 50);
+
+ UMA_HISTOGRAM_COUNTS_1000(
+ "Event.CompositorThreadEventQueue.CoalescedCount",
+ static_cast<int>(event_with_callback->coalescedCount()));
+ } else {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Event.CompositorThreadEventQueue.NonContinuous.QueueingTime",
+ (now - event_with_callback->creationTimestamp()).InMicroseconds(), 1,
+ kTenSeconds, 50);
+ }
+ }
+
+ ui::LatencyInfo monitored_latency_info = event_with_callback->latencyInfo();
std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor =
input_handler_->CreateLatencyInfoSwapPromiseMonitor(
&monitored_latency_info);
current_overscroll_params_.reset();
- InputHandlerProxy::EventDisposition disposition = HandleInputEvent(*event);
- callback.Run(disposition, std::move(event), monitored_latency_info,
- std::move(current_overscroll_params_));
+ InputHandlerProxy::EventDisposition disposition =
+ HandleInputEvent(event_with_callback->event());
+
+ switch (event_with_callback->event().type) {
+ case blink::WebGestureEvent::GestureScrollBegin:
+ case blink::WebGestureEvent::GesturePinchBegin:
+ has_ongoing_compositor_scroll_pinch = disposition == DID_HANDLE;
+ break;
+
+ case blink::WebGestureEvent::GestureScrollUpdate:
+ case blink::WebGestureEvent::GesturePinchUpdate:
+ has_ongoing_compositor_scroll_pinch = disposition == DID_HANDLE;
+ break;
+
+ case blink::WebGestureEvent::GestureScrollEnd:
+ case blink::WebGestureEvent::GesturePinchEnd:
+ has_ongoing_compositor_scroll_pinch = false;
+ break;
+ default:
+ break;
+ }
+
+ // Will run callback for every original events.
+ event_with_callback->RunCallbacks(disposition, monitored_latency_info,
+ std::move(current_overscroll_params_));
+}
+
+void InputHandlerProxy::DispatchQueuedInputEvent() {
tdresser 2016/11/01 18:12:44 DispatchQueuedInputEvents?
chongz 2016/11/02 21:29:33 Done.
+ if (!compositor_event_queue_enabled_)
+ return;
+
+ while (!event_queue_->empty())
+ DispatchSingleInputEvent(event_queue_->Pop());
}
InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
@@ -1120,6 +1237,10 @@ void InputHandlerProxy::UpdateRootLayerStateForSynchronousInputHandler(
}
}
+void InputHandlerProxy::DeliverInputForBeginFrame() {
+ DispatchQueuedInputEvent();
+}
+
void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings(
SynchronousInputHandler* synchronous_input_handler) {
allow_root_animate_ = !synchronous_input_handler;

Powered by Google App Engine
This is Rietveld 408576698