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