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-- Create the base table (`android_jank_cuj`) containing all completed CUJs 17-- found in the trace. 18SELECT RUN_METRIC('android/jank/cujs.sql'); 19 20-- Creates tables that store constant parameters for each CUJ - e.g. parameter 21-- that describes whether Choreographer callbacks run on a dedicated thread. 22SELECT RUN_METRIC('android/jank/params.sql'); 23 24-- Create tables to store each CUJs main, render, HWC release, 25-- and GPU completion threads. 26-- Also stores the (not CUJ-specific) threads of SF: main, render engine, 27-- and GPU completion threads. 28SELECT RUN_METRIC('android/jank/relevant_threads.sql'); 29 30-- Create tables to store the main slices on each of the relevant threads 31-- * `Choreographer#doFrame` on the main thread 32-- * `DrawFrames on the render` thread 33-- * `waiting for HWC release` on the HWC release thread 34-- * `Waiting for GPU completion` on the GPU completion thread 35-- * `commit` and `composite` on SF main thread. 36-- * `REThreaded::drawLayers` on SF RenderEngine thread. 37-- Also extracts vsync ids and GPU completion fence ids that allow us to match 38-- slices to concrete vsync IDs. 39-- Slices and vsyncs are matched between the app and SF processes by looking 40-- at the actual frame timeline data. 41-- We only store the slices that were produced for the vsyncs within the 42-- CUJ markers. 43SELECT RUN_METRIC('android/jank/relevant_slices.sql'); 44 45-- Computes the boundaries of specific frames and overall CUJ boundaries 46-- on specific important threads since each thread will work on a frame at a 47-- slightly different time. 48-- We also compute the corrected CUJ ts boundaries. This is necessary because 49-- the instrumentation logs begin/end CUJ markers *during* the first frame and 50-- typically *right at the start* of the last CUJ frame. The ts boundaries in 51-- `android_jank_cuj` table are based on these markers so do not actually 52-- contain the whole CUJ, but instead overlap with all Choreographer#doFrame 53-- slices that belong to a CUJ. 54SELECT RUN_METRIC('android/jank/cujs_boundaries.sql'); 55 56-- With relevant slices and corrected boundaries we can now estimate the ts 57-- boundaries of each frame within the CUJ. 58-- We also match with the data from the actual timeline to check which frames 59-- missed the deadline and whether this was due to the app or SF. 60SELECT RUN_METRIC('android/jank/frames.sql'); 61 62-- Creates tables with slices from various relevant threads that are within 63-- the CUJ boundaries. Used as data sources for further processing and 64-- jank cause analysis of traces. 65SELECT RUN_METRIC('android/jank/slices.sql'); 66 67-- Creates tables and functions to be used for manual investigations and 68-- jank cause analysis of traces. 69SELECT RUN_METRIC('android/jank/internal/query_base.sql'); 70SELECT RUN_METRIC('android/jank/query_functions.sql'); 71 72-- Creates a table that matches CUJ counters with the correct CUJs. 73-- After the CUJ ends FrameTracker emits counters with the number of total 74-- frames, missed frames, longest frame duration, etc. 75-- The same numbers are also reported by FrameTracker to statsd. 76SELECT RUN_METRIC('android/jank/internal/counters.sql'); 77 78-- Creates derived events to visualize a few of the created tables. 79-- Used only for debugging so by default not used and not displayed in the UI. 80-- See https://perfetto.dev/docs/contributing/common-tasks#adding-new-derived-events 81-- for instructions on how to add these events to the UI. 82SELECT RUN_METRIC('android/jank/internal/derived_events.sql'); 83 84 85DROP VIEW IF EXISTS android_jank_cuj_output; 86CREATE VIEW android_jank_cuj_output AS 87SELECT 88 AndroidJankCujMetric( 89 'cuj', ( 90 SELECT RepeatedField( 91 AndroidJankCujMetric_Cuj( 92 'id', cuj_id, 93 'name', cuj_name, 94 'process', process_metadata, 95 'layer_name', layer_name, 96 'ts', COALESCE(boundary.ts, cuj.ts), 97 'dur', COALESCE(boundary.dur, cuj.dur), 98 'counter_metrics', ( 99 SELECT AndroidJankCujMetric_Metrics( 100 'total_frames', total_frames, 101 'missed_frames', missed_frames, 102 'missed_app_frames', missed_app_frames, 103 'missed_sf_frames', missed_sf_frames, 104 'missed_frames_max_successive', missed_frames_max_successive, 105 'sf_callback_missed_frames', sf_callback_missed_frames, 106 'hwui_callback_missed_frames', hwui_callback_missed_frames, 107 'frame_dur_max', frame_dur_max) 108 FROM android_jank_cuj_counter_metrics cm 109 WHERE cm.cuj_id = cuj.cuj_id), 110 'trace_metrics', ( 111 SELECT AndroidJankCujMetric_Metrics( 112 'total_frames', COUNT(*), 113 'missed_frames', SUM(app_missed OR sf_missed), 114 'missed_app_frames', SUM(app_missed), 115 'missed_sf_frames', SUM(sf_missed), 116 'sf_callback_missed_frames', SUM(sf_callback_missed), 117 'hwui_callback_missed_frames', SUM(hwui_callback_missed), 118 'frame_dur_max', MAX(f.dur), 119 'frame_dur_avg', CAST(AVG(f.dur) AS INTEGER), 120 'frame_dur_p50', CAST(PERCENTILE(f.dur, 50) AS INTEGER), 121 'frame_dur_p90', CAST(PERCENTILE(f.dur, 90) AS INTEGER), 122 'frame_dur_p95', CAST(PERCENTILE(f.dur, 95) AS INTEGER), 123 'frame_dur_p99', CAST(PERCENTILE(f.dur, 99) AS INTEGER), 124 'frame_dur_ms_p50', PERCENTILE(f.dur / 1e6, 50), 125 'frame_dur_ms_p90', PERCENTILE(f.dur / 1e6, 90), 126 'frame_dur_ms_p95', PERCENTILE(f.dur / 1e6, 95), 127 'frame_dur_ms_p99', PERCENTILE(f.dur / 1e6, 99)) 128 FROM android_jank_cuj_frame f 129 WHERE f.cuj_id = cuj.cuj_id), 130 'timeline_metrics', ( 131 SELECT AndroidJankCujMetric_Metrics( 132 'total_frames', COUNT(*), 133 'missed_frames', SUM(app_missed OR sf_missed), 134 'missed_app_frames', SUM(app_missed), 135 'missed_sf_frames', SUM(sf_missed), 136 'sf_callback_missed_frames', SUM(sf_callback_missed), 137 'hwui_callback_missed_frames', SUM(hwui_callback_missed), 138 'frame_dur_max', MAX(f.dur), 139 'frame_dur_avg', CAST(AVG(f.dur) AS INTEGER), 140 'frame_dur_p50', CAST(PERCENTILE(f.dur, 50) AS INTEGER), 141 'frame_dur_p90', CAST(PERCENTILE(f.dur, 90) AS INTEGER), 142 'frame_dur_p95', CAST(PERCENTILE(f.dur, 95) AS INTEGER), 143 'frame_dur_p99', CAST(PERCENTILE(f.dur, 99) AS INTEGER), 144 'frame_dur_ms_p50', PERCENTILE(f.dur / 1e6, 50), 145 'frame_dur_ms_p90', PERCENTILE(f.dur / 1e6, 90), 146 'frame_dur_ms_p95', PERCENTILE(f.dur / 1e6, 95), 147 'frame_dur_ms_p99', PERCENTILE(f.dur / 1e6, 99)) 148 FROM android_jank_cuj_frame_timeline f 149 WHERE f.cuj_id = cuj.cuj_id), 150 'frame', ( 151 SELECT RepeatedField( 152 AndroidJankCujMetric_Frame( 153 'frame_number', f.frame_number, 154 'vsync', f.vsync, 155 'ts', f.ts, 156 'dur', f.dur, 157 'dur_expected', f.dur_expected, 158 'app_missed', f.app_missed, 159 'sf_missed', f.sf_missed, 160 'sf_callback_missed', f.sf_callback_missed, 161 'hwui_callback_missed', f.hwui_callback_missed)) 162 FROM android_jank_cuj_frame f 163 WHERE f.cuj_id = cuj.cuj_id 164 ORDER BY frame_number ASC), 165 'sf_frame', ( 166 SELECT RepeatedField( 167 AndroidJankCujMetric_Frame( 168 'frame_number', f.frame_number, 169 'vsync', f.vsync, 170 'ts', f.ts, 171 'dur', f.dur, 172 'dur_expected', f.dur_expected, 173 'sf_missed', f.sf_missed)) 174 FROM android_jank_cuj_sf_frame f 175 WHERE f.cuj_id = cuj.cuj_id 176 ORDER BY frame_number ASC) 177 )) 178 FROM android_jank_cuj cuj 179 LEFT JOIN android_jank_cuj_boundary boundary USING (cuj_id) 180 LEFT JOIN android_jank_cuj_layer_name cuj_layer USING (cuj_id) 181 ORDER BY cuj.cuj_id ASC)); 182