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 5-- This file creates two public views: 6-- - chrome_scroll_input_offsets and 7-- - chrome_presented_scroll_offsets 8-- 9-- These views store the pixel deltas and offsets for (respectively) all chrome 10-- scroll inputs (coalesced and not coalesced), and for chrome presented frames 11-- (not coalesced), along with the associated timestamp, and id. 12-- 13-- Raw deltas are recorded as changes in pixel positions along the y-axis of a 14-- screen, and are scaled to the viewport size. The corresponding trace event 15-- for this is TranslateAndScaleWebInputEvent. These are the deltas for all 16-- chrome scroll inputs. 17-- 18-- For presented frames, the delta is calculated from the visual offset, 19-- recorded once the input has been processed, in the 20-- InputHandlerProxy::HandleGestureScrollUpdate_Result event. These values are 21-- also scaled to the screen size. 22-- 23-- Offsets are calculated by summing all of the deltas, ordered by timestamp. 24-- For a given input/frame, the offset is the sum of its corresponding delta and 25-- all previous deltas. 26-- 27-- 28-- All values required for calculating deltas and offsets are recorded at 29-- various stages of input processing, and are unified by a single 30-- scroll_update_id value, recorded as scroll_deltas.trace_id in each event. 31 32INCLUDE PERFETTO MODULE chrome.scroll_jank.scroll_jank_v3; 33 34-- Non-coalesced scroll update events and their timestamps. 35CREATE PERFETTO VIEW internal_non_coalesced_scrolls AS 36SELECT 37 scroll_update_id, 38 ts 39FROM chrome_gesture_scroll_updates 40WHERE is_coalesced = False; 41 42-- All (coalesced and non-coalesced) vertical scrolling deltas and their 43-- associated scroll ids. Delta values are recorded after being scaled to the 44-- device's screen size in the TranslateAndScaleWebInputEvent trace event. In 45-- this trace event, the deltas recorded represent the true (read "original") 46-- values that the Browser receives from Android, and the only processing is 47-- scaling and translation. 48CREATE PERFETTO TABLE internal_scroll_deltas AS 49SELECT 50 EXTRACT_ARG(arg_set_id, 'scroll_deltas.trace_id') AS scroll_update_id, 51 EXTRACT_ARG(arg_set_id, 'scroll_deltas.original_delta_y') AS delta_y, 52 EXTRACT_ARG(arg_set_id, 'scroll_deltas.original_delta_y') IS NOT NULL AS is_coalesced 53FROM slice 54WHERE name = "TranslateAndScaleWebInputEvent"; 55 56-- Associate the raw (original) deltas (internal_scroll_deltas) with the 57-- corresponding non-coalesced scroll updates 58-- (internal_non_coalesced_scroll_updates) to get the timestamp of the event 59-- those deltas. This allows for ordering delta recordings to track them over 60-- time. 61CREATE PERFETTO VIEW internal_non_coalesced_deltas AS 62SELECT 63 scroll_update_id, 64 ts, 65 delta_y 66FROM internal_non_coalesced_scrolls 67INNER JOIN internal_scroll_deltas 68 USING (scroll_update_id); 69 70-- Selecting information scroll update events that have been coalesced, 71-- including timestamp and the specific event (scroll update id) it was 72-- coalesced into. Recordings of deltas will need to be associated with the 73-- timestamp of the scroll update they were coalesced into. 74CREATE PERFETTO TABLE internal_scroll_update_coalesce_info AS 75SELECT 76 ts, 77 EXTRACT_ARG(arg_set_id, 'scroll_deltas.coalesced_to_trace_id') AS coalesced_to_scroll_update_id, 78 EXTRACT_ARG(arg_set_id, 'scroll_deltas.trace_id') AS scroll_update_id 79FROM slice 80WHERE name = "WebCoalescedInputEvent::CoalesceWith" AND 81 coalesced_to_scroll_update_id IS NOT NULL; 82 83-- Associate the raw (original) deltas (internal_scroll_deltas) with the 84-- corresponding coalesced scroll updates (internal_scroll_update_coalesce_info) 85-- to get the timestamp of the event those deltas were coalesced into. This 86-- allows us to get the scaled coordinates for all of the input events 87-- (original input coordinates can't be used due to scaling). 88CREATE PERFETTO VIEW internal_coalesced_deltas AS 89SELECT 90 internal_scroll_update_coalesce_info.coalesced_to_scroll_update_id AS scroll_update_id, 91 ts, 92 internal_scroll_deltas.delta_y AS delta_y, 93 TRUE AS is_coalesced 94FROM internal_scroll_update_coalesce_info 95LEFT JOIN internal_scroll_deltas 96 USING (scroll_update_id); 97 98-- All of the presented frame scroll update ids. 99CREATE PERFETTO VIEW chrome_deltas_presented_frame_scroll_update_ids( 100 -- A scroll update id that was included in the presented frame. 101 -- There may be zero, one, or more. 102 scroll_update_id INT, 103 -- Slice id 104 id INT 105) AS 106SELECT 107 args.int_value AS scroll_update_id, 108 slice.id 109FROM args 110LEFT JOIN slice 111 USING (arg_set_id) 112WHERE slice.name = 'PresentedFrameInformation' 113AND args.flat_key GLOB 'scroll_deltas.trace_ids_in_gpu_frame*';; 114 115-- When every GestureScrollUpdate event is processed, the offset set by the 116-- compositor is recorded. This offset is scaled to the device screen size, and 117-- can be used to calculate deltas. 118CREATE PERFETTO VIEW internal_presented_frame_offsets AS 119SELECT 120 EXTRACT_ARG(arg_set_id, 'scroll_deltas.trace_id') AS scroll_update_id, 121 EXTRACT_ARG(arg_set_id, 'scroll_deltas.visual_offset_y') AS visual_offset_y 122FROM slice 123WHERE name = 'InputHandlerProxy::HandleGestureScrollUpdate_Result'; 124 125-- The raw coordinates and pixel offsets for all input events which were part of 126-- a scroll. This includes input events that were converted to scroll events 127-- which were presented (internal_non_coalesced_scrolls) and scroll events which 128-- were coalesced (internal_coalesced_deltas). 129CREATE PERFETTO TABLE chrome_scroll_input_offsets( 130 -- Trace id associated with the scroll. 131 scroll_update_id INT, 132 -- Timestamp the of the scroll input event. 133 ts INT, 134 -- The delta in raw coordinates between this scroll update event and the previous. 135 delta_y INT, 136 -- The pixel offset of this scroll update event compared to the previous one. 137 offset_y INT 138) AS 139-- First collect all coalesced and non-coalesced deltas so that the offsets 140-- can be calculated from them in order of timestamp. 141WITH all_deltas AS ( 142 SELECT 143 scroll_update_id, 144 ts, 145 delta_y 146 FROM internal_non_coalesced_deltas 147 WHERE delta_y IS NOT NULL 148 UNION 149 SELECT 150 scroll_update_id, 151 ts, 152 delta_y 153 FROM internal_coalesced_deltas 154 WHERE delta_y IS NOT NULL 155 ORDER BY scroll_update_id, ts) 156SELECT 157 scroll_update_id, 158 ts, 159 delta_y, 160 SUM(IFNULL(delta_y, 0)) OVER ( 161 ORDER BY scroll_update_id, ts 162 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS offset_y 163FROM all_deltas; 164 165-- Calculate the total visual offset for all presented frames (non-coalesced 166-- scroll updates) that have raw deltas recorded. These visual offsets 167-- correspond with the inverse of the deltas for the presented frame. 168CREATE PERFETTO VIEW internal_preprocessed_presented_frame_offsets AS 169SELECT 170 chrome_full_frame_view.scroll_update_id, 171 chrome_full_frame_view.presentation_timestamp AS ts, 172 chrome_deltas_presented_frame_scroll_update_ids.id, 173 internal_presented_frame_offsets.visual_offset_y - 174 LAG(internal_presented_frame_offsets.visual_offset_y) 175 OVER (ORDER BY chrome_full_frame_view.presentation_timestamp) 176 AS presented_frame_visual_offset_y 177FROM chrome_full_frame_view 178LEFT JOIN internal_scroll_deltas 179 USING (scroll_update_id) 180LEFT JOIN chrome_deltas_presented_frame_scroll_update_ids 181 USING (scroll_update_id) 182LEFT JOIN internal_presented_frame_offsets 183 USING (scroll_update_id) 184WHERE internal_scroll_deltas.delta_y IS NOT NULL; 185 186-- The scrolling offsets for the actual (applied) scroll events. These are not 187-- necessarily inclusive of all user scroll events, rather those scroll events 188-- that are actually processed. 189CREATE PERFETTO TABLE chrome_presented_scroll_offsets( 190 -- Trace Id associated with the scroll. 191 scroll_update_id INT, 192 -- Presentation timestamp. 193 ts INT, 194 -- The delta in coordinates as processed by Chrome between this scroll update 195 -- event and the previous. 196 delta_y INT, 197 -- The pixel offset of this scroll update (the presented frame) compared to 198 -- the previous one. 199 offset_y INT 200) AS 201WITH all_deltas AS ( 202 SELECT 203 scroll_update_id, 204 id, 205 MAX(ts) AS ts, 206 SUM(presented_frame_visual_offset_y) * -1 AS delta_y 207 FROM internal_preprocessed_presented_frame_offsets 208 GROUP BY id 209 ORDER BY ts) 210SELECT 211 scroll_update_id, 212 ts, 213 delta_y, 214 SUM(IFNULL(delta_y, 0)) OVER ( 215 ORDER BY scroll_update_id, ts 216 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS offset_y 217FROM all_deltas; 218