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