2 * Copyright (C) 2016 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import android.annotation.IntDef;
20 import android.view.Window;
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
26 * Class containing timing data for various milestones in a frame
27 * lifecycle reported by the rendering subsystem.
29 * Supported metrics can be queried via their corresponding identifier.
32 public final class FrameMetrics {
35 * Metric identifier for unknown delay.
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.
42 public static final int UNKNOWN_DELAY_DURATION = 0;
45 * Metric identifier for input handling duration.
47 * Represents the number of nanoseconds elapsed issuing
48 * input handling callbacks.
51 public static final int INPUT_HANDLING_DURATION = 1;
54 * Metric identifier for animation callback duration.
56 * Represents the number of nanoseconds elapsed issuing
57 * animation callbacks.
60 public static final int ANIMATION_DURATION = 2;
63 * Metric identifier for layout/measure duration.
65 * Represents the number of nanoseconds elapsed measuring
66 * and laying out the invalidated pieces of the view hierarchy.
69 public static final int LAYOUT_MEASURE_DURATION = 3;
71 * Metric identifier for draw duration.
73 * Represents the number of nanoseconds elapsed computing
74 * DisplayLists for transformations applied to the view
78 public static final int DRAW_DURATION = 4;
81 * Metric identifier for sync duration.
83 * Represents the number of nanoseconds elapsed
84 * synchronizing the computed display lists with the render
88 public static final int SYNC_DURATION = 5;
91 * Metric identifier for command issue duration.
93 * Represents the number of nanoseconds elapsed
94 * issuing draw commands to the GPU.
97 public static final int COMMAND_ISSUE_DURATION = 6;
100 * Metric identifier for swap buffers duration.
102 * Represents the number of nanoseconds elapsed issuing
103 * the frame buffer for this frame to the display
107 public static final int SWAP_BUFFERS_DURATION = 7;
110 * Metric identifier for total frame duration.
112 * Represents the total time in nanoseconds this frame took to render
113 * and be issued to the display subsystem.
116 * Equal to the sum of the values of all other time-valued metric
120 public static final int TOTAL_DURATION = 8;
123 * Metric identifier for a boolean value determining whether this frame was
124 * the first to draw in a new Window layout.
126 * {@link #getMetric(int)} will return 0 for false, 1 for true.
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.
134 public static final int FIRST_DRAW_FRAME = 9;
136 private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
139 * Identifiers for metrics available for each frame.
141 * {@see {@link #getMetric(int)}}
145 UNKNOWN_DELAY_DURATION,
146 INPUT_HANDLING_DURATION,
148 LAYOUT_MEASURE_DURATION,
151 COMMAND_ISSUE_DURATION,
152 SWAP_BUFFERS_DURATION,
156 @Retention(RetentionPolicy.SOURCE)
157 public @interface Metric {}
160 * Timestamp indices for frame milestones.
162 * May change from release to release.
164 * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
170 Index.INTENDED_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,
180 Index.ISSUE_DRAW_COMMANDS_START,
182 Index.FRAME_COMPLETED,
184 @Retention(RetentionPolicy.SOURCE)
185 private @interface Index {
187 int INTENDED_VSYNC = 1;
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;
197 int ISSUE_DRAW_COMMANDS_START = 11;
198 int SWAP_BUFFERS = 12;
199 int FRAME_COMPLETED = 13;
201 int FRAME_STATS_COUNT = 16; // must always be last
205 * Bucket endpoints for each Metric defined above.
207 * Each defined metric *must* have a corresponding entry
210 private static final int[] DURATIONS = new int[] {
212 Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
214 Index.HANDLE_INPUT_START, Index.ANIMATION_START,
216 Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
218 Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
220 Index.DRAW_START, Index.SYNC_QUEUED,
222 Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
224 Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
226 Index.SWAP_BUFFERS, Index.FRAME_COMPLETED,
228 Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
231 /* package */ final long[] mTimingData;
234 * Constructs a FrameMetrics object as a copy.
236 * Use this method to copy out metrics reported by
237 * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable(
238 * Window, FrameMetrics, int)}
240 * @param other the FrameMetrics object to copy.
242 public FrameMetrics(FrameMetrics other) {
243 mTimingData = new long[Index.FRAME_STATS_COUNT];
244 System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
251 mTimingData = new long[Index.FRAME_STATS_COUNT];
255 * Retrieves the value associated with Metric identifier {@code id}
258 * Boolean metrics are represented in [0,1], with 0 corresponding to
259 * false, and 1 corresponding to true.
261 * @param id the metric to retrieve
262 * @return the value of the metric or -1 if it is not available.
264 public long getMetric(@Metric int id) {
265 if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) {
269 if (mTimingData == null) {
273 if (id == FIRST_DRAW_FRAME) {
274 return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
277 int durationsIdx = 2 * id;
278 return mTimingData[DURATIONS[durationsIdx + 1]]
279 - mTimingData[DURATIONS[durationsIdx]];