File: event_latency.sql

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (271 lines) | stat: -rw-r--r-- 10,181 bytes parent folder | download | duplicates (10)
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
-- Copyright 2024 The Chromium Authors
-- Use of this source code is governed by a BSD-style license that can be
-- found in the LICENSE file.

-- Finds the start timestamp for a given slice's descendant with a given name.
-- If there are multiple descendants with a given name, the function will return
-- the first one, so it's most useful when working with a timeline broken down
-- into phases, where each subphase can happen only once.
CREATE PERFETTO FUNCTION _descendant_slice_begin(
    -- Id of the parent slice.
    parent_id LONG,
    -- Name of the child with the desired start TS.
    child_name STRING
)
-- Start timestamp of the child or NULL if it doesn't exist.
RETURNS LONG AS
SELECT
  s.ts
FROM descendant_slice($parent_id) AS s
WHERE
  s.name GLOB $child_name
LIMIT 1;

-- Finds the end timestamp for a given slice's descendant with a given name.
-- If there are multiple descendants with a given name, the function will return
-- the first one, so it's most useful when working with a timeline broken down
-- into phases, where each subphase can happen only once.
CREATE PERFETTO FUNCTION _descendant_slice_end(
    -- Id of the parent slice.
    parent_id LONG,
    -- Name of the child with the desired end TS.
    child_name STRING
)
-- End timestamp of the child or NULL if it doesn't exist.
RETURNS LONG AS
SELECT
  CASE WHEN NOT s.dur IS -1 THEN s.ts + s.dur ELSE NULL END
FROM descendant_slice($parent_id) AS s
WHERE
  s.name GLOB $child_name
LIMIT 1;

-- Checks if slice has a descendant with provided name.
CREATE PERFETTO FUNCTION _has_descendant_slice_with_name(
    -- Id of the slice to check descendants of.
    id LONG,
    -- Name of potential descendant slice.
    descendant_name STRING
)
-- Whether `descendant_name` is a name of an descendant slice.
RETURNS BOOL AS
SELECT
  EXISTS(
    SELECT
      1
    FROM descendant_slice($id)
    WHERE
      name = $descendant_name
    LIMIT 1
  );

-- Returns the presentation timestamp for a given EventLatency slice.
-- This is either the end of
-- SwapEndToPresentationCompositorFrame (if it exists),
-- the end of LatchToPresentation (if it exists),
-- the end of SwapStartToPresentation (if it exists),
-- or the end of LatchToSwapEnd (workaround in older Chrome versions).
CREATE PERFETTO FUNCTION _get_presentation_timestamp(
    -- The slice id which we need the presentation timestamp for.
    id LONG
)
RETURNS LONG AS
SELECT
  coalesce(
    _descendant_slice_end(id, 'SwapEndToPresentationCompositorFrame'),
    _descendant_slice_end(id, '*ToPresentation'),
    _descendant_slice_end(id, 'LatchToSwapEnd')
  )
FROM slice
WHERE
  $id = id;

