• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1-- Copyright 2024 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
5-- Finds the start timestamp for a given slice's descendant with a given name.
6-- If there are multiple descendants with a given name, the function will return
7-- the first one, so it's most useful when working with a timeline broken down
8-- into phases, where each subphase can happen only once.
9CREATE PERFETTO FUNCTION _descendant_slice_begin(
10  -- Id of the parent slice.
11  parent_id LONG,
12  -- Name of the child with the desired start TS.
13  child_name STRING
14)
15-- Start timestamp of the child or NULL if it doesn't exist.
16RETURNS LONG AS
17SELECT s.ts
18FROM descendant_slice($parent_id) s
19WHERE s.name GLOB $child_name
20LIMIT 1;
21
22-- Finds the end timestamp for a given slice's descendant with a given name.
23-- If there are multiple descendants with a given name, the function will return
24-- the first one, so it's most useful when working with a timeline broken down
25-- into phases, where each subphase can happen only once.
26CREATE PERFETTO FUNCTION _descendant_slice_end(
27  -- Id of the parent slice.
28  parent_id LONG,
29  -- Name of the child with the desired end TS.
30  child_name STRING
31)
32-- End timestamp of the child or NULL if it doesn't exist.
33RETURNS LONG AS
34SELECT
35  CASE WHEN s.dur
36    IS NOT -1 THEN s.ts + s.dur
37    ELSE NULL
38  END
39FROM descendant_slice($parent_id) s
40WHERE s.name GLOB $child_name
41LIMIT 1;
42
43-- Checks if slice has a descendant with provided name.
44CREATE PERFETTO FUNCTION _has_descendant_slice_with_name(
45  -- Id of the slice to check descendants of.
46  id LONG,
47  -- Name of potential descendant slice.
48  descendant_name STRING
49)
50-- Whether `descendant_name` is a name of an descendant slice.
51RETURNS BOOL AS
52SELECT EXISTS(
53  SELECT 1
54  FROM descendant_slice($id)
55  WHERE name = $descendant_name
56  LIMIT 1
57);
58
59-- Returns the presentation timestamp for a given EventLatency slice.
60-- This is either the end of
61-- SwapEndToPresentationCompositorFrame (if it exists),
62-- the end of LatchToPresentation (if it exists),
63-- the end of SwapStartToPresentation (if it exists),
64-- or the end of LatchToSwapEnd (workaround in older Chrome versions).
65CREATE PERFETTO FUNCTION _get_presentation_timestamp(
66  -- The slice id which we need the presentation timestamp for.
67  id LONG
68)
69RETURNS LONG AS
70SELECT
71  COALESCE(_descendant_slice_end(id, 'SwapEndToPresentationCompositorFrame'),
72    _descendant_slice_end(id, '*ToPresentation'),
73    _descendant_slice_end(id, 'LatchToSwapEnd'))
74FROM slice WHERE $id = id;
75
76-- All EventLatency slices.
77CREATE PERFETTO TABLE chrome_event_latencies(
78  -- Slice Id for the EventLatency scroll event.
79  id LONG,
80  -- Slice name.
81  name STRING,
82  -- The start timestamp of the scroll.
83  ts TIMESTAMP,
84  -- The duration of the scroll.
85  dur DURATION,
86  -- The id of the scroll update event.
87  scroll_update_id LONG,
88  -- Whether this input event was presented.
89  is_presented BOOL,
90  -- EventLatency event type.
91  event_type STRING,
92  -- Perfetto track this slice is found on.
93  track_id LONG,
94  -- Vsync interval (in milliseconds).
95  vsync_interval_ms DOUBLE,
96  -- Whether the corresponding frame is janky.
97  is_janky_scrolled_frame BOOL,
98  -- Timestamp of the BufferAvailableToBufferReady substage.
99  buffer_available_timestamp LONG,
100  -- Timestamp of the BufferReadyToLatch substage.
101  buffer_ready_timestamp LONG,
102  -- Timestamp of the LatchToSwapEnd substage.
103  latch_timestamp LONG,
104  -- Timestamp of the SwapEndToPresentationCompositorFrame substage.
105  swap_end_timestamp LONG,
106  -- Frame presentation timestamp aka the timestamp of the
107  -- SwapEndToPresentationCompositorFrame substage.
108  -- TODO(b/341047059): temporarily use LatchToSwapEnd as a workaround if
109  -- SwapEndToPresentationCompositorFrame is missing due to b/247542163.
110  presentation_timestamp LONG
111) AS
112SELECT
113  slice.id,
114  slice.name,
115  slice.ts,
116  slice.dur,
117  EXTRACT_arg(arg_set_id, 'event_latency.event_latency_id') AS scroll_update_id,
118  _has_descendant_slice_with_name(
119    slice.id,
120    'SubmitCompositorFrameToPresentationCompositorFrame')
121    AS is_presented,
122  EXTRACT_ARG(arg_set_id, 'event_latency.event_type') AS event_type,
123  slice.track_id,
124  EXTRACT_ARG(arg_set_id, 'event_latency.vsync_interval_ms')
125    AS vsync_interval_ms,
126  COALESCE(EXTRACT_ARG(arg_set_id, 'event_latency.is_janky_scrolled_frame'), 0)
127    AS is_janky_scrolled_frame,
128  _descendant_slice_begin(slice.id, 'BufferAvailableToBufferReady')
129    AS buffer_available_timestamp,
130  _descendant_slice_begin(slice.id, 'BufferReadyToLatch')
131    AS buffer_ready_timestamp,
132  _descendant_slice_begin(slice.id, 'LatchToSwapEnd') AS latch_timestamp,
133  _descendant_slice_begin(slice.id, 'SwapEndToPresentationCompositorFrame')
134    AS swap_end_timestamp,
135  _get_presentation_timestamp(slice.id) AS presentation_timestamp
136FROM slice
137WHERE name = 'EventLatency';
138
139-- All EventLatency slices that are relevant to scrolling, including presented
140-- pinches. Materialized to reduce how many times we query slice.
141CREATE PERFETTO TABLE _gesture_scroll_events_no_scroll_id
142AS
143SELECT
144  name,
145  ts,
146  dur,
147  id,
148  scroll_update_id,
149  is_presented,
150  _get_presentation_timestamp(chrome_event_latencies.id)
151  AS presentation_timestamp,
152  event_type,
153  track_id
154FROM chrome_event_latencies
155WHERE (
156  event_type GLOB '*GESTURE_SCROLL*'
157  -- Pinches are only relevant if the frame was presented.
158  OR (event_type GLOB '*GESTURE_PINCH_UPDATE'
159    AND _has_descendant_slice_with_name(
160      id,
161      'SubmitCompositorFrameToPresentationCompositorFrame')
162  )
163);
164
165-- Extracts scroll id for the EventLatency slice at `ts`.
166CREATE PERFETTO FUNCTION chrome_get_most_recent_scroll_begin_id(
167  -- Timestamp of the EventLatency slice to get the scroll id for.
168  ts TIMESTAMP)
169-- The event_latency_id of the EventLatency slice with the type
170-- GESTURE_SCROLL_BEGIN that is the closest to `ts`.
171RETURNS LONG AS
172SELECT scroll_update_id
173FROM _gesture_scroll_events_no_scroll_id
174WHERE event_type = 'GESTURE_SCROLL_BEGIN'
175AND ts<=$ts
176ORDER BY ts DESC
177LIMIT 1;
178
179-- All scroll-related events (frames) including gesture scroll updates, begins
180-- and ends with respective scroll ids and start/end timestamps, regardless of
181-- being presented. This includes pinches that were presented. See b/315761896
182-- for context on pinches.
183CREATE PERFETTO TABLE chrome_gesture_scroll_events(
184  -- Slice Id for the EventLatency scroll event.
185  id LONG,
186  -- Slice name.
187  name STRING,
188  -- The start timestamp of the scroll.
189  ts TIMESTAMP,
190  -- The duration of the scroll.
191  dur DURATION,
192  -- The id of the scroll update event.
193  scroll_update_id LONG,
194  -- The id of the scroll.
195  scroll_id LONG,
196  -- Whether this input event was presented.
197  is_presented BOOL,
198  -- Frame presentation timestamp aka the timestamp of the
199  -- SwapEndToPresentationCompositorFrame substage.
200  -- TODO(b/341047059): temporarily use LatchToSwapEnd as a workaround if
201  -- SwapEndToPresentationCompositorFrame is missing due to b/247542163.
202  presentation_timestamp LONG,
203  -- EventLatency event type.
204  event_type STRING,
205  -- Perfetto track this slice is found on.
206  track_id LONG
207) AS
208SELECT
209  id,
210  name,
211  ts,
212  dur,
213  scroll_update_id,
214  chrome_get_most_recent_scroll_begin_id(ts) AS scroll_id,
215  is_presented,
216  presentation_timestamp,
217  event_type,
218  track_id
219FROM _gesture_scroll_events_no_scroll_id;
220