• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 vsync_missed_callback;
17CREATE TABLE vsync_missed_callback AS
18SELECT CAST(STR_SPLIT(name, 'Callback#', 1) AS INTEGER) AS vsync,
19       MAX(name GLOB '*SF*') as sf_callback_missed,
20       MAX(name GLOB '*HWUI*') as hwui_callback_missed
21FROM slice
22WHERE name GLOB '*FT#Missed*Callback*'
23GROUP BY vsync;
24
25DROP TABLE IF EXISTS android_jank_cuj_frame_timeline;
26CREATE TABLE android_jank_cuj_frame_timeline AS
27WITH actual_timeline_with_vsync AS (
28  SELECT
29    *,
30    CAST(name AS INTEGER) AS vsync
31  FROM actual_frame_timeline_slice
32  WHERE dur > 0
33)
34SELECT
35  cuj_id,
36  vsync,
37  -- We use MAX to check if at least one of the layers jank_type matches the pattern
38  MAX(jank_type GLOB '*App Deadline Missed*') AS app_missed,
39  -- We use MAX to check if at least one of the layers jank_type matches the pattern
40  MAX(
41    jank_type GLOB '*SurfaceFlinger CPU Deadline Missed*'
42    OR jank_type GLOB '*SurfaceFlinger GPU Deadline Missed*'
43    OR jank_type GLOB '*SurfaceFlinger Scheduling*'
44    OR jank_type GLOB '*Prediction Error*'
45    OR jank_type GLOB '*Display HAL*') AS sf_missed,
46  IFNULL(MAX(sf_callback_missed), 0) AS sf_callback_missed,
47  IFNULL(MAX(hwui_callback_missed), 0) AS hwui_callback_missed,
48  -- We use MIN to check if ALL layers finished on time
49  MIN(on_time_finish) AS on_time_finish,
50  MAX(timeline.ts + timeline.dur) AS ts_end_actual,
51  MAX(timeline.dur) AS dur,
52  -- At the moment of writing we expect to see at most one expected_frame_timeline_slice
53  -- for a given vsync but using MAX here in case this changes in the future.
54  -- In case expected timeline is missing, as a fallback we use the typical frame deadline
55  -- for 60Hz.
56  COALESCE(MAX(expected.dur), 16600000) AS dur_expected,
57  COUNT(DISTINCT timeline.layer_name) as number_of_layers_for_frame,
58  -- we use MAX to get at least one of the frame's layer names
59  MAX(timeline.layer_name) as frame_layer_name
60FROM android_jank_cuj_vsync_boundary boundary
61JOIN actual_timeline_with_vsync timeline
62  ON boundary.upid = timeline.upid
63    AND vsync >= vsync_min
64    AND vsync <= vsync_max
65LEFT JOIN expected_frame_timeline_slice expected
66  ON expected.upid = timeline.upid AND expected.name = timeline.name
67LEFT JOIN vsync_missed_callback missed_callback USING(vsync)
68WHERE
69  boundary.layer_id IS NULL
70  OR (
71    timeline.layer_name GLOB '*#*'
72    AND boundary.layer_id
73      = CAST(STR_SPLIT(timeline.layer_name, '#', 1) AS INTEGER))
74GROUP BY cuj_id, vsync;
75
76DROP TABLE IF EXISTS android_jank_cuj_layer_name;
77CREATE TABLE android_jank_cuj_layer_name AS
78SELECT
79    cuj_id,
80    MAX(frame_layer_name) as layer_name
81FROM android_jank_cuj_frame_timeline timeline
82GROUP BY cuj_id
83-- Return only cujs where the max number of layers for all frames in the whole cuj equals 1,
84-- this is to infer the layer name if the cuj marker for layer id is not present
85HAVING MAX(number_of_layers_for_frame) = 1;
86
87-- Matches slices and boundaries to compute estimated frame boundaries across
88-- all threads. Joins with the actual timeline to figure out which frames missed
89-- the deadline and whether the app process or SF are at fault.
90DROP TABLE IF EXISTS android_jank_cuj_frame;
91CREATE TABLE android_jank_cuj_frame AS
92WITH frame_base AS (
93  SELECT
94    cuj_id,
95    ROW_NUMBER() OVER (PARTITION BY cuj_id ORDER BY do_frame.vsync ASC) AS frame_number,
96    vsync,
97    boundary.ts,
98    boundary.ts_expected,
99    boundary.ts_do_frame_start,
100    COUNT(fence_idx) AS gpu_fence_count,
101    COUNT(fence_idx) > 0 AS drew_anything
102  FROM android_jank_cuj_do_frame_slice do_frame
103  JOIN android_jank_cuj_main_thread_frame_boundary boundary USING (cuj_id, vsync)
104  JOIN android_jank_cuj_draw_frame_slice draw_frame USING (cuj_id, vsync)
105  LEFT JOIN android_jank_cuj_gpu_completion_fence fence USING (cuj_id, vsync)
106  WHERE draw_frame.id = fence.draw_frame_slice_id
107  GROUP BY cuj_id, vsync, boundary.ts, boundary.ts_do_frame_start
108)
109SELECT
110  frame_base.*,
111  app_missed,
112  sf_missed,
113  sf_callback_missed,
114  hwui_callback_missed,
115  on_time_finish,
116  ts_end_actual - ts AS dur,
117  ts_end_actual - ts_do_frame_start AS dur_unadjusted,
118  dur_expected,
119  ts_end_actual AS ts_end
120FROM frame_base
121JOIN android_jank_cuj_frame_timeline USING (cuj_id, vsync);
122
123-- Similar to `android_jank_cuj_frame` computes overall SF frame boundaries.
124-- The computation is somewhat simpler as most of SF work happens within the duration of
125-- the commit/composite slices on the main thread.
126DROP TABLE IF EXISTS android_jank_cuj_sf_frame;
127CREATE TABLE android_jank_cuj_sf_frame AS
128SELECT
129  cuj_id,
130  ROW_NUMBER() OVER (PARTITION BY cuj_id ORDER BY vsync ASC) AS frame_number,
131  vsync,
132  boundary.ts,
133  boundary.ts_main_thread_start,
134  boundary.ts_end,
135  boundary.dur,
136  actual_timeline.jank_tag = 'Self Jank' AS sf_missed,
137  NULL AS app_missed, -- for simplicity align schema with android_jank_cuj_frame
138  jank_tag,
139  jank_type,
140  prediction_type,
141  present_type,
142  gpu_composition,
143  -- In case expected timeline is missing, as a fallback we use the typical frame deadline
144  -- for 60Hz.
145  -- See similar expression in android_jank_cuj_frame_timeline.
146  COALESCE(expected_timeline.dur, 16600000) AS dur_expected
147FROM android_jank_cuj_sf_main_thread_frame_boundary boundary
148JOIN android_jank_cuj_sf_process sf_process
149JOIN actual_frame_timeline_slice actual_timeline
150  ON actual_timeline.upid = sf_process.upid
151    AND boundary.vsync = CAST(actual_timeline.name AS INTEGER)
152LEFT JOIN expected_frame_timeline_slice expected_timeline
153  ON expected_timeline.upid = actual_timeline.upid
154    AND expected_timeline.name = actual_timeline.name;
155