• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 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
16INCLUDE PERFETTO MODULE time.conversion;
17INCLUDE PERFETTO MODULE android.frames.timeline;
18
19-- The amount by which each frame missed of hit its deadline. Positive if the
20-- deadline was not missed. Frames are considered janky if `overrun` is
21-- negative.
22-- Calculated as the difference between the end of the
23-- `expected_frame_timeline_slice` and `actual_frame_timeline_slice` for the
24-- frame.
25-- Availability: from S (API 31).
26-- For Googlers: more details in go/android-performance-metrics-glossary.
27CREATE PERFETTO TABLE android_frames_overrun(
28    -- Frame id.
29    frame_id INT,
30    -- Difference between `expected` and `actual` frame ends. Positive if frame
31    -- didn't miss deadline.
32    overrun INT
33) AS
34SELECT
35    frame_id,
36    (exp_slice.ts + exp_slice.dur) - (act_slice.ts + act_slice.dur) AS overrun
37FROM _distinct_from_actual_timeline_slice act
38JOIN _distinct_from_expected_timeline_slice exp USING (frame_id)
39JOIN slice act_slice ON (act.id = act_slice.id)
40JOIN slice exp_slice ON (exp.id = exp_slice.id);
41
42-- How much time did the frame's Choreographer callbacks take.
43CREATE PERFETTO TABLE android_frames_ui_time(
44    -- Frame id
45    frame_id INT,
46    -- UI time duration
47    ui_time INT
48) AS
49SELECT
50    frame_id,
51    dur AS ui_time
52FROM android_frames_choreographer_do_frame f
53JOIN slice USING (id);
54
55-- App Vsync delay for a frame. The time between the VSYNC-app signal and the
56-- start of Choreographer work.
57-- Calculated as time difference between the actual frame start (from
58-- `actual_frame_timeline_slice`) and start of the `Choreographer#doFrame`
59-- slice.
60-- NOTE: Sometimes because of data losses `app_vsync_delay` can be negative.
61-- The frames where it happens are filtered out.
62-- For Googlers: more details in go/android-performance-metrics-glossary.
63CREATE PERFETTO TABLE android_app_vsync_delay_per_frame(
64    -- Frame id
65    frame_id INT,
66    -- App VSYNC delay.
67    app_vsync_delay INT
68) AS
69-- As there can be multiple `DrawFrame` slices, the `frames_surface_slices`
70-- table contains multiple rows for the same `frame_id` which only differ on
71-- `draw_frame_id`. As we don't care about `draw_frame_id` we can just collapse
72-- them.
73WITH distinct_frames AS (
74    SELECT
75        frame_id,
76        do_frame_id,
77        actual_frame_timeline_id
78    FROM android_frames
79    GROUP BY 1
80)
81SELECT
82    frame_id,
83    act.ts - do_frame.ts AS app_vsync_delay
84FROM distinct_frames f
85JOIN slice act ON (f.actual_frame_timeline_id = act.id)
86JOIN slice do_frame ON (f.do_frame_id = do_frame.id)
87WHERE act.ts >= do_frame.ts;
88
89-- How much time did the frame take across the UI Thread + RenderThread.
90-- Calculated as sum of `app VSYNC delay` `Choreographer#doFrame` slice
91-- duration and summed durations of all `DrawFrame` slices associated with this
92-- frame.
93-- Availability: from N (API 24).
94-- For Googlers: more details in go/android-performance-metrics-glossary.
95CREATE PERFETTO TABLE android_cpu_time_per_frame(
96    -- Frame id
97    frame_id INT,
98    -- Difference between actual timeline of the frame and
99    -- `Choreographer#doFrame`. See `android_app_vsync_delay_per_frame` table for more details.
100    app_vsync_delay INT,
101    -- Duration of `Choreographer#doFrame` slice.
102    do_frame_dur INT,
103    -- Duration of `DrawFrame` slice. Summed duration of all `DrawFrame`
104    -- slices, if more than one. See `android_frames_draw_frame` for more details.
105    draw_frame_dur INT,
106    -- CPU time across the UI Thread + RenderThread.
107    cpu_time INT
108) AS
109WITH all_draw_frames AS (
110SELECT
111    frame_id,
112    SUM(dur) as draw_frame_dur
113FROM android_frames_draw_frame
114JOIN slice USING (id)
115GROUP BY frame_id
116),
117distinct_frames AS (
118    SELECT
119        frame_id,
120        do_frame_id,
121        actual_frame_timeline_id
122    FROM android_frames
123    GROUP BY 1
124)
125SELECT
126    frame_id,
127    app_vsync_delay,
128    do_frame.dur AS do_frame_dur,
129    draw_frame_dur,
130    app_vsync_delay + do_frame.dur + draw_frame_dur AS cpu_time
131FROM android_app_vsync_delay_per_frame
132JOIN all_draw_frames USING (frame_id)
133JOIN distinct_frames f USING (frame_id)
134JOIN slice do_frame ON (f.do_frame_id = do_frame.id);
135
136-- CPU time of frames which don't have `android_cpu_time_per_frame` available.
137-- Calculated as UI time of the frame + 5ms.
138-- For Googlers: more details in go/android-performance-metrics-glossary.
139CREATE PERFETTO TABLE _cpu_time_per_frame_fallback(
140    -- Frame id.
141    frame_id INT,
142    -- Estimated cpu time.
143    estimated_cpu_time INT
144) AS
145SELECT
146    frame_id,
147    ui_time + time_from_ms(5) AS estimated_cpu_time
148FROM android_frames_ui_time;
149
150CREATE PERFETTO TABLE _estimated_cpu_time_per_frame(
151    frame_id INT,
152    cpu_time INT
153) AS
154SELECT
155    frame_id,
156    IIF(r.cpu_time IS NULL, f.estimated_cpu_time, r.cpu_time) AS cpu_time
157FROM _cpu_time_per_frame_fallback f
158LEFT JOIN android_cpu_time_per_frame r USING (frame_id);
159
160-- Aggregated stats of the frame.
161--
162-- For Googlers: more details in go/android-performance-metrics-glossary.
163CREATE PERFETTO TABLE android_frame_stats(
164    -- Frame id.
165    frame_id INT,
166    -- The amount by which each frame missed of hit its deadline. See
167    -- `android_frames_overrun` for details.
168    overrun INT,
169    -- How much time did the frame take across the UI Thread + RenderThread.
170    cpu_time INT,
171    -- How much time did the frame's Choreographer callbacks take.
172    ui_time INT,
173    -- Was frame janky.
174    was_jank BOOL,
175    -- CPU time of the frame took over 20ms.
176    was_slow_frame BOOL,
177    -- CPU time of the frame took over 50ms.
178    was_big_jank BOOL,
179    -- CPU time of the frame took over 200ms.
180    was_huge_jank BOOL
181) AS
182SELECT
183    frame_id,
184    overrun,
185    cpu_time,
186    ui_time,
187    IIF(overrun < 0, 1, NULL) AS was_jank,
188    IIF(cpu_time > time_from_ms(20), 1, NULL) AS was_slow_frame,
189    IIF(cpu_time > time_from_ms(50), 1, NULL) AS was_big_jank,
190    IIF(cpu_time > time_from_ms(200), 1, NULL) AS was_huge_jank
191FROM android_frames_overrun
192JOIN android_frames_ui_time USING (frame_id)
193-- Because some frames might not have CPU time calculated properly (data loss
194-- or too old API), we will use fallback cpu time from
195-- `_cpu_time_per_frame_fallback`.
196JOIN _estimated_cpu_time_per_frame USING (frame_id);
197
198