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 16DROP TABLE IF EXISTS android_jank_cuj_counter; 17CREATE PERFETTO TABLE android_jank_cuj_counter AS 18WITH cuj_counter_track AS ( 19 SELECT DISTINCT 20 upid, 21 track.id AS track_id, 22 -- extract the CUJ name inside <> 23 STR_SPLIT(STR_SPLIT(track.name, '>#', 0), '<', 1) AS cuj_name, 24 -- take the name of the counter after # 25 STR_SPLIT(track.name, '#', 1) AS counter_name 26 FROM process_counter_track track 27 JOIN android_jank_cuj USING (upid) 28 WHERE track.name GLOB 'J<*>#*' 29) 30SELECT 31 ts, 32 upid, 33 cuj_name, 34 counter_name, 35 CAST(value AS INTEGER) AS value 36FROM counter 37JOIN cuj_counter_track ON counter.track_id = cuj_counter_track.track_id; 38 39CREATE OR REPLACE PERFETTO FUNCTION android_jank_cuj_counter_value(cuj_name STRING, 40 counter_name STRING, 41 ts_min INT, 42 ts_max INT) 43RETURNS INT AS 44SELECT value 45FROM android_jank_cuj_counter 46WHERE 47 cuj_name = $cuj_name 48 AND counter_name = $counter_name 49 AND ts >= $ts_min 50 AND ($ts_max IS NULL OR ts <= $ts_max) 51ORDER BY ts ASC LIMIT 1; 52 53DROP TABLE IF EXISTS cuj_marker_missed_callback; 54CREATE PERFETTO TABLE cuj_marker_missed_callback AS 55SELECT 56 marker_track.name AS cuj_slice_name, 57 marker.ts, 58 marker.name AS marker_name 59FROM slice marker 60JOIN track marker_track on marker_track.id = marker.track_id 61WHERE marker.name GLOB '*FT#Missed*'; 62 63CREATE OR REPLACE PERFETTO FUNCTION android_missed_vsyncs_for_callback( 64 cuj_slice_name STRING, 65 ts_min INT, 66 ts_max INT, 67 callback_missed STRING 68) 69RETURNS INT AS 70SELECT IFNULL(SUM(marker_name GLOB $callback_missed), 0) 71FROM cuj_marker_missed_callback 72WHERE 73 cuj_slice_name = $cuj_slice_name 74 AND ts >= $ts_min 75 AND ($ts_max IS NULL OR ts <= $ts_max) 76ORDER BY ts ASC 77LIMIT 1; 78 79DROP TABLE IF EXISTS android_jank_cuj_counter_metrics; 80CREATE PERFETTO TABLE android_jank_cuj_counter_metrics AS 81-- Order CUJs to get the ts of the next CUJ with the same name. 82-- This is to avoid selecting counters logged for the next CUJ in case multiple 83-- CUJs happened in a short succession. 84WITH cujs_ordered AS ( 85 SELECT 86 cuj_id, 87 cuj_name, 88 cuj_slice_name, 89 upid, 90 state, 91 ts_end, 92 CASE 93 WHEN process_name GLOB 'com.android.*' THEN ts_end 94 WHEN process_name = 'com.google.android.apps.nexuslauncher' THEN ts_end 95 -- Some processes publish counters just before logging the CUJ end 96 ELSE MAX(ts, ts_end - 4000000) 97 END AS ts_earliest_allowed_counter, 98 LEAD(ts_end) OVER (PARTITION BY cuj_name ORDER BY ts_end ASC) AS ts_end_next_cuj 99 FROM android_jank_cuj 100) 101SELECT 102 cuj_id, 103 cuj_name, 104 upid, 105 state, 106 android_jank_cuj_counter_value(cuj_name, 'totalFrames', ts_earliest_allowed_counter, ts_end_next_cuj) AS total_frames, 107 android_jank_cuj_counter_value(cuj_name, 'missedFrames', ts_earliest_allowed_counter, ts_end_next_cuj) AS missed_frames, 108 android_jank_cuj_counter_value(cuj_name, 'missedAppFrames', ts_earliest_allowed_counter, ts_end_next_cuj) AS missed_app_frames, 109 android_jank_cuj_counter_value(cuj_name, 'missedSfFrames', ts_earliest_allowed_counter, ts_end_next_cuj) AS missed_sf_frames, 110 android_jank_cuj_counter_value(cuj_name, 'maxSuccessiveMissedFrames', ts_earliest_allowed_counter, ts_end_next_cuj) AS missed_frames_max_successive, 111 -- convert ms to nanos to align with the unit for `dur` in the other tables 112 android_jank_cuj_counter_value(cuj_name, 'maxFrameTimeMillis', ts_earliest_allowed_counter, ts_end_next_cuj) * 1000000 AS frame_dur_max, 113 android_missed_vsyncs_for_callback(cuj_slice_name, ts_earliest_allowed_counter, ts_end_next_cuj, '*SF*') AS sf_callback_missed_frames, 114 android_missed_vsyncs_for_callback(cuj_slice_name, ts_earliest_allowed_counter, ts_end_next_cuj, '*HWUI*') AS hwui_callback_missed_frames 115FROM cujs_ordered cuj; 116