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-- These are helper functions/tables used in computing jank metrics 6 7INCLUDE PERFETTO MODULE chrome.event_latency; 8 9-- This function takes timestamps of two consecutive frames and determines if 10-- its janky by a delay of more than 0.5 of a frame in order to make sure that 11-- the comparison does not filter out ratios that are precisely 0.5, which can 12-- fall a little above or below exact value due to inherent inaccuracy of operations with 13-- floating-point numbers. Value 1e-9 have been chosen as follows: the ratio has 14-- nanoseconds in numerator and VSync interval in denominator. Assuming refresh 15-- rate more than 1 FPS (and therefore VSync interval less than a second), this 16-- ratio should increase with increments more than minimal value in numerator 17-- (1ns) divided by maximum value in denominator, giving 1e-9. 18 19-- Function : function takes scroll ids of frames to verify it's from 20-- the same scroll, and makes sure the frame ts occurred within the scroll 21-- timestamp of the neighbour and computes whether the frame was janky or not. 22CREATE PERFETTO FUNCTION _is_janky_frame(cur_gesture_id LONG, 23 neighbour_gesture_id LONG, 24 neighbour_ts TIMESTAMP, 25 cur_gesture_begin_ts TIMESTAMP, 26 cur_gesture_end_ts TIMESTAMP, 27 cur_frame_exact DOUBLE, 28 neighbour_frame_exact DOUBLE) 29-- Returns true if the frame was janky, false otherwise 30RETURNS BOOL AS 31SELECT 32 CASE WHEN 33 $cur_gesture_id != $neighbour_gesture_id OR 34 $neighbour_ts IS NULL OR 35 $neighbour_ts < $cur_gesture_begin_ts OR 36 $neighbour_ts > $cur_gesture_end_ts THEN 37 FALSE ELSE 38 $cur_frame_exact > $neighbour_frame_exact + 0.5 + 1e-9 39 END; 40 41-- Function : function takes the cur_frame_exact, prev_frame_exact and 42-- next_frame_exact and returns the value of the jank budget of the current 43-- frame. 44-- 45-- jank_budget is the minimum amount of frames/time we need to reduce the frame 46-- duration by for it to be no longer considered janky. 47-- 48-- Returns the jank budget in percentage (i.e. 0.75) of vsync interval 49-- percentage. 50CREATE PERFETTO FUNCTION _jank_budget( 51 cur_frame_exact DOUBLE, 52 prev_frame_exact DOUBLE, 53 next_frame_exact DOUBLE 54) 55RETURNS DOUBLE AS 56-- We determine the difference between the frame count of the current frame 57-- and its consecutive frames by subtracting with the frame_exact values. We 58-- null check for cases when the neighbor frame count can be null for the 59-- first and last frames. 60-- 61-- Since a frame is considered janky, if the difference in the frame count 62-- with its adjacent frame is greater than 0.5 (half a vsync) which means we 63-- need to reduce the frame count by a value less than 0.5 of maximum 64-- difference in frame count for it to be no longer janky. We subtract 1e-9 as 65-- we want to output minimum amount required. 66SELECT 67 COALESCE( 68 -- Could be null if next or previous is null. 69 MAX( 70 ($cur_frame_exact - $prev_frame_exact), 71 ($cur_frame_exact - $next_frame_exact) 72 ), 73 -- If one of them is null output the first non-null. 74 ($cur_frame_exact - $prev_frame_exact), 75 ($cur_frame_exact - $next_frame_exact) 76 -- Otherwise return null 77 ) - 0.5 - 1e-9; 78 79-- Extract mojo information for the long-task-tracking scenario for specific 80-- names. For example, LongTaskTracker slices may have associated IPC 81-- metadata, or InterestingTask slices for input may have associated IPC to 82-- determine whether the task is fling/etc. 83CREATE PERFETTO FUNCTION chrome_select_long_task_slices( 84 -- The name of slice. 85 name STRING) 86RETURNS TABLE( 87 -- Name of the interface of the IPC call. 88 interface_name STRING, 89 -- Hash of the IPC call. 90 ipc_hash LONG, 91 -- Message type (e.g. reply). 92 message_type STRING, 93 -- The slice id. 94 id LONG 95) AS 96SELECT 97 EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name, 98 EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash, 99 CASE 100 WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply" 101 ELSE "message" 102 END AS message_type, 103 s.id 104FROM slice s 105WHERE 106 category GLOB "*scheduler.long_tasks*" 107 AND name = $name; 108