1-- 2-- Copyright 2022 The Android Open Source Project 3-- 4-- Licensed under the Apache License, Version 2.0 (the "License"); 5-- you may not use this file except in compliance with the License. 6-- You may obtain a copy of the License at 7-- 8-- https://www.apache.org/licenses/LICENSE-2.0 9-- 10-- Unless required by applicable law or agreed to in writing, software 11-- distributed under the License is distributed on an "AS IS" BASIS, 12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13-- See the License for the specific language governing permissions and 14-- limitations under the License. 15-- 16-- Those are helper functions used in computing jank metrics 17 18-- This function takes timestamps of two consecutive frames and determines if 19-- its janky by a delay of more than 0.5 of a frame in order to make sure that 20-- the comparison does not filter out ratios that are precisely 0.5, which can 21-- fall a little above or below exact value due to inherent inaccuracy of operations with 22-- floating-point numbers. Value 1e-9 have been chosen as follows: the ratio has 23-- nanoseconds in numerator and VSync interval in denominator. Assuming refresh 24-- rate more than 1 FPS (and therefore VSync interval less than a second), this 25-- ratio should increase with increments more than minimal value in numerator 26-- (1ns) divided by maximum value in denominator, giving 1e-9. 27 28SELECT CREATE_FUNCTION( 29 -- Function : function takes scroll ids of frames to verify it's from 30 -- the same scroll, and makes sure the frame ts occured within the scroll 31 -- timestamp of the neighbour and computes whether the frame was janky or not. 32 'IsJankyFrame(cur_id LONG,next_id LONG,neighbour_ts LONG,' || 33 'cur_begin_ts LONG,cur_gesture_end LONG,cur_frame_exact FLOAT,' || 34 'neighbour_frame_exact FLOAT)', 35 -- Returns true if the frame was janky, false otherwise 36 'BOOL', 37 'SELECT 38 CASE WHEN 39 $cur_id != $next_id OR 40 $neighbour_ts IS NULL OR 41 $neighbour_ts < $cur_begin_ts OR 42 $neighbour_ts > $cur_gesture_end THEN 43 FALSE ELSE 44 $cur_frame_exact > $neighbour_frame_exact + 0.5 + 1e-9 45 END' 46); 47 48SELECT CREATE_FUNCTION( 49 -- Function : function takes the cur_frame_exact, prev_frame_exact and 50 -- next_frame_exact and returns the value of the jank budget of the current 51 -- frame. 52 -- 53 -- JankBudget is the minimum amount of frames/time we need to reduce the frame 54 -- duration by for it to be no longer considered janky. 55 'JankBudget(cur_frame_exact FLOAT, prev_frame_exact FLOAT, ' || 56 ' next_frame_exact FLOAT)', 57 -- Returns the jank budget in percentage (i.e. 0.75) of vsync interval 58 -- percentage. 59 -- 60 -- We determine the difference between the frame count of the current frame 61 -- and its consecutive frames by subtracting with the frame_exact values. We 62 -- null check for cases when the neighbor frame count can be null for the 63 -- first and last frames. 64 -- 65 -- Since a frame is considered janky, if the difference in the frame count 66 -- with its adjacent frame is greater than 0.5 (half a vsync) which means we 67 -- need to reduce the frame count by a value less than 0.5 of maximum 68 -- difference in frame count for it to be no longer janky. We subtract 1e-9 as 69 -- we want to output minimum amount required. 70 'FLOAT', 71 'SELECT 72 COALESCE( 73 -- Could be null if next or previous is null. 74 MAX( 75 ($cur_frame_exact - $prev_frame_exact), 76 ($cur_frame_exact - $next_frame_exact) 77 ), 78 -- If one of them is null output the first non-null. 79 ($cur_frame_exact - $prev_frame_exact), 80 ($cur_frame_exact - $next_frame_exact) 81 -- Otherwise return null 82 ) - 0.5 - 1e-9' 83); 84