Commit dd067bd5 authored by Sahel Sharify's avatar Sahel Sharify Committed by Commit Bot

Added UMA performance metrics for fling.

This cl adds new metrics for GSU events that are generated from a
touchscreen fling progress. We want to keep the latency of these GSUs
separate from GSU events generated from touch move events since the
latency for handling the GSU events from fling doesn't include the time
needed for handling a touch event.

Bug: 249063
Test: RenderWidgetHostLatencyTrackerTest.TestInertialToScrollHistograms
Change-Id: Iba4664d19e5218cae4886ee543b709d4c2152fa4
Reviewed-on: https://chromium-review.googlesource.com/1062806Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Reviewed-by: default avatarNavid Zolghadr <nzolghadr@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Commit-Queue: Sahel Sharifymoghaddam <sahel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561525}
parent ff06bc7f
......@@ -292,7 +292,7 @@ void FlingController::GenerateAndSendGestureScrollEvents(
const gfx::Vector2dF& delta /* = gfx::Vector2dF() */) {
GestureEventWithLatencyInfo synthetic_gesture(
type, current_fling_parameters_.modifiers, base::TimeTicks::Now(),
ui::LatencyInfo(ui::SourceEventType::TOUCH));
ui::LatencyInfo(ui::SourceEventType::INERTIAL));
synthetic_gesture.event.SetPositionInWidget(current_fling_parameters_.point);
synthetic_gesture.event.SetPositionInScreen(
current_fling_parameters_.global_point);
......@@ -395,7 +395,7 @@ void FlingController::CancelCurrentFling() {
ui::SourceEventType::UNKNOWN;
if (scroll_begin_event.SourceDevice() ==
blink::kWebGestureDeviceTouchscreen) {
latency_source_event_type = ui::SourceEventType::TOUCH;
latency_source_event_type = ui::SourceEventType::INERTIAL;
} else if (scroll_begin_event.SourceDevice() ==
blink::kWebGestureDeviceTouchpad) {
latency_source_event_type = ui::SourceEventType::WHEEL;
......
......@@ -422,6 +422,62 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
}
}
TEST_F(RenderWidgetHostLatencyTrackerTest, TestInertialToScrollHistograms) {
const GURL url(kUrl);
contents()->NavigateAndCommit(url);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate(
5.f, -5.f, 0, blink::kWebGestureDeviceTouchscreen);
base::TimeTicks now = base::TimeTicks::Now();
scroll.SetTimeStamp(now);
ui::LatencyInfo scroll_latency(ui::SourceEventType::INERTIAL);
scroll_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
tracker()->latency_component_id(), now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &scroll_latency, now);
AddRenderingScheduledComponent(&scroll_latency, rendering_on_main, now);
tracker()->OnInputEvent(scroll, &scroll_latency);
EXPECT_TRUE(scroll_latency.FindLatency(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
tracker()->latency_component_id(), nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
tracker()->OnInputEventAck(scroll, &scroll_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(scroll_latency);
}
// UMA histograms.
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollInertial.Touch."
"TimeToScrollUpdateSwapBegin2",
1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.TimeToHandled2_Main",
rendering_on_main ? 1 : 0));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.TimeToHandled2_Impl",
rendering_on_main ? 0 : 1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.HandledToRendererSwap2_Main",
rendering_on_main ? 1 : 0));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.HandledToRendererSwap2_Impl",
rendering_on_main ? 0 : 1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.RendererSwapToBrowserNotified2",
1));
EXPECT_TRUE(HistogramSizeEq(
"Event.Latency.ScrollInertial.Touch.BrowserNotifiedToBeforeGpuSwap2",
1));
EXPECT_TRUE(
HistogramSizeEq("Event.Latency.ScrollInertial.Touch.GpuSwap2", 1));
}
}
TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
const GURL url(kUrl);
contents()->NavigateAndCommit(url);
......
......@@ -23188,6 +23188,81 @@ uploading your change for review.
</summary>
</histogram>
<histogram
name="Event.Latency.ScrollInertial.Touch.BrowserNotifiedToBeforeGpuSwap2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between the browser receives the notification of a ScrollUpdate gesture
generated from a touchscreen fling induced renderer swap and GPU starts to
swap.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram name="Event.Latency.ScrollInertial.Touch.GpuSwap2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between gpu starts to swap a ScrollUpdate gesture event generated from
a touchscreen fling induced frame and the swap finishes.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram name="Event.Latency.ScrollInertial.Touch.HandledToRendererSwap2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between a ScrollUpdate gesture event generated from a touchscreen
fling, is handled on main/impl thread (specified by suffix) and before
renderer starts to swap.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram
name="Event.Latency.ScrollInertial.Touch.RendererSwapToBrowserNotified2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between the renderer starts to swap a frame induced by a ScrollUpdate
gesture event generated from a touchscreen fling, and browser receives the
swap notification.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram name="Event.Latency.ScrollInertial.Touch.TimeToHandled2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between initial creation of a ScrollUpdate gesture event generated from
a touchscreen fling is handled on main/impl thread (specified by suffix). If
no swap was induced by the ScrollUpdate gesture event, no recording is made.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram
name="Event.Latency.ScrollInertial.Touch.TimeToScrollUpdateSwapBegin2"
units="microseconds">
<owner>sahel@chromium.org</owner>
<summary>
Time between initial creation of a ScrollUpdate gesture event generated from
a touchscreen fling and the start of the frame swap on the GPU service
caused by the generated ScrollUpdate gesture event. If no swap was induced
by the event, no recording is made.
Team: input-dev@chromium.org.
</summary>
</histogram>
<histogram name="Event.Latency.ScrollUpdate.BrowserNotifiedToBeforeGpuSwap"
units="microseconds">
<obsolete>
......@@ -119161,6 +119236,9 @@ uploading your change for review.
<affected-histogram
name="Event.Latency.ScrollBegin.Wheel.HandledToRendererSwap2"/>
<affected-histogram name="Event.Latency.ScrollBegin.Wheel.TimeToHandled2"/>
<affected-histogram
name="Event.Latency.ScrollInertial.Touch.HandledToRendererSwap2"/>
<affected-histogram name="Event.Latency.ScrollInertial.Touch.TimeToHandled2"/>
<affected-histogram name="Event.Latency.ScrollUpdate.HandledToRendererSwap"/>
<affected-histogram
name="Event.Latency.ScrollUpdate.Touch.HandledToRendererSwap2"/>
......@@ -255,7 +255,26 @@ LatencyInfo WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(
source_event_type = SourceEventType::WHEEL;
} else if (event.SourceDevice() ==
blink::WebGestureDevice::kWebGestureDeviceTouchscreen) {
source_event_type = SourceEventType::TOUCH;
blink::WebGestureEvent::InertialPhaseState inertial_phase_state =
blink::WebGestureEvent::kUnknownMomentumPhase;
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
inertial_phase_state = event.data.scroll_begin.inertial_phase;
break;
case blink::WebInputEvent::kGestureScrollUpdate:
inertial_phase_state = event.data.scroll_update.inertial_phase;
break;
case blink::WebInputEvent::kGestureScrollEnd:
inertial_phase_state = event.data.scroll_end.inertial_phase;
break;
default:
break;
}
bool is_in_inertial_phase =
inertial_phase_state == blink::WebGestureEvent::kMomentumPhase;
source_event_type = is_in_inertial_phase ? SourceEventType::INERTIAL
: SourceEventType::TOUCH;
}
LatencyInfo latency_info(source_event_type);
return latency_info;
......
......@@ -116,6 +116,7 @@ enum SourceEventType {
WHEEL,
MOUSE,
TOUCH,
INERTIAL,
KEY_PRESS,
FRAME,
OTHER,
......
......@@ -30,6 +30,7 @@ std::string LatencySourceEventTypeToInputModalityString(
case ui::SourceEventType::MOUSE:
return "Mouse";
case ui::SourceEventType::TOUCH:
case ui::SourceEventType::INERTIAL:
return "Touch";
case ui::SourceEventType::KEY_PRESS:
return "KeyPress";
......@@ -38,6 +39,10 @@ std::string LatencySourceEventTypeToInputModalityString(
}
}
bool IsInertialScroll(const LatencyInfo& latency) {
return latency.source_event_type() == ui::SourceEventType::INERTIAL;
}
// This UMA metric tracks the time from when the original wheel event is created
// to when the scroll gesture results in final frame swap. All scroll events are
// included in this metric.
......@@ -95,6 +100,7 @@ void LatencyTracker::OnGpuSwapBuffersCompleted(const LatencyInfo& latency) {
if (source_event_type == ui::SourceEventType::WHEEL ||
source_event_type == ui::SourceEventType::MOUSE ||
source_event_type == ui::SourceEventType::TOUCH ||
source_event_type == ui::SourceEventType::INERTIAL ||
source_event_type == ui::SourceEventType::KEY_PRESS) {
ComputeEndToEndLatencyHistograms(gpu_swap_begin_component,
gpu_swap_end_component, latency);
......@@ -173,9 +179,12 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
if (latency.FindLatency(
ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
&original_component)) {
scroll_name = "ScrollBegin";
DCHECK(input_modality == "Wheel" || input_modality == "Touch");
// For inertial scrolling we don't separate the first event from the rest of
// them.
scroll_name = IsInertialScroll(latency) ? "ScrollInertial" : "ScrollBegin";
// This UMA metric tracks the performance of overall scrolling as a high
// level metric.
UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS(
......@@ -186,7 +195,7 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
// first scroll event in a sequence and the original timestamp of that
// scroll event's underlying touch/wheel event.
UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS(
"Event.Latency.ScrollBegin." + input_modality +
"Event.Latency." + scroll_name + "." + input_modality +
".TimeToScrollUpdateSwapBegin2",
original_component, gpu_swap_begin_component);
......@@ -198,9 +207,12 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
} else if (latency.FindLatency(
ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
&original_component)) {
scroll_name = "ScrollUpdate";
DCHECK(input_modality == "Wheel" || input_modality == "Touch");
// For inertial scrolling we don't separate the first event from the rest of
// them.
scroll_name = IsInertialScroll(latency) ? "ScrollInertial" : "ScrollUpdate";
// This UMA metric tracks the performance of overall scrolling as a high
// level metric.
UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS(
......@@ -211,7 +223,7 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
// is created to when the scroll gesture results in final frame swap.
// First scroll events are excluded from this metric.
UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS(
"Event.Latency.ScrollUpdate." + input_modality +
"Event.Latency." + scroll_name + "." + input_modality +
".TimeToScrollUpdateSwapBegin2",
original_component, gpu_swap_begin_component);
......@@ -238,7 +250,8 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
}
// Record scroll latency metrics.
DCHECK(scroll_name == "ScrollBegin" || scroll_name == "ScrollUpdate");
DCHECK(scroll_name == "ScrollBegin" || scroll_name == "ScrollUpdate" ||
(IsInertialScroll(latency) && scroll_name == "ScrollInertial"));
LatencyInfo::LatencyComponent rendering_scheduled_component;
bool rendering_scheduled_on_main = latency.FindLatency(
ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0,
......@@ -249,7 +262,10 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
&rendering_scheduled_component);
DCHECK_AND_RETURN_ON_FAIL(found_component);
}
if (input_modality == "Touch" || input_modality == "Wheel") {
// Inertial scrolls are excluded from Ukm metrics.
if ((input_modality == "Touch" && !IsInertialScroll(latency)) ||
input_modality == "Wheel") {
InputMetricEvent input_metric_event;
if (scroll_name == "ScrollBegin") {
input_metric_event = input_modality == "Touch"
......
......@@ -84,6 +84,7 @@ enum SourceEventType {
WHEEL,
MOUSE,
TOUCH,
INERTIAL,
KEY_PRESS,
FRAME,
OTHER,
......
......@@ -191,6 +191,8 @@ ui::mojom::SourceEventType UISourceEventTypeToMojo(ui::SourceEventType type) {
return ui::mojom::SourceEventType::MOUSE;
case ui::TOUCH:
return ui::mojom::SourceEventType::TOUCH;
case ui::INERTIAL:
return ui::mojom::SourceEventType::INERTIAL;
case ui::KEY_PRESS:
return ui::mojom::SourceEventType::KEY_PRESS;
case ui::FRAME:
......@@ -212,6 +214,8 @@ ui::SourceEventType MojoSourceEventTypeToUI(ui::mojom::SourceEventType type) {
return ui::MOUSE;
case ui::mojom::SourceEventType::TOUCH:
return ui::TOUCH;
case ui::mojom::SourceEventType::INERTIAL:
return ui::INERTIAL;
case ui::mojom::SourceEventType::KEY_PRESS:
return ui::KEY_PRESS;
case ui::mojom::SourceEventType::FRAME:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment