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