Commit dbb1c14f authored by Mikhail Khokhlov's avatar Mikhail Khokhlov Committed by Commit Bot

[tools/perf] Add experimental JankyScrollPeriods metric

This CL adds JankyScrollPeriods metric from Chrometto dashboard to
be computed on the waterfall. We want to compare results of this metric
and ScrollJankMetric on lab devices and delete one of them afterwards.

Bug: b/150125501
Change-Id: Ifec9f2f41b9f579a94ada95d35459f00b3f17cf4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2080414Reviewed-by: default avatarDeep Roy <dproy@chromium.org>
Commit-Queue: Mikhail Khokhlov <khokhlov@google.com>
Cr-Commit-Position: refs/heads/master@{#745587}
parent 0291066b
...@@ -26,7 +26,10 @@ class SystemHealthInfiniteScroll(system_health.MobileCommonSystemHealth): ...@@ -26,7 +26,10 @@ class SystemHealthInfiniteScroll(system_health.MobileCommonSystemHealth):
def CreateCoreTimelineBasedMeasurementOptions(self): def CreateCoreTimelineBasedMeasurementOptions(self):
options = super(SystemHealthInfiniteScroll, options = super(SystemHealthInfiniteScroll,
self).CreateCoreTimelineBasedMeasurementOptions() self).CreateCoreTimelineBasedMeasurementOptions()
options.SetTimelineBasedMetrics(['tbmv3:scroll_jank_metric']) options.SetTimelineBasedMetrics([
'tbmv3:scroll_jank_metric',
'tbmv3:janky_scroll_periods',
])
return options return options
def CreateStorySet(self, options): def CreateStorySet(self, options):
......
// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0
syntax = "proto2";
package perfetto.protos;
import "protos/perfetto/metrics/metrics.proto";
// A metric that counts the number of janky scroll gestures and the number
// of periods of continuous jankiness.
message JankyScrollPeriods {
optional int64 num_gestures = 1;
optional int64 num_periods = 2;
}
extend TraceMetrics {
optional JankyScrollPeriods janky_scroll_periods = 453;
}
-- Copyright 2020 The Chromium Authors. All rights reserved.
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.
-- A metric that counts the number of janky scroll periods. A janky scroll period
-- is defined as a time period during which:
-- (i) Chrome was handling GuestureScrollUpdate input events, and
-- (ii) sequential GuestureScrollUpdate events had a duration that differed
-- by more than half a frame.
-- The metric assumes a frame rate of 60fps.
--
-- Note that there's a similar metric in scroll_jank_metric.sql that uses
-- a slightly different approach to estimate jankiness. Keeping two metrics
-- around is a temporary measure for experimental purposes. In the end we want
-- to leave only one of them.
-- TODO(khokhlov): Remove one of these metrics.
-- Get the GestureScrollUpdate events by name ordered by timestamp, compute
-- the number of frames (relative to 60 fps) that each event took. 1.6e+7 is
-- 16 ms in nanoseconds.
-- Note that here and further below the result is a table not a view because
-- it speeds up the metric computation.
CREATE TABLE GestureScrollUpdates AS
SELECT
id AS ScrollId,
ts AS ScrollTs,
arg_set_id AS ScrollArgSetId,
dur AS ScrollDur,
dur/1.6e+7 AS ScrollFramesExact,
CAST(dur/1.6e+7 AS int) AS ScrollFramesRounded
FROM
slice
WHERE
name = 'InputLatency::GestureScrollUpdate'
ORDER BY ScrollTs;
-- TODO(khokhlov): This is pretty slow and should be rewritten using window
-- functions when they are enabled in Chrome's sqlite.
CREATE TABLE GestureScrollUpdatesWithRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM GestureScrollUpdates prev
WHERE prev.ScrollTs < next.ScrollTs) + 1 as rowNumber,
*
FROM
GestureScrollUpdates next;
-- This takes the GestureScrollUpdate and joins it to the previous row (NULL
-- if there isn't one) and the next row (NULL if there isn't one). And then
-- computes whether the duration of the event (relative to 60 fps) varied by
-- more than 0.5 (which is 1/2 of 16 ms).
CREATE TABLE ScrollJanksComplete AS
SELECT
currScrollId,
currTs,
currScrollFramesExact,
currScrollFramesExact
NOT BETWEEN
prevScrollFramesExact - 0.5 AND
prevScrollFramesExact + 0.5
AS prevJank,
currScrollFramesExact
NOT BETWEEN
next.ScrollFramesExact - 0.5 AND
next.ScrollFramesExact + 0.5
AS nextJank,
(
currScrollFramesExact
NOT BETWEEN
prevScrollFramesExact - 0.5 AND
prevScrollFramesExact + 0.5
) AND (
currScrollFramesExact
NOT BETWEEN
next.ScrollFramesExact - 0.5 AND
next.ScrollFramesExact + 0.5
) AS bothJank
FROM (
SELECT
curr.rowNumber AS currRowNumber,
curr.Scrollts AS currTs,
curr.ScrollId AS currScrollId,
curr.ScrollFramesExact AS currScrollFramesExact,
prev.ScrollFramesExact AS prevScrollFramesExact
FROM
GestureScrollUpdatesWithRowNumbers curr LEFT JOIN
GestureScrollUpdatesWithRowNumbers prev ON prev.rowNumber + 1 = curr.rowNumber
) currprev JOIN
GestureScrollUpdatesWithRowNumbers next ON currprev.currRowNumber + 1 = next.rowNumber
ORDER BY currprev.currTs ASC;
-- TODO(khokhlov): This is pretty slow and should be rewritten using window
-- functions when they are enabled in Chrome's sqlite.
CREATE TABLE ScrollJanksCompleteWithRowNumbers AS
SELECT
(SELECT COUNT(*)
FROM ScrollJanksComplete prev
WHERE prev.currTs < next.currTs) + 1 as rowNumber,
*
FROM
ScrollJanksComplete next;
-- This just lists outs the rowNumber (which is ordered by timestamp) and
-- whether it was a janky slice (as defined by comparing to both the next and
-- previous slice).
CREATE VIEW ScrollJanks AS
SELECT
rowNumber,
bothJank OR
(nextJank AND prevJank IS NULL) OR
(prevJank AND nextJank IS NULL)
AS Jank
FROM ScrollJanksCompleteWithRowNumbers;
-- This sums the number of periods with sequential janky slices. When Chrome
-- experiences a jank it often stumbles for a while, this attempts to
-- encapsulate this by only counting thestumbles and not all the janky
-- individual slices.
CREATE VIEW JankyScrollPeriodsView AS
SELECT
SUM(CASE WHEN curr.Jank = 1 THEN 1 ELSE 0 END) as gestures,
SUM(CASE WHEN curr.Jank = 1 AND (prev.Jank IS NULL OR prev.Jank = 0)
THEN 1 ELSE 0 END) AS periods
FROM (
SELECT * from ScrollJanks
) curr LEFT JOIN (
SELECT * from ScrollJanks
) prev ON curr.rowNumber = prev.rowNumber + 1;
-- Output the proto with metric values.
CREATE VIEW janky_scroll_periods_output AS
SELECT JankyScrollPeriods(
'num_gestures', COALESCE(gestures, 0),
'num_periods', COALESCE(periods, 0))
FROM JankyScrollPeriodsView;
{
"name": "Janky Scroll Periods Metric",
"description": "Counts the number of janky scroll gestures and periods of continuous jankiness.",
"histograms": [
{
"name": "num_gestures",
"description": "Number of all janky gestures.",
"requiredCategories": ["latencyInfo"],
"unit": "count_smallerIsBetter"
},
{
"name": "num_periods",
"description": "Number of all janky periods.",
"requiredCategories": ["latencyInfo"],
"unit": "count_smallerIsBetter"
}
]
}
...@@ -2,6 +2,15 @@ ...@@ -2,6 +2,15 @@
-- Use of this source code is governed by a BSD-style license that can be -- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file. -- found in the LICENSE file.
-- The metric finds periods in a trace when scroll update events started
-- but didn't finish. The idea is that it's perceived by the user as a scroll
-- delay, i.e. jank.
-- Note that there's a similar metric in janky_scroll_periods.sql that uses
-- a slightly different approach to estimate jankiness. Keeping two metrics
-- around is a temporary measure for experimental purposes. In the end we want
-- to leave only one of them.
-- TODO(khokhlov): Remove one of these metrics.
-- This selects GestureScrollUpdate events. Note the result is a table not a -- This selects GestureScrollUpdate events. Note the result is a table not a
-- view to speed up the metric computation. -- view to speed up the metric computation.
CREATE TABLE input_latency_events AS CREATE TABLE input_latency_events AS
......
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