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 16SELECT RUN_METRIC('android/process_metadata.sql'); 17 18DROP VIEW IF EXISTS splitted_jank_type_timeline; 19CREATE PERFETTO VIEW splitted_jank_type_timeline AS 20WITH RECURSIVE split_jank_type AS ( 21 SELECT 22 upid, 23 name, 24 present_type, 25 '' AS jank_type, 26 jank_type || ', ' AS unparsed 27 FROM actual_frame_timeline_slice 28 UNION ALL 29 SELECT 30 upid, 31 name, 32 present_type, 33 substr(unparsed, 1, instr(unparsed, ',')-1) AS jank_type, 34 substr(unparsed, instr(unparsed, ',')+2) AS unparsed 35 FROM split_jank_type 36 WHERE unparsed != '' 37) 38SELECT 39 upid, 40 name AS vsync, 41 present_type, 42 jank_type 43FROM split_jank_type 44WHERE jank_type != ''; 45 46DROP VIEW IF EXISTS android_frame_timeline_metric_per_process; 47CREATE PERFETTO VIEW android_frame_timeline_metric_per_process AS 48WITH frames AS ( 49 SELECT 50 process.upid, 51 process.name AS process_name, 52 timeline.name AS vsync, 53 jank_type GLOB '*App Deadline Missed*' AS missed_app_frame, 54 jank_type GLOB '*SurfaceFlinger CPU Deadline Missed*' 55 OR jank_type GLOB '*SurfaceFlinger GPU Deadline Missed*' 56 OR jank_type GLOB '*SurfaceFlinger Scheduling*' 57 OR jank_type GLOB '*Prediction Error*' 58 OR jank_type GLOB '*Display HAL*' AS missed_sf_frame, 59 jank_type GLOB '*App Deadline Missed*' 60 OR jank_type GLOB '*SurfaceFlinger CPU Deadline Missed*' 61 OR jank_type GLOB '*SurfaceFlinger GPU Deadline Missed*' 62 OR jank_type GLOB '*SurfaceFlinger Scheduling*' 63 OR jank_type GLOB '*Prediction Error*' 64 OR jank_type GLOB '*Display HAL*' 65 OR jank_type GLOB '*Dropped Frame*' AS missed_frame, 66 jank_type GLOB '*Dropped Frame*' AS dropped_frame, 67 -- discard dropped frame duration as it is not a meaningful value 68 IIF(jank_type GLOB '*Dropped Frame*', NULL, dur) AS dur, 69 IIF(jank_type GLOB '*Dropped Frame*', NULL, dur / 1e6) AS dur_ms 70 FROM actual_frame_timeline_slice timeline 71 JOIN process USING (upid)) 72SELECT 73 upid, 74 process_name, 75 process_metadata.metadata AS process_metadata, 76 COUNT(DISTINCT(vsync)) AS total_frames, 77 COUNT(DISTINCT(IIF(missed_app_frame, vsync, NULL))) AS missed_app_frames, 78 COUNT(DISTINCT(IIF(missed_sf_frame, vsync, NULL))) AS missed_sf_frames, 79 COUNT(DISTINCT(IIF(missed_frame, vsync, NULL))) AS missed_frames, 80 COUNT(DISTINCT(IIF(dropped_frame, vsync, NULL))) AS dropped_frames, 81 CAST(PERCENTILE(dur, 50) AS INTEGER) AS frame_dur_p50, 82 CAST(PERCENTILE(dur, 90) AS INTEGER) AS frame_dur_p90, 83 CAST(PERCENTILE(dur, 95) AS INTEGER) AS frame_dur_p95, 84 CAST(PERCENTILE(dur, 99) AS INTEGER) AS frame_dur_p99, 85 PERCENTILE(dur_ms, 50) AS frame_dur_ms_p50, 86 PERCENTILE(dur_ms, 90) AS frame_dur_ms_p90, 87 PERCENTILE(dur_ms, 95) AS frame_dur_ms_p95, 88 PERCENTILE(dur_ms, 99) AS frame_dur_ms_p99, 89 CAST(AVG(dur) AS INTEGER) AS frame_dur_avg, 90 MAX(dur) AS frame_dur_max 91FROM frames 92JOIN process_metadata USING (upid) 93GROUP BY upid, process_name; 94 95DROP VIEW IF EXISTS android_frame_timeline_metric_output; 96CREATE PERFETTO VIEW android_frame_timeline_metric_output AS 97WITH per_jank_type_metric AS ( 98 SELECT 99 jank_type, 100 COUNT(DISTINCT(vsync)) AS total_count, 101 COUNT(DISTINCT(IIF(present_type = 'Unspecified Present', vsync, NULL))) AS present_unspecified_count, 102 COUNT(DISTINCT(IIF(present_type = 'On-time Present', vsync, NULL))) AS present_on_time_count, 103 COUNT(DISTINCT(IIF(present_type = 'Late Present', vsync, NULL))) AS present_late_count, 104 COUNT(DISTINCT(IIF(present_type = 'Early Present', vsync, NULL))) AS present_early_count, 105 COUNT(DISTINCT(IIF(present_type = 'Dropped Frame', vsync, NULL))) AS present_dropped_count, 106 COUNT(DISTINCT(IIF(present_type = 'Unknown Present', vsync, NULL))) AS present_unknown_count 107 FROM splitted_jank_type_timeline 108 GROUP BY jank_type 109), 110per_process_jank_type_metric AS ( 111 SELECT 112 upid, 113 jank_type, 114 COUNT(DISTINCT(vsync)) AS total_count, 115 COUNT(DISTINCT(IIF(present_type = 'Unspecified Present', vsync, NULL))) AS present_unspecified_count, 116 COUNT(DISTINCT(IIF(present_type = 'On-time Present', vsync, NULL))) AS present_on_time_count, 117 COUNT(DISTINCT(IIF(present_type = 'Late Present', vsync, NULL))) AS present_late_count, 118 COUNT(DISTINCT(IIF(present_type = 'Early Present', vsync, NULL))) AS present_early_count, 119 COUNT(DISTINCT(IIF(present_type = 'Dropped Frame', vsync, NULL))) AS present_dropped_count, 120 COUNT(DISTINCT(IIF(present_type = 'Unknown Present', vsync, NULL))) AS present_unknown_count 121 FROM splitted_jank_type_timeline 122 GROUP BY upid, jank_type 123) 124SELECT 125 AndroidFrameTimelineMetric( 126 'total_frames', SUM(total_frames), 127 'missed_app_frames', SUM(missed_app_frames), 128 'dropped_frames', SUM(dropped_frames), 129 'process', ( 130 SELECT 131 RepeatedField( 132 AndroidFrameTimelineMetric_ProcessBreakdown( 133 'process', process_metadata, 134 'total_frames', total_frames, 135 'missed_frames', missed_frames, 136 'missed_app_frames', missed_app_frames, 137 'missed_sf_frames', missed_sf_frames, 138 'frame_dur_max', frame_dur_max, 139 'frame_dur_avg', frame_dur_avg, 140 'frame_dur_p50', frame_dur_p50, 141 'frame_dur_p90', frame_dur_p90, 142 'frame_dur_p95', frame_dur_p95, 143 'frame_dur_p99', frame_dur_p99, 144 'frame_dur_ms_p50', frame_dur_ms_p50, 145 'frame_dur_ms_p90', frame_dur_ms_p90, 146 'frame_dur_ms_p95', frame_dur_ms_p95, 147 'frame_dur_ms_p99', frame_dur_ms_p99, 148 'dropped_frames', dropped_frames, 149 'jank_types', ( 150 SELECT 151 RepeatedField( 152 AndroidFrameTimelineMetric_JankTypeMetric( 153 'type', jank_type, 154 'total_count', total_count, 155 'present_unspecified_count', present_unspecified_count, 156 'present_on_time_count', present_on_time_count, 157 'present_late_count', present_late_count, 158 'present_early_count', present_early_count, 159 'present_dropped_count', present_dropped_count, 160 'present_unknown_count', present_unknown_count 161 ) 162 ) 163 FROM per_process_jank_type_metric 164 WHERE upid = process.upid 165 ) 166 ) 167 ) 168 FROM android_frame_timeline_metric_per_process process 169 ), 170 'jank_types', ( 171 SELECT 172 RepeatedField( 173 AndroidFrameTimelineMetric_JankTypeMetric( 174 'type', jank_type, 175 'total_count', total_count, 176 'present_unspecified_count', present_unspecified_count, 177 'present_on_time_count', present_on_time_count, 178 'present_late_count', present_late_count, 179 'present_early_count', present_early_count, 180 'present_dropped_count', present_dropped_count, 181 'present_unknown_count', present_unknown_count 182 ) 183 ) 184 FROM per_jank_type_metric 185 ) 186 ) 187FROM android_frame_timeline_metric_per_process; 188