-- All EventLatency slices.
CREATE PERFETTO TABLE chrome_event_latencies (
  -- Slice Id for the EventLatency scroll event.
  id LONG,
  -- Slice name.
  name STRING,
  -- The start timestamp of the scroll.
  ts TIMESTAMP,
  -- The duration of the scroll.
  dur DURATION,
  -- The id of the scroll update event (aka LatencyInfo.ID).
  scroll_update_id LONG,
  -- The id of the first frame (pre-surface aggregation) which included the
  -- scroll update and was presented. NULL if:
  -- (1) the event is not a scroll update (`event_type` is NOT
  --     GESTURE_SCROLL_UPDATE, FIRST_GESTURE_SCROLL_UPDATE, or
  --     INERTIAL_GESTURE_SCROLL_UPDATE),
  -- (2) the scroll update wasn't presented (e.g. it was an overscroll) or
  -- (3) the trace comes from an old Chrome version (https://crrev.com/c/6185817
  --     was first included in version 134.0.6977.0 and was cherry-picked in
  --     version 133.0.6943.33).
  surface_frame_trace_id LONG,
  -- The id of the first frame (post-surface aggregation) which included the
  -- scroll update and was presented. NULL if:
  -- (1) the event is not a scroll update (`event_type` is NOT
  --     GESTURE_SCROLL_UPDATE, FIRST_GESTURE_SCROLL_UPDATE, or
  --     INERTIAL_GESTURE_SCROLL_UPDATE),
  -- (2) the scroll update wasn't presented (e.g. it was an overscroll) or
  -- (3) the trace comes from an old Chrome version (https://crrev.com/c/6185817
  --     was first included in version 134.0.6977.0 and was cherry-picked in
  --     version 133.0.6943.33).
  display_trace_id LONG,
  -- Whether this input event was presented.
  is_presented BOOL,
  -- EventLatency event type.
  event_type STRING,
  -- Perfetto track this slice is found on.
  track_id LONG,
  -- Vsync interval (in milliseconds).
  vsync_interval_ms DOUBLE,
  -- Whether the corresponding frame is janky based on the
  -- Event.ScrollJank.DelayedFramesPercentage.FixedWindow metric.
  is_janky_scrolled_frame BOOL,
  -- Whether the corresponding frame is janky based on the
  -- Event.ScrollJank.DelayedFramesPercentage.FixedWindow3 metric.
  is_janky_scrolled_frame_v3 BOOL,
  -- Timestamp of the BufferAvailableToBufferReady substage.
  buffer_available_timestamp LONG,
  -- Timestamp of the BufferReadyToLatch substage.
  buffer_ready_timestamp LONG,
  -- Timestamp of the LatchToSwapEnd substage (or LatchToPresentation as a
  -- fallback).
  latch_timestamp LONG,
  -- Timestamp of the SwapEndToPresentationCompositorFrame substage.
  swap_end_timestamp LONG,
  -- Frame presentation timestamp aka the timestamp of the
  -- SwapEndToPresentationCompositorFrame substage.
  -- TODO(b/341047059): temporarily use LatchToSwapEnd as a workaround if
  -- SwapEndToPresentationCompositorFrame is missing due to b/247542163.
  presentation_timestamp LONG
) AS
SELECT
  slice.id,
  slice.name,
  slice.ts,
  slice.dur,
  extract_arg(arg_set_id, 'event_latency.event_latency_id') AS scroll_update_id,
  extract_arg(arg_set_id, 'event_latency.surface_frame_trace_id') AS surface_frame_trace_id,
  extract_arg(arg_set_id, 'event_latency.display_trace_id') AS display_trace_id,
  _has_descendant_slice_with_name(slice.id, 'SubmitCompositorFrameToPresentationCompositorFrame') AS is_presented,
  extract_arg(arg_set_id, 'event_latency.event_type') AS event_type,
  slice.track_id,
  extract_arg(arg_set_id, 'event_latency.vsync_interval_ms') AS vsync_interval_ms,
  coalesce(extract_arg(arg_set_id, 'event_latency.is_janky_scrolled_frame'), 0) AS is_janky_scrolled_frame,
  coalesce(extract_arg(arg_set_id, 'event_latency.is_janky_scrolled_frame_v3'), 0) AS is_janky_scrolled_frame_v3,
  _descendant_slice_begin(slice.id, 'BufferAvailableToBufferReady') AS buffer_available_timestamp,
  _descendant_slice_begin(slice.id, 'BufferReadyToLatch') AS buffer_ready_timestamp,
  coalesce(
    _descendant_slice_begin(slice.id, 'LatchToSwapEnd'),
    _descendant_slice_begin(slice.id, 'LatchToPresentation')
  ) AS latch_timestamp,
  _descendant_slice_begin(slice.id, 'SwapEndToPresentationCompositorFrame') AS swap_end_timestamp,
  _get_presentation_timestamp(slice.id) AS presentation_timestamp
