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 android.annotation.IntDef; 20 import android.view.Window; 21 22 import java.lang.annotation.Retention; 23 import java.lang.annotation.RetentionPolicy; 24 25 /** 26 * Class containing timing data for various milestones in a frame 27 * lifecycle reported by the rendering subsystem. 28 * <p> 29 * Supported metrics can be queried via their corresponding identifier. 30 * </p> 31 */ 32 public final class FrameMetrics { 33 34 /** 35 * Metric identifier for unknown delay. 36 * <p> 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. 40 * </p> 41 */ 42 public static final int UNKNOWN_DELAY_DURATION = 0; 43 44 /** 45 * Metric identifier for input handling duration. 46 * <p> 47 * Represents the number of nanoseconds elapsed issuing 48 * input handling callbacks. 49 * </p> 50 */ 51 public static final int INPUT_HANDLING_DURATION = 1; 52 53 /** 54 * Metric identifier for animation callback duration. 55 * <p> 56 * Represents the number of nanoseconds elapsed issuing 57 * animation callbacks. 58 * </p> 59 */ 60 public static final int ANIMATION_DURATION = 2; 61 62 /** 63 * Metric identifier for layout/measure duration. 64 * <p> 65 * Represents the number of nanoseconds elapsed measuring 66 * and laying out the invalidated pieces of the view hierarchy. 67 * </p> 68 */ 69 public static final int LAYOUT_MEASURE_DURATION = 3; 70 /** 71 * Metric identifier for draw duration. 72 * <p> 73 * Represents the number of nanoseconds elapsed computing 74 * DisplayLists for transformations applied to the view 75 * hierarchy. 76 * </p> 77 */ 78 public static final int DRAW_DURATION = 4; 79 80 /** 81 * Metric identifier for sync duration. 82 * <p> 83 * Represents the number of nanoseconds elapsed 84 * synchronizing the computed display lists with the render 85 * thread. 86 * </p> 87 */ 88 public static final int SYNC_DURATION = 5; 89 90 /** 91 * Metric identifier for command issue duration. 92 * <p> 93 * Represents the number of nanoseconds elapsed 94 * issuing draw commands to the GPU. 95 * </p> 96 */ 97 public static final int COMMAND_ISSUE_DURATION = 6; 98 99 /** 100 * Metric identifier for swap buffers duration. 101 * <p> 102 * Represents the number of nanoseconds elapsed issuing 103 * the frame buffer for this frame to the display 104 * subsystem. 105 * </p> 106 */ 107 public static final int SWAP_BUFFERS_DURATION = 7; 108 109 /** 110 * Metric identifier for total frame duration. 111 * <p> 112 * Represents the total time in nanoseconds this frame took to render 113 * and be issued to the display subsystem. 114 * </p> 115 * <p> 116 * Equal to the sum of the values of all other time-valued metric 117 * identifiers. 118 * </p> 119 */ 120 public static final int TOTAL_DURATION = 8; 121 122 /** 123 * Metric identifier for a boolean value determining whether this frame was 124 * the first to draw in a new Window layout. 125 * <p> 126 * {@link #getMetric(int)} will return 0 for false, 1 for true. 127 * </p> 128 * <p> 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. 132 * </p> 133 */ 134 public static final int FIRST_DRAW_FRAME = 9; 135 136 private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0; 137 138 /** 139 * Identifiers for metrics available for each frame. 140 * 141 * {@see {@link #getMetric(int)}} 142 * @hide 143 */ 144 @IntDef({ 145 UNKNOWN_DELAY_DURATION, 146 INPUT_HANDLING_DURATION, 147 ANIMATION_DURATION, 148 LAYOUT_MEASURE_DURATION, 149 DRAW_DURATION, 150 SYNC_DURATION, 151 COMMAND_ISSUE_DURATION, 152 SWAP_BUFFERS_DURATION, 153 TOTAL_DURATION, 154 FIRST_DRAW_FRAME, 155 }) 156 @Retention(RetentionPolicy.SOURCE) 157 public @interface Metric {} 158 159 /** 160 * Timestamp indices for frame milestones. 161 * 162 * May change from release to release. 163 * 164 * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h. 165 * 166 * @hide 167 */ 168 @IntDef ({ 169 Index.FLAGS, 170 Index.INTENDED_VSYNC, 171 Index.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, 177 Index.DRAW_START, 178 Index.SYNC_QUEUED, 179 Index.SYNC_START, 180 Index.ISSUE_DRAW_COMMANDS_START, 181 Index.SWAP_BUFFERS, 182 Index.FRAME_COMPLETED, 183 }) 184 @Retention(RetentionPolicy.SOURCE) 185 private @interface Index { 186 int FLAGS = 0; 187 int INTENDED_VSYNC = 1; 188 int VSYNC = 2; 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; 194 int DRAW_START = 8; 195 int SYNC_QUEUED = 9; 196 int SYNC_START = 10; 197 int ISSUE_DRAW_COMMANDS_START = 11; 198 int SWAP_BUFFERS = 12; 199 int FRAME_COMPLETED = 13; 200 201 int FRAME_STATS_COUNT = 14; // must always be last 202 } 203 204 /* 205 * Bucket endpoints for each Metric defined above. 206 * 207 * Each defined metric *must* have a corresponding entry 208 * in this list. 209 */ 210 private static final int[] DURATIONS = new int[] { 211 // UNKNOWN_DELAY 212 Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START, 213 // INPUT_HANDLING 214 Index.HANDLE_INPUT_START, Index.ANIMATION_START, 215 // ANIMATION 216 Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START, 217 // LAYOUT_MEASURE 218 Index.PERFORM_TRAVERSALS_START, Index.DRAW_START, 219 // DRAW 220 Index.DRAW_START, Index.SYNC_QUEUED, 221 // SYNC 222 Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START, 223 // COMMAND_ISSUE 224 Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS, 225 // SWAP_BUFFERS 226 Index.SWAP_BUFFERS, Index.FRAME_COMPLETED, 227 // TOTAL_DURATION 228 Index.INTENDED_VSYNC, Index.FRAME_COMPLETED, 229 }; 230 231 /* package */ final long[] mTimingData; 232 233 /** 234 * Constructs a FrameMetrics object as a copy. 235 * <p> 236 * Use this method to copy out metrics reported by 237 * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable( 238 * Window, FrameMetrics, int)} 239 * </p> 240 * @param other the FrameMetrics object to copy. 241 */ 242 public FrameMetrics(FrameMetrics other) { 243 mTimingData = new long[Index.FRAME_STATS_COUNT]; 244 System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length); 245 } 246 247 /** 248 * @hide 249 */ 250 FrameMetrics() { 251 mTimingData = new long[Index.FRAME_STATS_COUNT]; 252 } 253 254 /** 255 * Retrieves the value associated with Metric identifier {@code id} 256 * for this frame. 257 * <p> 258 * Boolean metrics are represented in [0,1], with 0 corresponding to 259 * false, and 1 corresponding to true. 260 * </p> 261 * @param id the metric to retrieve 262 * @return the value of the metric or -1 if it is not available. 263 */ 264 public long getMetric(@Metric int id) { 265 if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) { 266 return -1; 267 } 268 269 if (mTimingData == null) { 270 return -1; 271 } 272 273 if (id == FIRST_DRAW_FRAME) { 274 return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0; 275 } 276 277 int durationsIdx = 2 * id; 278 return mTimingData[DURATIONS[durationsIdx + 1]] 279 - mTimingData[DURATIONS[durationsIdx]]; 280 } 281 } 282 283