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 int COMMAND_SUBMISSION_COMPLETED = 22; 258 259 int FRAME_STATS_COUNT = 23; // must always be last and in sync with 260 // FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h 261 } 262 263 /* 264 * Bucket endpoints for each Metric defined above. 265 * 266 * Each defined metric *must* have a corresponding entry 267 * in this list. 268 */ 269 private static final int[] DURATIONS = new int[] { 270 // UNKNOWN_DELAY 271 Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START, 272 // INPUT_HANDLING 273 Index.HANDLE_INPUT_START, Index.ANIMATION_START, 274 // ANIMATION 275 Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START, 276 // LAYOUT_MEASURE 277 Index.PERFORM_TRAVERSALS_START, Index.DRAW_START, 278 // DRAW 279 Index.DRAW_START, Index.SYNC_QUEUED, 280 // SYNC 281 Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START, 282 // COMMAND_ISSUE 283 Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS, 284 // SWAP_BUFFERS 285 Index.SWAP_BUFFERS, Index.SWAP_BUFFERS_COMPLETED, 286 // TOTAL_DURATION 287 Index.INTENDED_VSYNC, Index.FRAME_COMPLETED, 288 // RESERVED for FIRST_DRAW_FRAME 289 0, 0, 290 // RESERVED forINTENDED_VSYNC_TIMESTAMP 291 0, 0, 292 // RESERVED VSYNC_TIMESTAMP 293 0, 0, 294 // GPU_DURATION 295 Index.COMMAND_SUBMISSION_COMPLETED, Index.GPU_COMPLETED, 296 // DEADLINE 297 Index.INTENDED_VSYNC, Index.FRAME_DEADLINE, 298 }; 299 300 /** 301 * @hide 302 */ 303 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 304 public final long[] mTimingData; 305 306 /** 307 * Constructs a FrameMetrics object as a copy. 308 * <p> 309 * Use this method to copy out metrics reported by 310 * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable( 311 * Window, FrameMetrics, int)} 312 * </p> 313 * @param other the FrameMetrics object to copy. 314 */ FrameMetrics(FrameMetrics other)315 public FrameMetrics(FrameMetrics other) { 316 mTimingData = new long[Index.FRAME_STATS_COUNT]; 317 System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length); 318 } 319 320 /** 321 * @hide 322 */ FrameMetrics()323 public FrameMetrics() { 324 mTimingData = new long[Index.FRAME_STATS_COUNT]; 325 } 326 327 /** 328 * Retrieves the value associated with Metric identifier {@code id} 329 * for this frame. 330 * <p> 331 * Boolean metrics are represented in [0,1], with 0 corresponding to 332 * false, and 1 corresponding to true. 333 * </p> 334 * @param id the metric to retrieve 335 * @return the value of the metric or -1 if it is not available. 336 */ getMetric(@etric int id)337 public long getMetric(@Metric int id) { 338 if (id < UNKNOWN_DELAY_DURATION || id > DEADLINE) { 339 return -1; 340 } 341 342 if (mTimingData == null) { 343 return -1; 344 } 345 346 if (id == FIRST_DRAW_FRAME) { 347 return (mTimingData[Index.FLAGS] & FLAG_WINDOW_VISIBILITY_CHANGED) != 0 ? 1 : 0; 348 } else if (id == INTENDED_VSYNC_TIMESTAMP) { 349 return mTimingData[Index.INTENDED_VSYNC]; 350 } else if (id == VSYNC_TIMESTAMP) { 351 return mTimingData[Index.VSYNC]; 352 } 353 354 int durationsIdx = 2 * id; 355 return mTimingData[DURATIONS[durationsIdx + 1]] 356 - mTimingData[DURATIONS[durationsIdx]]; 357 } 358 } 359 360