• 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      * The total duration is the difference in time between when the frame
120      * began and when it ended. This value may not be exactly equal to the
121      * sum of the values of all other time-valued metric identifiers because
122      * some stages may happen concurrently.
123      * </p>
124      */
125     public static final int TOTAL_DURATION = 8;
126 
127     /**
128      * Metric identifier for a boolean value determining whether this frame was
129      * the first to draw in a new Window layout.
130      * <p>
131      * {@link #getMetric(int)} will return 0 for false, 1 for true.
132      * </p>
133      * <p>
134      * First draw frames are expected to be slow and should usually be exempt
135      * from display jank calculations as they do not cause skips in animations
136      * and are usually hidden by window animations or other tricks.
137      * </p>
138      */
139     public static final int FIRST_DRAW_FRAME = 9;
140 
141     /**
142      * Metric identifier for the timestamp of the intended vsync for this frame.
143      * <p>
144      * The intended start point for the frame. If this value is different from
145      * {@link #VSYNC_TIMESTAMP}, there was work occurring on the UI thread that
146      * prevented it from responding to the vsync signal in a timely fashion.
147      * </p>
148      */
149     public static final int INTENDED_VSYNC_TIMESTAMP = 10;
150 
151     /**
152      * Metric identifier for the timestamp of the actual vsync for this frame.
153      * <p>
154      * The time value that was used in all the vsync listeners and drawing for
155      * the frame (Choreographer frame callbacks, animations,
156      * {@link View#getDrawingTime()}, etc.)
157      * </p>
158      */
159     public static final int VSYNC_TIMESTAMP = 11;
160 
161     /**
162      * Metric identifier for GPU duration.
163      * <p>
164      * Represents the total time in nanoseconds this frame took to complete on the GPU.
165      * </p>
166      **/
167     public static final int GPU_DURATION = 12;
168 
169     /**
170      * Metric identifier for the total duration that was available to the app to produce a frame.
171      * <p>
172      * Represents the total time in nanoseconds the system allocated for the app to produce its
173      * frame. If FrameMetrics.TOTAL_DURATION < FrameMetrics.DEADLINE, the app hit its intended
174      * deadline and there was no jank visible to the user.
175      * </p>
176      **/
177     public static final int DEADLINE = 13;
178 
179     /**
180      * Identifiers for metrics available for each frame.
181      *
182      * {@see #getMetric(int)}
183      * @hide
184      */
185     @IntDef({
186             UNKNOWN_DELAY_DURATION,
187             INPUT_HANDLING_DURATION,
188             ANIMATION_DURATION,
189             LAYOUT_MEASURE_DURATION,
190             DRAW_DURATION,
191             SYNC_DURATION,
192             COMMAND_ISSUE_DURATION,
193             SWAP_BUFFERS_DURATION,
194             TOTAL_DURATION,
195             FIRST_DRAW_FRAME,
196             INTENDED_VSYNC_TIMESTAMP,
197             VSYNC_TIMESTAMP,
198             GPU_DURATION,
199             DEADLINE,
200     })
201     @Retention(RetentionPolicy.SOURCE)
202     public @interface Metric {}
203 
204     /**
205      * Timestamp indices for frame milestones.
206      *
207      * May change from release to release.
208      *
209      * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
210      *
211      * @hide
212      */
213     @IntDef ({
214             Index.FLAGS,
215             Index.FRAME_TIMELINE_VSYNC_ID,
216             Index.INTENDED_VSYNC,
217             Index.VSYNC,
218             Index.INPUT_EVENT_ID,
219             Index.HANDLE_INPUT_START,
220             Index.ANIMATION_START,
221             Index.PERFORM_TRAVERSALS_START,
222             Index.DRAW_START,
223             Index.FRAME_DEADLINE,
224             Index.SYNC_QUEUED,
225             Index.SYNC_START,
226             Index.ISSUE_DRAW_COMMANDS_START,
227             Index.SWAP_BUFFERS,
228             Index.FRAME_COMPLETED,
229             Index.DEQUEUE_BUFFER_DURATION,
230             Index.QUEUE_BUFFER_DURATION,
231             Index.GPU_COMPLETED,
232             Index.SWAP_BUFFERS_COMPLETED,
233             Index.DISPLAY_PRESENT_TIME,
234     })
235     @Retention(RetentionPolicy.SOURCE)
236     public @interface Index {
237         int FLAGS = 0;
238         int FRAME_TIMELINE_VSYNC_ID = 1;
239         int INTENDED_VSYNC = 2;
240         int VSYNC = 3;
241         int INPUT_EVENT_ID = 4;
242         int HANDLE_INPUT_START = 5;
243         int ANIMATION_START = 6;
244         int PERFORM_TRAVERSALS_START = 7;
245         int DRAW_START = 8;
246         int FRAME_DEADLINE = 9;
247         int FRAME_START_TIME = 10;
248         int FRAME_INTERVAL = 11;
249         int SYNC_QUEUED = 12;
250         int SYNC_START = 13;
251         int ISSUE_DRAW_COMMANDS_START = 14;
252         int SWAP_BUFFERS = 15;
253         int FRAME_COMPLETED = 16;
254         int DEQUEUE_BUFFER_DURATION = 17;
255         int QUEUE_BUFFER_DURATION = 18;
256         int GPU_COMPLETED = 19;
257         int SWAP_BUFFERS_COMPLETED = 20;
258         int DISPLAY_PRESENT_TIME = 21;
259         int COMMAND_SUBMISSION_COMPLETED = 22;
260 
261         int FRAME_STATS_COUNT = 23; // must always be last and in sync with
262                                     // FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
263     }
264 
265     /*
266      * Bucket endpoints for each Metric defined above.
267      *
268      * Each defined metric *must* have a corresponding entry
269      * in this list.
270      */
271     private static final int[] DURATIONS = new int[] {
272         // UNKNOWN_DELAY
273         Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
274         // INPUT_HANDLING
275         Index.HANDLE_INPUT_START, Index.ANIMATION_START,
276         // ANIMATION
277         Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
278         // LAYOUT_MEASURE
279         Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
280         // DRAW
281         Index.DRAW_START, Index.SYNC_QUEUED,
282         // SYNC
283         Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
284         // COMMAND_ISSUE
285         Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
286         // SWAP_BUFFERS
287         Index.SWAP_BUFFERS, Index.SWAP_BUFFERS_COMPLETED,
288         // TOTAL_DURATION
289         Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
290         // RESERVED for FIRST_DRAW_FRAME
291         0, 0,
292         // RESERVED forINTENDED_VSYNC_TIMESTAMP
293         0, 0,
294         // RESERVED VSYNC_TIMESTAMP
295         0, 0,
296         // GPU_DURATION
297         Index.COMMAND_SUBMISSION_COMPLETED, Index.GPU_COMPLETED,
298         // DEADLINE
299         Index.INTENDED_VSYNC, Index.FRAME_DEADLINE,
300     };
301 
302     /**
303      * @hide
304      */
305     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
306     public final long[] mTimingData;
307 
308     /**
309      * Constructs a FrameMetrics object as a copy.
310      * <p>
311      * Use this method to copy out metrics reported by
312      * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable(
313      * Window, FrameMetrics, int)}
314      * </p>
315      * @param other the FrameMetrics object to copy.
316      */
FrameMetrics(FrameMetrics other)317     public FrameMetrics(FrameMetrics other) {
318         mTimingData = new long[Index.FRAME_STATS_COUNT];
319         System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
320     }
321 
322     /**
323      * @hide
324      */
FrameMetrics()325     public FrameMetrics() {
326         mTimingData = new long[Index.FRAME_STATS_COUNT];
327     }
328 
329     /**
330      * Retrieves the value associated with Metric identifier {@code id}
331      * for this frame.
332      * <p>
333      * Boolean metrics are represented in [0,1], with 0 corresponding to
334      * false, and 1 corresponding to true.
335      * </p>
336      * @param id the metric to retrieve
337      * @return the value of the metric or -1 if it is not available.
338      */
getMetric(@etric int id)339     public long getMetric(@Metric int id) {
340         if (id < UNKNOWN_DELAY_DURATION || id > DEADLINE) {
341             return -1;
342         }
343 
344         if (mTimingData == null) {
345             return -1;
346         }
347 
348         if (id == FIRST_DRAW_FRAME) {
349             return (mTimingData[Index.FLAGS] & FLAG_WINDOW_VISIBILITY_CHANGED) != 0 ? 1 : 0;
350         } else if (id == INTENDED_VSYNC_TIMESTAMP) {
351             return mTimingData[Index.INTENDED_VSYNC];
352         } else if (id == VSYNC_TIMESTAMP) {
353             return mTimingData[Index.VSYNC];
354         }
355 
356         int durationsIdx = 2 * id;
357         return mTimingData[DURATIONS[durationsIdx + 1]]
358                 - mTimingData[DURATIONS[durationsIdx]];
359     }
360 }
361 
362