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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
-- 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.
INCLUDE PERFETTO MODULE chrome.chrome_scrolls;
INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3;
-- Selects EventLatency slices that correspond with janks in a scroll. This is
-- based on the V3 version of scroll jank metrics.
CREATE PERFETTO TABLE chrome_janky_event_latencies_v3 (
-- The slice id.
id LONG,
-- The start timestamp of the slice.
ts TIMESTAMP,
-- The duration of the slice.
dur DURATION,
-- The track_id for the slice.
track_id LONG,
-- The name of the slice (EventLatency).
name STRING,
-- The stage of EventLatency that the caused the jank.
cause_of_jank STRING,
-- The stage of cause_of_jank that caused the jank.
sub_cause_of_jank STRING,
-- How many vsyncs this frame missed its deadline by.
delayed_frame_count LONG,
-- The start timestamp where frame presentation was delayed.
frame_jank_ts TIMESTAMP,
-- The duration in ms of the delay in frame presentation.
frame_jank_dur LONG
) AS
SELECT
s.id,
s.ts,
s.dur,
s.track_id,
s.name,
e.cause_of_jank,
e.sub_cause_of_jank,
cast_int!((e.delay_since_last_frame/e.vsync_interval) - 1) AS delayed_frame_count,
cast_int!(s.ts + s.dur - ((e.delay_since_last_frame - e.vsync_interval) * 1e6)) AS frame_jank_ts,
cast_int!((e.delay_since_last_frame - e.vsync_interval) * 1e6) AS frame_jank_dur
FROM chrome_gesture_scroll_updates AS s
JOIN chrome_janky_frames AS e
ON s.id = e.event_latency_id;
-- Frame presentation interval is the delta between when the frame was supposed
-- to be presented and when it was actually presented.
CREATE PERFETTO VIEW chrome_janky_frame_presentation_intervals (
-- Unique id.
id LONG,
-- The start timestamp of the slice.
ts TIMESTAMP,
-- The duration of the slice.
dur DURATION,
-- How many vsyncs this frame missed its deadline by.
delayed_frame_count LONG,
-- The stage of EventLatency that the caused the jank.
cause_of_jank STRING,
-- The stage of cause_of_jank that caused the jank.
sub_cause_of_jank STRING,
-- The id of the associated event latency in the slice table.
event_latency_id LONG
) AS
SELECT
row_number() OVER (ORDER BY frame_jank_ts) AS id,
frame_jank_ts AS ts,
frame_jank_dur AS dur,
delayed_frame_count,
cause_of_jank,
sub_cause_of_jank,
id AS event_latency_id
FROM chrome_janky_event_latencies_v3;
-- Scroll jank frame presentation stats for individual scrolls.
CREATE PERFETTO TABLE chrome_scroll_stats (
-- Id of the individual scroll.
scroll_id LONG,
-- The number of frames in the scroll.
frame_count LONG,
-- The number of missed vsyncs in the scroll.
missed_vsyncs LONG,
-- The number presented frames in the scroll.
presented_frame_count LONG,
-- The number of janky frames in the scroll.
janky_frame_count LONG,
-- The % of frames that janked in the scroll.
janky_frame_percent DOUBLE
) AS
WITH
vsyncs AS (
SELECT
count() AS presented_vsync_count,
scroll.id AS scroll_id
FROM chrome_unique_frame_presentation_ts AS frame
JOIN chrome_scrolls AS scroll
ON frame.presentation_timestamp >= scroll.ts
AND frame.presentation_timestamp <= scroll.ts + scroll.dur
GROUP BY
scroll_id
),
missed_vsyncs AS (
SELECT
cast_int!(SUM((delay_since_last_frame / vsync_interval) - 1)) AS total_missed_vsyncs,
scroll_id
FROM chrome_janky_frames
GROUP BY
scroll_id
),
frame_stats AS (
SELECT
scroll_id,
num_frames AS presented_frame_count,
coalesce(num_janky_frames, 0) AS janky_frame_count,
round(coalesce(scroll_jank_percentage, 0), 2) AS janky_frame_percent
FROM chrome_frames_per_scroll
)
SELECT
vsyncs.scroll_id,
presented_vsync_count + coalesce(total_missed_vsyncs, 0) AS frame_count,
total_missed_vsyncs AS missed_vsyncs,
presented_frame_count,
janky_frame_count,
janky_frame_percent
FROM vsyncs
LEFT JOIN missed_vsyncs
USING (scroll_id)
LEFT JOIN frame_stats
USING (scroll_id);
-- Defines slices for all of janky scrolling intervals in a trace.
CREATE PERFETTO TABLE chrome_scroll_jank_intervals_v3 (
-- The unique identifier of the janky interval.
id LONG,
-- The start timestamp of the janky interval.
ts TIMESTAMP,
-- The duration of the janky interval.
dur DURATION
) AS
-- Sub-table to retrieve all janky slice timestamps. Ordering calculations are
-- based on timestamps rather than durations.
WITH
janky_latencies AS (
SELECT
s.frame_jank_ts AS start_ts,
s.frame_jank_ts + s.frame_jank_dur AS end_ts
FROM chrome_janky_event_latencies_v3 AS s
),
-- Determine the local maximum timestamp for janks thus far; this will allow
-- us to coalesce all earlier events up to the maximum.
ordered_jank_end_ts AS (
SELECT
*,
max(end_ts) OVER (ORDER BY start_ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_end_ts_so_far
FROM janky_latencies
),
-- Determine the local minimum timestamp for janks thus far; this will allow
-- us to coalesce all later events up to the nearest local maximum.
range_starts AS (
SELECT
*,
CASE
-- This is a two-pass calculation to calculate the first event in the
-- group. An event is considered the first event in a group if all events
-- which started before it also finished the current one started.
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_jank_end_ts
),
-- Assign an id to allow coalescing of individual slices.
range_groups AS (
SELECT
*,
sum(range_start) OVER (ORDER BY start_ts) AS range_group
FROM range_starts
)
-- Coalesce all slices within an interval.
SELECT
range_group AS id,
min(start_ts) AS ts,
max(end_ts) - min(start_ts) AS dur
FROM range_groups
GROUP BY
range_group;
|