blob: dcdef3eaa2759d29402d2834b0147eb21e49a436 [file] [log] [blame]
Andres Morales910beb82016-02-02 16:19:40 -08001/*
2 * Copyright (C) 2016 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 * http://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
17package android.view;
18
19import android.annotation.IntDef;
Mathew Inwoode5ad5982018-08-17 15:07:52 +010020import android.annotation.UnsupportedAppUsage;
Andres Morales910beb82016-02-02 16:19:40 -080021
22import java.lang.annotation.Retention;
23import java.lang.annotation.RetentionPolicy;
24
25/**
26 * Class containing timing data for various milestones in a frame
27 * lifecycle reported by the rendering subsystem.
28 * <p>
29 * Supported metrics can be queried via their corresponding identifier.
30 * </p>
31 */
32public final class FrameMetrics {
33
34 /**
35 * Metric identifier for unknown delay.
36 * <p>
37 * Represents the number of nanoseconds elapsed waiting for the
38 * UI thread to become responsive and process the frame. This
39 * should be 0 most of the time.
40 * </p>
41 */
42 public static final int UNKNOWN_DELAY_DURATION = 0;
43
44 /**
45 * Metric identifier for input handling duration.
46 * <p>
47 * Represents the number of nanoseconds elapsed issuing
48 * input handling callbacks.
49 * </p>
50 */
51 public static final int INPUT_HANDLING_DURATION = 1;
52
53 /**
54 * Metric identifier for animation callback duration.
55 * <p>
56 * Represents the number of nanoseconds elapsed issuing
57 * animation callbacks.
58 * </p>
59 */
60 public static final int ANIMATION_DURATION = 2;
61
62 /**
63 * Metric identifier for layout/measure duration.
64 * <p>
65 * Represents the number of nanoseconds elapsed measuring
66 * and laying out the invalidated pieces of the view hierarchy.
67 * </p>
68 */
69 public static final int LAYOUT_MEASURE_DURATION = 3;
70 /**
71 * Metric identifier for draw duration.
72 * <p>
73 * Represents the number of nanoseconds elapsed computing
74 * DisplayLists for transformations applied to the view
75 * hierarchy.
76 * </p>
77 */
78 public static final int DRAW_DURATION = 4;
79
80 /**
81 * Metric identifier for sync duration.
82 * <p>
83 * Represents the number of nanoseconds elapsed
84 * synchronizing the computed display lists with the render
85 * thread.
86 * </p>
87 */
88 public static final int SYNC_DURATION = 5;
89
90 /**
91 * Metric identifier for command issue duration.
92 * <p>
93 * Represents the number of nanoseconds elapsed
94 * issuing draw commands to the GPU.
95 * </p>
96 */
97 public static final int COMMAND_ISSUE_DURATION = 6;
98
99 /**
100 * Metric identifier for swap buffers duration.
101 * <p>
102 * Represents the number of nanoseconds elapsed issuing
103 * the frame buffer for this frame to the display
104 * subsystem.
105 * </p>
106 */
107 public static final int SWAP_BUFFERS_DURATION = 7;
108
109 /**
110 * Metric identifier for total frame duration.
111 * <p>
112 * Represents the total time in nanoseconds this frame took to render
113 * and be issued to the display subsystem.
114 * </p>
115 * <p>
116 * Equal to the sum of the values of all other time-valued metric
117 * identifiers.
118 * </p>
119 */
120 public static final int TOTAL_DURATION = 8;
121
122 /**
123 * Metric identifier for a boolean value determining whether this frame was
124 * the first to draw in a new Window layout.
125 * <p>
126 * {@link #getMetric(int)} will return 0 for false, 1 for true.
127 * </p>
128 * <p>
129 * First draw frames are expected to be slow and should usually be exempt
130 * from display jank calculations as they do not cause skips in animations
131 * and are usually hidden by window animations or other tricks.
132 * </p>
133 */
134 public static final int FIRST_DRAW_FRAME = 9;
135
Bryan Cassellf4c2a522017-02-22 08:09:50 -0800136 /**
137 * Metric identifier for the timestamp of the intended vsync for this frame.
138 * <p>
139 * The intended start point for the frame. If this value is different from
140 * {@link #VSYNC_TIMESTAMP}, there was work occurring on the UI thread that
141 * prevented it from responding to the vsync signal in a timely fashion.
142 * </p>
143 */
144 public static final int INTENDED_VSYNC_TIMESTAMP = 10;
145
146 /**
147 * Metric identifier for the timestamp of the actual vsync for this frame.
148 * <p>
149 * The time value that was used in all the vsync listeners and drawing for
150 * the frame (Choreographer frame callbacks, animations,
151 * {@link View#getDrawingTime()}, etc…)
152 * </p>
153 */
154 public static final int VSYNC_TIMESTAMP = 11;
155
Andres Morales910beb82016-02-02 16:19:40 -0800156 private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
157
158 /**
159 * Identifiers for metrics available for each frame.
160 *
Elliot Waite54de7742017-01-11 15:30:35 -0800161 * {@see #getMetric(int)}
Andres Morales910beb82016-02-02 16:19:40 -0800162 * @hide
163 */
164 @IntDef({
165 UNKNOWN_DELAY_DURATION,
166 INPUT_HANDLING_DURATION,
167 ANIMATION_DURATION,
168 LAYOUT_MEASURE_DURATION,
169 DRAW_DURATION,
170 SYNC_DURATION,
171 COMMAND_ISSUE_DURATION,
172 SWAP_BUFFERS_DURATION,
173 TOTAL_DURATION,
174 FIRST_DRAW_FRAME,
Bryan Cassellf4c2a522017-02-22 08:09:50 -0800175 INTENDED_VSYNC_TIMESTAMP,
176 VSYNC_TIMESTAMP,
Andres Morales910beb82016-02-02 16:19:40 -0800177 })
178 @Retention(RetentionPolicy.SOURCE)
179 public @interface Metric {}
180
181 /**
182 * Timestamp indices for frame milestones.
183 *
184 * May change from release to release.
185 *
186 * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
187 *
188 * @hide
189 */
190 @IntDef ({
191 Index.FLAGS,
192 Index.INTENDED_VSYNC,
193 Index.VSYNC,
194 Index.OLDEST_INPUT_EVENT,
195 Index.NEWEST_INPUT_EVENT,
196 Index.HANDLE_INPUT_START,
197 Index.ANIMATION_START,
198 Index.PERFORM_TRAVERSALS_START,
199 Index.DRAW_START,
200 Index.SYNC_QUEUED,
201 Index.SYNC_START,
202 Index.ISSUE_DRAW_COMMANDS_START,
203 Index.SWAP_BUFFERS,
204 Index.FRAME_COMPLETED,
205 })
206 @Retention(RetentionPolicy.SOURCE)
207 private @interface Index {
208 int FLAGS = 0;
209 int INTENDED_VSYNC = 1;
210 int VSYNC = 2;
211 int OLDEST_INPUT_EVENT = 3;
212 int NEWEST_INPUT_EVENT = 4;
213 int HANDLE_INPUT_START = 5;
214 int ANIMATION_START = 6;
215 int PERFORM_TRAVERSALS_START = 7;
216 int DRAW_START = 8;
217 int SYNC_QUEUED = 9;
218 int SYNC_START = 10;
219 int ISSUE_DRAW_COMMANDS_START = 11;
220 int SWAP_BUFFERS = 12;
221 int FRAME_COMPLETED = 13;
222
John Reck65ddb152016-08-02 09:38:26 -0700223 int FRAME_STATS_COUNT = 16; // must always be last
Andres Morales910beb82016-02-02 16:19:40 -0800224 }
225
226 /*
227 * Bucket endpoints for each Metric defined above.
228 *
229 * Each defined metric *must* have a corresponding entry
230 * in this list.
231 */
232 private static final int[] DURATIONS = new int[] {
233 // UNKNOWN_DELAY
234 Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
235 // INPUT_HANDLING
236 Index.HANDLE_INPUT_START, Index.ANIMATION_START,
237 // ANIMATION
238 Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
239 // LAYOUT_MEASURE
240 Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
241 // DRAW
242 Index.DRAW_START, Index.SYNC_QUEUED,
243 // SYNC
244 Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
245 // COMMAND_ISSUE
246 Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
247 // SWAP_BUFFERS
248 Index.SWAP_BUFFERS, Index.FRAME_COMPLETED,
249 // TOTAL_DURATION
250 Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
251 };
252
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100253 @UnsupportedAppUsage
Andres Morales910beb82016-02-02 16:19:40 -0800254 /* package */ final long[] mTimingData;
255
256 /**
257 * Constructs a FrameMetrics object as a copy.
258 * <p>
259 * Use this method to copy out metrics reported by
Andres Moralesd908c622016-04-20 13:13:34 -0700260 * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable(
261 * Window, FrameMetrics, int)}
Andres Morales910beb82016-02-02 16:19:40 -0800262 * </p>
263 * @param other the FrameMetrics object to copy.
264 */
265 public FrameMetrics(FrameMetrics other) {
266 mTimingData = new long[Index.FRAME_STATS_COUNT];
267 System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
268 }
269
270 /**
271 * @hide
272 */
273 FrameMetrics() {
274 mTimingData = new long[Index.FRAME_STATS_COUNT];
275 }
276
277 /**
278 * Retrieves the value associated with Metric identifier {@code id}
279 * for this frame.
280 * <p>
281 * Boolean metrics are represented in [0,1], with 0 corresponding to
282 * false, and 1 corresponding to true.
283 * </p>
284 * @param id the metric to retrieve
285 * @return the value of the metric or -1 if it is not available.
286 */
287 public long getMetric(@Metric int id) {
Bryan Cassellf4c2a522017-02-22 08:09:50 -0800288 if (id < UNKNOWN_DELAY_DURATION || id > VSYNC_TIMESTAMP) {
Andres Morales910beb82016-02-02 16:19:40 -0800289 return -1;
290 }
291
292 if (mTimingData == null) {
293 return -1;
294 }
295
296 if (id == FIRST_DRAW_FRAME) {
297 return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
Bryan Cassellf4c2a522017-02-22 08:09:50 -0800298 } else if (id == INTENDED_VSYNC_TIMESTAMP) {
299 return mTimingData[Index.INTENDED_VSYNC];
300 } else if (id == VSYNC_TIMESTAMP) {
301 return mTimingData[Index.VSYNC];
Andres Morales910beb82016-02-02 16:19:40 -0800302 }
303
304 int durationsIdx = 2 * id;
305 return mTimingData[DURATIONS[durationsIdx + 1]]
306 - mTimingData[DURATIONS[durationsIdx]];
307 }
308}
309