blob: 8e66f86f421eae73fc6546ba2b5def6e489d25dc [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;
20import android.view.Window;
21
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
136 private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
137
138 /**
139 * Identifiers for metrics available for each frame.
140 *
141 * {@see {@link #getMetric(int)}}
142 * @hide
143 */
144 @IntDef({
145 UNKNOWN_DELAY_DURATION,
146 INPUT_HANDLING_DURATION,
147 ANIMATION_DURATION,
148 LAYOUT_MEASURE_DURATION,
149 DRAW_DURATION,
150 SYNC_DURATION,
151 COMMAND_ISSUE_DURATION,
152 SWAP_BUFFERS_DURATION,
153 TOTAL_DURATION,
154 FIRST_DRAW_FRAME,
155 })
156 @Retention(RetentionPolicy.SOURCE)
157 public @interface Metric {}
158
159 /**
160 * Timestamp indices for frame milestones.
161 *
162 * May change from release to release.
163 *
164 * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
165 *
166 * @hide
167 */
168 @IntDef ({
169 Index.FLAGS,
170 Index.INTENDED_VSYNC,
171 Index.VSYNC,
172 Index.OLDEST_INPUT_EVENT,
173 Index.NEWEST_INPUT_EVENT,
174 Index.HANDLE_INPUT_START,
175 Index.ANIMATION_START,
176 Index.PERFORM_TRAVERSALS_START,
177 Index.DRAW_START,
178 Index.SYNC_QUEUED,
179 Index.SYNC_START,
180 Index.ISSUE_DRAW_COMMANDS_START,
181 Index.SWAP_BUFFERS,
182 Index.FRAME_COMPLETED,
183 })
184 @Retention(RetentionPolicy.SOURCE)
185 private @interface Index {
186 int FLAGS = 0;
187 int INTENDED_VSYNC = 1;
188 int VSYNC = 2;
189 int OLDEST_INPUT_EVENT = 3;
190 int NEWEST_INPUT_EVENT = 4;
191 int HANDLE_INPUT_START = 5;
192 int ANIMATION_START = 6;
193 int PERFORM_TRAVERSALS_START = 7;
194 int DRAW_START = 8;
195 int SYNC_QUEUED = 9;
196 int SYNC_START = 10;
197 int ISSUE_DRAW_COMMANDS_START = 11;
198 int SWAP_BUFFERS = 12;
199 int FRAME_COMPLETED = 13;
200
201 int FRAME_STATS_COUNT = 14; // must always be last
202 }
203
204 /*
205 * Bucket endpoints for each Metric defined above.
206 *
207 * Each defined metric *must* have a corresponding entry
208 * in this list.
209 */
210 private static final int[] DURATIONS = new int[] {
211 // UNKNOWN_DELAY
212 Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
213 // INPUT_HANDLING
214 Index.HANDLE_INPUT_START, Index.ANIMATION_START,
215 // ANIMATION
216 Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
217 // LAYOUT_MEASURE
218 Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
219 // DRAW
220 Index.DRAW_START, Index.SYNC_QUEUED,
221 // SYNC
222 Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
223 // COMMAND_ISSUE
224 Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
225 // SWAP_BUFFERS
226 Index.SWAP_BUFFERS, Index.FRAME_COMPLETED,
227 // TOTAL_DURATION
228 Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
229 };
230
231 /* package */ final long[] mTimingData;
232
233 /**
234 * Constructs a FrameMetrics object as a copy.
235 * <p>
236 * Use this method to copy out metrics reported by
237 * {@link Window.FrameMetricsListener#onMetricsAvailable(Window, FrameMetrics, int)}
238 * </p>
239 * @param other the FrameMetrics object to copy.
240 */
241 public FrameMetrics(FrameMetrics other) {
242 mTimingData = new long[Index.FRAME_STATS_COUNT];
243 System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
244 }
245
246 /**
247 * @hide
248 */
249 FrameMetrics() {
250 mTimingData = new long[Index.FRAME_STATS_COUNT];
251 }
252
253 /**
254 * Retrieves the value associated with Metric identifier {@code id}
255 * for this frame.
256 * <p>
257 * Boolean metrics are represented in [0,1], with 0 corresponding to
258 * false, and 1 corresponding to true.
259 * </p>
260 * @param id the metric to retrieve
261 * @return the value of the metric or -1 if it is not available.
262 */
263 public long getMetric(@Metric int id) {
264 if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) {
265 return -1;
266 }
267
268 if (mTimingData == null) {
269 return -1;
270 }
271
272 if (id == FIRST_DRAW_FRAME) {
273 return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
274 }
275
276 int durationsIdx = 2 * id;
277 return mTimingData[DURATIONS[durationsIdx + 1]]
278 - mTimingData[DURATIONS[durationsIdx]];
279 }
280}
281