• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1-- Copyright 2023 The Chromium Authors
2-- Use of this source code is governed by a BSD-style license that can be
3-- found in the LICENSE file.
4
5INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
6INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
7INCLUDE PERFETTO MODULE common.slices;
8
9-- Selects EventLatency slices that correspond with janks in a scroll. This is
10-- based on the V3 version of scroll jank metrics.
11CREATE PERFETTO TABLE chrome_janky_event_latencies_v3(
12  -- The slice id.
13  id INT,
14  -- The start timestamp of the slice.
15  ts INT,
16  -- The duration of the slice.
17  dur INT,
18  -- The track_id for the slice.
19  track_id INT,
20  -- The name of the slice (EventLatency).
21  name STRING,
22  -- The stage of EventLatency that the caused the jank.
23  cause_of_jank STRING,
24  -- The stage of cause_of_jank that caused the jank.
25  sub_cause_of_jank STRING,
26  -- How many vsyncs this frame missed its deadline by.
27  delayed_frame_count INT,
28  -- The start timestamp where frame presentation was delayed.
29  frame_jank_ts INT,
30  -- The duration in ms of the delay in frame presentation.
31  frame_jank_dur INT
32) AS
33SELECT
34  s.id,
35  s.ts,
36  s.dur,
37  s.track_id,
38  s.name,
39  e.cause_of_jank,
40  e.sub_cause_of_jank,
41  CAST((e.delay_since_last_frame/e.vsync_interval) - 1 AS INT) AS delayed_frame_count,
42  CAST(s.ts + s.dur - ((e.delay_since_last_frame - e.vsync_interval) * 1e6) AS INT) AS frame_jank_ts,
43  CAST((e.delay_since_last_frame - e.vsync_interval) * 1e6 AS INT) AS frame_jank_dur
44FROM slice s
45JOIN chrome_janky_frames e
46  ON s.id = e. event_latency_id;
47
48-- Frame presentation interval is the delta between when the frame was supposed
49-- to be presented and when it was actually presented.
50CREATE PERFETTO VIEW chrome_janky_frame_presentation_intervals(
51  -- Unique id.
52  id INT,
53  -- The start timestamp of the slice.
54  ts INT,
55  -- The duration of the slice.
56  dur INT,
57  -- How many vsyncs this frame missed its deadline by.
58  delayed_frame_count INT,
59  -- The stage of EventLatency that the caused the jank.
60  cause_of_jank INT,
61  -- The stage of cause_of_jank that caused the jank.
62  sub_cause_of_jank INT,
63  -- The id of the associated event latency in the slice table.
64  event_latency_id INT
65) AS
66SELECT
67  ROW_NUMBER() OVER(ORDER BY frame_jank_ts) AS id,
68  frame_jank_ts AS ts,
69  frame_jank_dur AS dur,
70  delayed_frame_count,
71  cause_of_jank,
72  sub_cause_of_jank,
73  id AS event_latency_id
74FROM chrome_janky_event_latencies_v3;
75
76-- Scroll jank frame presentation stats for individual scrolls.
77CREATE PERFETTO VIEW chrome_scroll_stats(
78  -- Id of the individual scroll.
79  scroll_id INT,
80  -- The number of frames in the scroll.
81  frame_count INT,
82  -- The number of missed vsyncs in the scroll.
83  missed_vsyncs INT,
84  -- The number presented frames in the scroll.
85  presented_frame_count INT,
86  -- The number of janky frames in the scroll.
87  janky_frame_count INT,
88  -- The % of frames that janked in the scroll.
89  janky_frame_percent FLOAT
90) AS
91WITH vsyncs AS (
92  SELECT
93    COUNT() AS presented_vsync_count,
94    scroll.id AS scroll_id
95  FROM chrome_unique_frame_presentation_ts frame
96  JOIN chrome_scrolls scroll
97    ON frame.presentation_timestamp >= scroll.ts
98    AND frame.presentation_timestamp <= scroll.ts + scroll.dur
99  GROUP BY scroll_id),
100missed_vsyncs AS (
101  SELECT
102    CAST(SUM((delay_since_last_frame / vsync_interval) - 1) AS INT)  AS total_missed_vsyncs,
103    scroll_id
104  FROM chrome_janky_frames
105  GROUP BY scroll_id),
106frame_stats AS (
107  SELECT
108    scroll_id,
109    num_frames AS presented_frame_count,
110    IFNULL(num_janky_frames, 0) AS janky_frame_count,
111    ROUND(IFNULL(scroll_jank_percentage, 0), 2) AS janky_frame_percent
112  FROM chrome_frames_per_scroll
113)
114SELECT
115  vsyncs.scroll_id,
116  presented_vsync_count + IFNULL(total_missed_vsyncs, 0) AS frame_count,
117  total_missed_vsyncs AS missed_vsyncs,
118  presented_frame_count,
119  janky_frame_count,
120  janky_frame_percent
121FROM vsyncs
122LEFT JOIN missed_vsyncs
123  USING (scroll_id)
124LEFT JOIN frame_stats
125  USING (scroll_id);
126
127-- Defines slices for all of janky scrolling intervals in a trace.
128CREATE PERFETTO TABLE chrome_scroll_jank_intervals_v3(
129  -- The unique identifier of the janky interval.
130  id INT,
131  -- The start timestamp of the janky interval.
132  ts INT,
133  -- The duration of the janky interval.
134  dur INT
135) AS
136-- Sub-table to retrieve all janky slice timestamps. Ordering calculations are
137-- based on timestamps rather than durations.
138WITH janky_latencies AS (
139  SELECT
140    s.frame_jank_ts AS start_ts,
141    s.frame_jank_ts + s.frame_jank_dur AS end_ts
142  FROM chrome_janky_event_latencies_v3 s),
143-- Determine the local maximum timestamp for janks thus far; this will allow
144-- us to coalesce all earlier events up to the maximum.
145ordered_jank_end_ts AS (
146  SELECT
147    *,
148    MAX(end_ts) OVER (
149      ORDER BY start_ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
150      AS max_end_ts_so_far
151  FROM janky_latencies),
152-- Determine the local minimum timestamp for janks thus far; this will allow
153-- us to coalesce all later events up to the nearest local maximum.
154range_starts AS (
155  SELECT
156    *,
157    CASE
158      -- This is a two-pass calculation to calculate the first event in the
159      -- group. An event is considered the first event in a group if all events
160      -- which started before it also finished the current one started.
161      WHEN start_ts <= 1 + LAG(max_end_ts_so_far) OVER (ORDER BY start_ts) THEN 0
162      ELSE 1
163    END AS range_start
164  FROM ordered_jank_end_ts),
165-- Assign an id to allow coalescing of individual slices.
166range_groups AS (
167  SELECT
168    *,
169    SUM(range_start) OVER (ORDER BY start_ts) AS range_group
170  FROM range_starts)
171-- Coalesce all slices within an interval.
172SELECT
173  range_group AS id,
174  MIN(start_ts) AS ts,
175  MAX(end_ts) - MIN(start_ts) AS dur
176FROM range_groups
177GROUP BY range_group;
178