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