• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.view;
18 
19 import static android.graphics.FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
20 
21 import android.annotation.IntDef;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.os.Build;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 
28 /**
29  * Class containing timing data for various milestones in a frame
30  * lifecycle reported by the rendering subsystem.
31  * <p>
32  * Supported metrics can be queried via their corresponding identifier.
33  * </p>
34  */
35 public final class FrameMetrics {
36 
37     /**
38      * Metric identifier for unknown delay.
39      * <p>
40      * Represents the number of nanoseconds elapsed waiting for the
41      * UI thread to become responsive and process the frame. This
42      * should be 0 most of the time.
43      * </p>
44      */
45     public static final int UNKNOWN_DELAY_DURATION = 0;
46 
47     /**
48      * Metric identifier for input handling duration.
49      * <p>
50      * Represents the number of nanoseconds elapsed issuing
51      * input handling callbacks.
52      * </p>
53      */
54     public static final int INPUT_HANDLING_DURATION = 1;
55 
56     /**
57      * Metric identifier for animation callback duration.
58      * <p>
59      * Represents the number of nanoseconds elapsed issuing
60      * animation callbacks.
61      * </p>
62      */
63     public static final int ANIMATION_DURATION = 2;
64 
65     /**
66      * Metric identifier for layout/measure duration.
67      * <p>
68      * Represents the number of nanoseconds elapsed measuring
69      * and laying out the invalidated pieces of the view hierarchy.
70      * </p>
71      */
72     public static final int LAYOUT_MEASURE_DURATION = 3;
73     /**
74      * Metric identifier for draw duration.
75      * <p>
76      * Represents the number of nanoseconds elapsed computing
77      * DisplayLists for transformations applied to the view
78      * hierarchy.
79      * </p>
80      */
81     public static final int DRAW_DURATION = 4;
82 
83     /**
84      * Metric identifier for sync duration.
85      * <p>
86      * Represents the number of nanoseconds elapsed
87      * synchronizing the computed display lists with the render
88      * thread.
89      * </p>
90      */
91     public static final int SYNC_DURATION = 5;
92 
93     /**
94      * Metric identifier for command issue duration.
95      * <p>
96      * Represents the number of nanoseconds elapsed
97      * issuing draw commands to the GPU.
98      * </p>
99      */
100     public static final int COMMAND_ISSUE_DURATION = 6;
101 
102     /**
103      * Metric identifier for swap buffers duration.
104      * <p>
105      * Represents the number of nanoseconds elapsed issuing
106      * the frame buffer for this frame to the display
107      * subsystem.
108      * </p>
109      */
110     public static final int SWAP_BUFFERS_DURATION = 7;
111 
112     /**
113      * Metric identifier for total frame duration.
114      * <p>
115      * Represents the total time in nanoseconds this frame took to render
116      * and be issued to the display subsystem.
117      * </p>
118      * <p>
119      * Equal to the sum of the values of all other time-valued metric
120      * identifiers.
121      * </p>
122      */
123     public static final int TOTAL_DURATION = 8;
124 
125     /**
126      * Metric identifier for a boolean value determining whether this frame was
127      * the first to draw in a new Window layout.
128      * <p>
129      * {@link #getMetric(int)} will return 0 for false, 1 for true.
130      * </p>
131      * <p>
132      * First draw frames are expected to be slow and should usually be exempt
133      * from display jank calculations as they do not cause skips in animations
134      * and are usually hidden by window animations or other tricks.
135      * </p>
136      */
137     public static final int FIRST_DRAW_FRAME = 9;
138 
139     /**
140      * Metric identifier for the timestamp of the intended vsync for this frame.
141      * <p>
142      * The intended start point for the frame. If this value is different from
143      * {@link #VSYNC_TIMESTAMP}, there was work occurring on the UI thread that
144      * prevented it from responding to the vsync signal in a timely fashion.
145      * </p>
146      */
147     public static final int INTENDED_VSYNC_TIMESTAMP = 10;
148 
149     /**
150      * Metric identifier for the timestamp of the actual vsync for this frame.
151      * <p>
152      * The time value that was used in all the vsync listeners and drawing for
153      * the frame (Choreographer frame callbacks, animations,
154      * {@link View#getDrawingTime()}, etc.)
155      * </p>
156      */
157     public static final int VSYNC_TIMESTAMP = 11;
158 
159     /**
160      * Metric identifier for GPU duration.
161      * <p>
162      * Represents the total time in nanoseconds this frame took to complete on the GPU.
163      * </p>
164      **/
165     public static final int GPU_DURATION = 12;
166 
167     /**
168      * Metric identifier for the total duration that was available to the app to produce a frame.
169      * <p>
170      * Represents the total time in nanoseconds the system allocated for the app to produce its
171      * frame. If FrameMetrics.TOTAL_DURATION < FrameMetrics.DEADLINE, the app hit its intended
172      * deadline and there was no jank visible to the user.
173      * </p>
174      **/
175     public static final int DEADLINE = 13;
176 
177     /**
178      * Identifiers for metrics available for each frame.
179      *
180      * {@see #getMetric(int)}
181      * @hide
182      */
183     @IntDef({
184             UNKNOWN_DELAY_DURATION,
185             INPUT_HANDLING_DURATION,
186             ANIMATION_DURATION,
187             LAYOUT_MEASURE_DURATION,
188             DRAW_DURATION,
189             SYNC_DURATION,
190             COMMAND_ISSUE_DURATION,
191             SWAP_BUFFERS_DURATION,
192             TOTAL_DURATION,
193             FIRST_DRAW_FRAME,
194             INTENDED_VSYNC_TIMESTAMP,
195             VSYNC_TIMESTAMP,
196             GPU_DURATION,
197             DEADLINE,
198     })
199     @Retention(RetentionPolicy.SOURCE)
200     public @interface Metric {}
201 
202     /**
203      * Timestamp indices for frame milestones.
204      *
205      * May change from release to release.
206      *
207      * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
208      *
209      * @hide
210      */
211     @IntDef ({
212             Index.FLAGS,
213             Index.FRAME_TIMELINE_VSYNC_ID,
214             Index.INTENDED_VSYNC,
215             Index.VSYNC,
216             Index.INPUT_EVENT_ID,
217             Index.HANDLE_INPUT_START,
218             Index.ANIMATION_START,
219             Index.PERFORM_TRAVERSALS_START,
220             Index.DRAW_START,
221             Index.FRAME_DEADLINE,
222             Index.SYNC_QUEUED,
223             Index.SYNC_START,
224             Index.ISSUE_DRAW_COMMANDS_START,
225             Index.SWAP_BUFFERS,
226             Index.FRAME_COMPLETED,
227             Index.DEQUEUE_BUFFER_DURATION,
228             Index.QUEUE_BUFFER_DURATION,
229             Index.GPU_COMPLETED,
230             Index.SWAP_BUFFERS_COMPLETED,
231             Index.DISPLAY_PRESENT_TIME,
232     })
233     @Retention(RetentionPolicy.SOURCE)
234     public @interface Index {
235         int FLAGS = 0;
236         int FRAME_TIMELINE_VSYNC_ID = 1;
237         int INTENDED_VSYNC = 2;
238         int VSYNC = 3;
239         int INPUT_EVENT_ID = 4;
240         int HANDLE_INPUT_START = 5;
241         int ANIMATION_START = 6;
242         int PERFORM_TRAVERSALS_START = 7;
243         int DRAW_START = 8;
244         int FRAME_DEADLINE = 9;
245         int FRAME_START_TIME = 10;
246         int FRAME_INTERVAL = 11;
247         int SYNC_QUEUED = 12;
248         int SYNC_START = 13;
249         int ISSUE_DRAW_COMMANDS_START = 14;
250         int SWAP_BUFFERS = 15;
251         int FRAME_COMPLETED = 16;
252         int DEQUEUE_BUFFER_DURATION = 17;
253         int QUEUE_BUFFER_DURATION = 18;
254         int GPU_COMPLETED = 19;
255         int SWAP_BUFFERS_COMPLETED = 20;
256         int DISPLAY_PRESENT_TIME = 21;
257 
258         int FRAME_STATS_COUNT = 22; // must always be last and in sync with
259                                     // FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
260     }
261 
262     /*
263      * Bucket endpoints for each Metric defined above.
264      *
265      * Each defined metric *must* have a corresponding entry
266      * in this list.
267      */
268     private static final int[] DURATIONS = new int[] {
269         // UNKNOWN_DELAY
270         Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
271         // INPUT_HANDLING
272         Index.HANDLE_INPUT_START, Index.ANIMATION_START,
273         // ANIMATION
274         Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
275         // LAYOUT_MEASURE
276         Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
277         // DRAW
278         Index.DRAW_START, Index.SYNC_QUEUED,
279         // SYNC
280         Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
281         // COMMAND_ISSUE
282         Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
283         // SWAP_BUFFERS
284         Index.SWAP_BUFFERS, Index.SWAP_BUFFERS_COMPLETED,
285         // TOTAL_DURATION
286         Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
287         // RESERVED for FIRST_DRAW_FRAME
288         0, 0,
289         // RESERVED forINTENDED_VSYNC_TIMESTAMP
290         0, 0,
291         // RESERVED VSYNC_TIMESTAMP
292         0, 0,
293         // GPU_DURATION
294         Index.SWAP_BUFFERS, Index.GPU_COMPLETED,
295         // DEADLINE
296         Index.INTENDED_VSYNC, Index.FRAME_DEADLINE,
297     };
298 
299     /**
300      * @hide
301      */
302     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
303     public final long[] mTimingData;
304 
305     /**
306      * Constructs a FrameMetrics object as a copy.
307      * <p>
308      * Use this method to copy out metrics reported by
309      * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable(
310      * Window, FrameMetrics, int)}
311      * </p>
312      * @param other the FrameMetrics object to copy.
313      */
FrameMetrics(FrameMetrics other)314     public FrameMetrics(FrameMetrics other) {
315         mTimingData = new long[Index.FRAME_STATS_COUNT];
316         System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
317     }
318 
319     /**
320      * @hide
321      */
FrameMetrics()322     public FrameMetrics() {
323         mTimingData = new long[Index.FRAME_STATS_COUNT];
324     }
325 
326     /**
327      * Retrieves the value associated with Metric identifier {@code id}
328      * for this frame.
329      * <p>
330      * Boolean metrics are represented in [0,1], with 0 corresponding to
331      * false, and 1 corresponding to true.
332      * </p>
333      * @param id the metric to retrieve
334      * @return the value of the metric or -1 if it is not available.
335      */
getMetric(@etric int id)336     public long getMetric(@Metric int id) {
337         if (id < UNKNOWN_DELAY_DURATION || id > DEADLINE) {
338             return -1;
339         }
340 
341         if (mTimingData == null) {
342             return -1;
343         }
344 
345         if (id == FIRST_DRAW_FRAME) {
346             return (mTimingData[Index.FLAGS] & FLAG_WINDOW_VISIBILITY_CHANGED) != 0 ? 1 : 0;
347         } else if (id == INTENDED_VSYNC_TIMESTAMP) {
348             return mTimingData[Index.INTENDED_VSYNC];
349         } else if (id == VSYNC_TIMESTAMP) {
350             return mTimingData[Index.VSYNC];
351         }
352 
353         int durationsIdx = 2 * id;
354         return mTimingData[DURATIONS[durationsIdx + 1]]
355                 - mTimingData[DURATIONS[durationsIdx]];
356     }
357 }
358 
359