FROM slice
WHERE
  name = 'EventLatency';

-- All scroll-related events (frames) including gesture scroll updates, begins
-- and ends with respective scroll ids and start/end timestamps, regardless of
-- being presented. This includes pinches that were presented. See b/315761896
-- for context on pinches.
CREATE PERFETTO TABLE chrome_gesture_scroll_updates (
  -- Slice Id for the EventLatency scroll event.
  id LONG,
  -- Slice name.
  name STRING,
  -- The start timestamp of the scroll.
  ts TIMESTAMP,
  -- The duration of the scroll.
  dur DURATION,
  -- The id of the scroll update event.
  scroll_update_id LONG,
  -- Whether this input event was presented.
  is_presented BOOL,
  -- EventLatency event type.
  event_type STRING,
  -- Perfetto track this slice is found on.
  track_id LONG,
  -- Vsync interval (in milliseconds).
  vsync_interval_ms DOUBLE,
  -- Whether the corresponding frame is janky based on the
  -- Event.ScrollJank.DelayedFramesPercentage.FixedWindow metric.
  is_janky BOOL,
  -- Whether the corresponding frame is janky based on the
  -- Event.ScrollJank.DelayedFramesPercentage.FixedWindow3 metric.
  is_janky_v3 BOOL,
  -- Timestamp of the BufferAvailableToBufferReady substage.
  buffer_available_timestamp LONG,
  -- Timestamp of the BufferReadyToLatch substage.
  buffer_ready_timestamp LONG,
  -- Timestamp of the LatchToSwapEnd substage (or LatchToPresentation as a
  -- fallback).
  latch_timestamp LONG,
  -- Timestamp of the SwapEndToPresentationCompositorFrame substage.
  swap_end_timestamp LONG,
  -- Frame presentation timestamp aka the timestamp of the
  -- SwapEndToPresentationCompositorFrame substage.
  -- TODO(b/341047059): temporarily use LatchToSwapEnd as a workaround if
  -- SwapEndToPresentationCompositorFrame is missing due to b/247542163.
  presentation_timestamp LONG,
  -- The id of the scroll.
  scroll_id LONG
) AS
-- To compute scroll id, we first mark all of the FIRST_GESTURE_SCROLL_UPDATE events
-- (or the first scroll update in the trace) as the points where scroll id should be
-- incremented and then use the cumulative sum as the scroll id.
WITH
  updates_without_scroll_ids AS (
    SELECT
      id,
      name,
      ts,
      dur,
      scroll_update_id,
      is_presented,
      event_type,
      track_id,
      vsync_interval_ms,
      is_janky_scrolled_frame AS is_janky,
      is_janky_scrolled_frame_v3 AS is_janky_v3,
      buffer_available_timestamp,
      buffer_ready_timestamp,
      latch_timestamp,
      swap_end_timestamp,
      presentation_timestamp,
      (
        event_type = 'FIRST_GESTURE_SCROLL_UPDATE' OR row_number() OVER (ORDER BY ts) = 1
      ) AS is_first_update_in_scroll
    FROM chrome_event_latencies
    WHERE
      event_type IN ('GESTURE_SCROLL_UPDATE', 'FIRST_GESTURE_SCROLL_UPDATE', 'INERTIAL_GESTURE_SCROLL_UPDATE')
      OR (
        -- Pinches are only relevant if the frame was presented.
        event_type GLOB '*GESTURE_PINCH_UPDATE'
        AND is_presented
      )
  )
SELECT
  id,
  name,
  ts,
  dur,
  scroll_update_id,
  is_presented,
  event_type,
  track_id,
  vsync_interval_ms,
  is_janky,
  is_janky_v3,
  buffer_available_timestamp,
  buffer_ready_timestamp,
  latch_timestamp,
  swap_end_timestamp,
  presentation_timestamp,
  coalesce(
    sum(cast_int!(is_first_update_in_scroll)) OVER (ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
    0
  ) AS scroll_id
FROM updates_without_scroll_ids;