Home | History | Annotate | Download | only in view
      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