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