1 /* 2 * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage; 20 import android.os.Build; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 /** 25 * This class contains window content frame statistics. For example, a window content 26 * is rendred in frames when a view is scrolled. The frame statistics are a snapshot 27 * for the time interval from {@link #getStartTimeNano()} to {@link #getEndTimeNano()}. 28 * <p> 29 * The key idea is that in order to provide a smooth user experience an application 30 * has to draw a frame at a specific time interval obtained by calling {@link 31 * #getRefreshPeriodNano()}. If the application does not render a frame every refresh 32 * period the user will see irregular UI transitions. 33 * </p> 34 * <p> 35 * An application posts a frame for presentation by synchronously rendering its contents 36 * in a buffer which is then posted or posting a buffer to which the application is 37 * asychronously rendering the content via GL. After the frame is posted and rendered 38 * (potentially asynchronosly) it is presented to the user. The time a frame was posted 39 * can be obtained via {@link #getFramePostedTimeNano(int)}, the time a frame content 40 * was rendered and ready for dsiplay (GL case) via {@link #getFrameReadyTimeNano(int)}, 41 * and the time a frame was presented on the screen via {@link #getFramePresentedTimeNano(int)}. 42 * </p> 43 */ 44 public final class WindowContentFrameStats extends FrameStats implements Parcelable { 45 private long[] mFramesPostedTimeNano; 46 private long[] mFramesReadyTimeNano; 47 48 /** 49 * @hide 50 */ WindowContentFrameStats()51 public WindowContentFrameStats() { 52 /* do nothing */ 53 } 54 55 /** 56 * Initializes this isntance. 57 * 58 * @param refreshPeriodNano The display refresh period. 59 * @param framesPostedTimeNano The times in milliseconds for when the frame contents were posted. 60 * @param framesPresentedTimeNano The times in milliseconds for when the frame contents were presented. 61 * @param framesReadyTimeNano The times in milliseconds for when the frame contents were ready to be presented. 62 * 63 * @hide 64 */ 65 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) init(long refreshPeriodNano, long[] framesPostedTimeNano, long[] framesPresentedTimeNano, long[] framesReadyTimeNano)66 public void init(long refreshPeriodNano, long[] framesPostedTimeNano, 67 long[] framesPresentedTimeNano, long[] framesReadyTimeNano) { 68 mRefreshPeriodNano = refreshPeriodNano; 69 mFramesPostedTimeNano = framesPostedTimeNano; 70 mFramesPresentedTimeNano = framesPresentedTimeNano; 71 mFramesReadyTimeNano = framesReadyTimeNano; 72 } 73 WindowContentFrameStats(Parcel parcel)74 private WindowContentFrameStats(Parcel parcel) { 75 mRefreshPeriodNano = parcel.readLong(); 76 mFramesPostedTimeNano = parcel.createLongArray(); 77 mFramesPresentedTimeNano = parcel.createLongArray(); 78 mFramesReadyTimeNano = parcel.createLongArray(); 79 } 80 81 /** 82 * Get the time a frame at a given index was posted by the producer (e.g. the application). 83 * It is either explicitly set or defaulted to the time when the render buffer was posted. 84 * <p> 85 * <strong>Note:</strong> A frame can be posted and still it contents being rendered 86 * asynchronously in GL. To get the time the frame content was completely rendered and 87 * ready to display call {@link #getFrameReadyTimeNano(int)}. 88 * </p> 89 * 90 * @param index The frame index. 91 * @return The posted time in nanoseconds. 92 */ getFramePostedTimeNano(int index)93 public long getFramePostedTimeNano(int index) { 94 if (mFramesPostedTimeNano == null) { 95 throw new IndexOutOfBoundsException(); 96 } 97 return mFramesPostedTimeNano[index]; 98 } 99 100 /** 101 * Get the time a frame at a given index was ready for presentation. 102 * <p> 103 * <strong>Note:</strong> A frame can be posted and still it contents being rendered 104 * asynchronously in GL. In such a case this is the time when the frame contents were 105 * completely rendered. 106 * </p> 107 * 108 * @param index The frame index. 109 * @return The ready time in nanoseconds or {@link #UNDEFINED_TIME_NANO} 110 * if the frame is not ready yet. 111 */ getFrameReadyTimeNano(int index)112 public long getFrameReadyTimeNano(int index) { 113 if (mFramesReadyTimeNano == null) { 114 throw new IndexOutOfBoundsException(); 115 } 116 return mFramesReadyTimeNano[index]; 117 } 118 119 @Override describeContents()120 public int describeContents() { 121 return 0; 122 } 123 124 @Override writeToParcel(Parcel parcel, int flags)125 public void writeToParcel(Parcel parcel, int flags) { 126 parcel.writeLong(mRefreshPeriodNano); 127 parcel.writeLongArray(mFramesPostedTimeNano); 128 parcel.writeLongArray(mFramesPresentedTimeNano); 129 parcel.writeLongArray(mFramesReadyTimeNano); 130 } 131 132 @Override toString()133 public String toString() { 134 StringBuilder builder = new StringBuilder(); 135 builder.append("WindowContentFrameStats["); 136 builder.append("frameCount:" + getFrameCount()); 137 builder.append(", fromTimeNano:" + getStartTimeNano()); 138 builder.append(", toTimeNano:" + getEndTimeNano()); 139 builder.append(']'); 140 return builder.toString(); 141 } 142 143 public static final @android.annotation.NonNull Parcelable.Creator<WindowContentFrameStats> CREATOR = 144 new Creator<WindowContentFrameStats>() { 145 @Override 146 public WindowContentFrameStats createFromParcel(Parcel parcel) { 147 return new WindowContentFrameStats(parcel); 148 } 149 150 @Override 151 public WindowContentFrameStats[] newArray(int size) { 152 return new WindowContentFrameStats[size]; 153 } 154 }; 155 } 156