aboutsummaryrefslogtreecommitdiff
path: root/src/trace_processor/perfetto_sql/stdlib/chrome/chrome_scrolls.sql
blob: f6e29f9e92c773c20a006a2fc8a97fc64d10aeee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
-- Copyright 2023 The Chromium Authors
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.

-- Defines slices for all of the individual scrolls in a trace based on the
-- LatencyInfo-based scroll definition.
--
-- NOTE: this view of top level scrolls is based on the LatencyInfo definition
-- of a scroll, which differs subtly from the definition based on
-- EventLatencies.
-- TODO(b/278684408): add support for tracking scrolls across multiple Chrome/
-- WebView instances. Currently gesture_scroll_id unique within an instance, but
-- is not unique across multiple instances. Switching to an EventLatency based
-- definition of scrolls should resolve this.
CREATE PERFETTO TABLE chrome_scrolls(
  -- The unique identifier of the scroll.
  id INT,
  -- The start timestamp of the scroll.
  ts INT,
  -- The duration of the scroll.
  dur INT,
  -- The earliest timestamp of the InputLatency::GestureScrollBegin for the
  -- corresponding scroll id.
  gesture_scroll_begin_ts INT,
  -- The earliest timestamp of the InputLatency::GestureScrollEnd for the
  -- corresponding scroll id.
  gesture_scroll_end_ts INT
) AS
WITH all_scrolls AS (
  SELECT
    name,
    ts,
    dur,
    extract_arg(arg_set_id, 'chrome_latency_info.gesture_scroll_id') AS scroll_id
  FROM slice
  WHERE name GLOB 'InputLatency::GestureScroll*'
  AND extract_arg(arg_set_id, 'chrome_latency_info.gesture_scroll_id') IS NOT NULL
),
scroll_starts AS (
  SELECT
    scroll_id,
    MIN(ts) AS gesture_scroll_begin_ts
  FROM all_scrolls
  WHERE name = 'InputLatency::GestureScrollBegin'
  GROUP BY scroll_id
), scroll_ends AS (
  SELECT
    scroll_id,
    MIN(ts) AS gesture_scroll_end_ts
  FROM all_scrolls
  WHERE name = 'InputLatency::GestureScrollEnd'
  GROUP BY scroll_id
)
SELECT
  sa.scroll_id AS id,
  MIN(ts) AS ts,
  CAST(MAX(ts + dur) - MIN(ts) AS INT) AS dur,
  ss.gesture_scroll_begin_ts AS gesture_scroll_begin_ts,
  se.gesture_scroll_end_ts AS gesture_scroll_end_ts
FROM all_scrolls sa
  LEFT JOIN scroll_starts ss ON
    sa.scroll_id = ss.scroll_id
  LEFT JOIN scroll_ends se ON
    sa.scroll_id = se.scroll_id
GROUP BY sa.scroll_id;

-- Defines slices for all of scrolls intervals in a trace based on the scroll
-- definition in chrome_scrolls. Note that scrolls may overlap (particularly in
-- cases of jank/broken traces, etc); so scrolling intervals are not exactly the
-- same as individual scrolls.
CREATE PERFETTO VIEW chrome_scrolling_intervals(
  -- The unique identifier of the scroll interval. This may span multiple scrolls if they overlap.
  id INT,
  -- Comma-separated list of scroll ids that are included in this interval.
  scroll_ids STRING,
  -- The start timestamp of the scroll interval.
  ts INT,
  -- The duration of the scroll interval.
  dur INT
) AS
WITH all_scrolls AS (
  SELECT
    id AS scroll_id,
    s.ts AS start_ts,
    s.ts + s.dur AS end_ts
  FROM chrome_scrolls s),
ordered_end_ts AS (
  SELECT
    *,
    MAX(end_ts) OVER (ORDER BY start_ts) AS max_end_ts_so_far
  FROM all_scrolls),
range_starts AS (
  SELECT
    *,
    CASE
      WHEN start_ts <= 1 + LAG(max_end_ts_so_far) OVER (ORDER BY start_ts) THEN 0
      ELSE 1
    END AS range_start
  FROM ordered_end_ts),
range_groups AS (
  SELECT
    *,
    SUM(range_start) OVER (ORDER BY start_ts) AS range_group
  FROM range_starts)
SELECT
  range_group AS id,
  GROUP_CONCAT(scroll_id) AS scroll_ids,
  MIN(start_ts) AS ts,
  MAX(end_ts) - MIN(start_ts) AS dur
FROM range_groups
GROUP BY range_group;