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