Home | History | Annotate | Download | only in surfaceflinger
      1 /*
      2  * Copyright (C) 2012 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 #ifndef ANDROID_DISPSYNC_H
     18 #define ANDROID_DISPSYNC_H
     19 
     20 #include <stddef.h>
     21 
     22 #include <utils/Mutex.h>
     23 #include <utils/Timers.h>
     24 #include <utils/RefBase.h>
     25 
     26 namespace android {
     27 
     28 class String8;
     29 class Fence;
     30 class DispSyncThread;
     31 
     32 // DispSync maintains a model of the periodic hardware-based vsync events of a
     33 // display and uses that model to execute period callbacks at specific phase
     34 // offsets from the hardware vsync events.  The model is constructed by
     35 // feeding consecutive hardware event timestamps to the DispSync object via
     36 // the addResyncSample method.
     37 //
     38 // The model is validated using timestamps from Fence objects that are passed
     39 // to the DispSync object via the addPresentFence method.  These fence
     40 // timestamps should correspond to a hardware vsync event, but they need not
     41 // be consecutive hardware vsync times.  If this method determines that the
     42 // current model accurately represents the hardware event times it will return
     43 // false to indicate that a resynchronization (via addResyncSample) is not
     44 // needed.
     45 class DispSync {
     46 
     47 public:
     48 
     49     class Callback: public virtual RefBase {
     50     public:
     51         virtual ~Callback() {};
     52         virtual void onDispSyncEvent(nsecs_t when) = 0;
     53     };
     54 
     55     explicit DispSync(const char* name);
     56     ~DispSync();
     57 
     58     // reset clears the resync samples and error value.
     59     void reset();
     60 
     61     // addPresentFence adds a fence for use in validating the current vsync
     62     // event model.  The fence need not be signaled at the time
     63     // addPresentFence is called.  When the fence does signal, its timestamp
     64     // should correspond to a hardware vsync event.  Unlike the
     65     // addResyncSample method, the timestamps of consecutive fences need not
     66     // correspond to consecutive hardware vsync events.
     67     //
     68     // This method should be called with the retire fence from each HWComposer
     69     // set call that affects the display.
     70     bool addPresentFence(const sp<Fence>& fence);
     71 
     72     // The beginResync, addResyncSample, and endResync methods are used to re-
     73     // synchronize the DispSync's model to the hardware vsync events.  The re-
     74     // synchronization process involves first calling beginResync, then
     75     // calling addResyncSample with a sequence of consecutive hardware vsync
     76     // event timestamps, and finally calling endResync when addResyncSample
     77     // indicates that no more samples are needed by returning false.
     78     //
     79     // This resynchronization process should be performed whenever the display
     80     // is turned on (i.e. once immediately after it's turned on) and whenever
     81     // addPresentFence returns true indicating that the model has drifted away
     82     // from the hardware vsync events.
     83     void beginResync();
     84     bool addResyncSample(nsecs_t timestamp);
     85     void endResync();
     86 
     87     // The setPeriod method sets the vsync event model's period to a specific
     88     // value.  This should be used to prime the model when a display is first
     89     // turned on.  It should NOT be used after that.
     90     void setPeriod(nsecs_t period);
     91 
     92     // The getPeriod method returns the current vsync period.
     93     nsecs_t getPeriod();
     94 
     95     // setRefreshSkipCount specifies an additional number of refresh
     96     // cycles to skip.  For example, on a 60Hz display, a skip count of 1
     97     // will result in events happening at 30Hz.  Default is zero.  The idea
     98     // is to sacrifice smoothness for battery life.
     99     void setRefreshSkipCount(int count);
    100 
    101     // addEventListener registers a callback to be called repeatedly at the
    102     // given phase offset from the hardware vsync events.  The callback is
    103     // called from a separate thread and it should return reasonably quickly
    104     // (i.e. within a few hundred microseconds).
    105     status_t addEventListener(const char* name, nsecs_t phase,
    106             const sp<Callback>& callback);
    107 
    108     // removeEventListener removes an already-registered event callback.  Once
    109     // this method returns that callback will no longer be called by the
    110     // DispSync object.
    111     status_t removeEventListener(const sp<Callback>& callback);
    112 
    113     // computeNextRefresh computes when the next refresh is expected to begin.
    114     // The periodOffset value can be used to move forward or backward; an
    115     // offset of zero is the next refresh, -1 is the previous refresh, 1 is
    116     // the refresh after next. etc.
    117     nsecs_t computeNextRefresh(int periodOffset) const;
    118 
    119     // dump appends human-readable debug info to the result string.
    120     void dump(String8& result) const;
    121 
    122 private:
    123 
    124     void updateModelLocked();
    125     void updateErrorLocked();
    126     void resetErrorLocked();
    127 
    128     enum { MAX_RESYNC_SAMPLES = 32 };
    129     enum { MIN_RESYNC_SAMPLES_FOR_UPDATE = 6 };
    130     enum { NUM_PRESENT_SAMPLES = 8 };
    131     enum { MAX_RESYNC_SAMPLES_WITHOUT_PRESENT = 4 };
    132 
    133     const char* const mName;
    134 
    135     // mPeriod is the computed period of the modeled vsync events in
    136     // nanoseconds.
    137     nsecs_t mPeriod;
    138 
    139     // mPhase is the phase offset of the modeled vsync events.  It is the
    140     // number of nanoseconds from time 0 to the first vsync event.
    141     nsecs_t mPhase;
    142 
    143     // mReferenceTime is the reference time of the modeled vsync events.
    144     // It is the nanosecond timestamp of the first vsync event after a resync.
    145     nsecs_t mReferenceTime;
    146 
    147     // mError is the computed model error.  It is based on the difference
    148     // between the estimated vsync event times and those observed in the
    149     // mPresentTimes array.
    150     nsecs_t mError;
    151 
    152     // Whether we have updated the vsync event model since the last resync.
    153     bool mModelUpdated;
    154 
    155     // These member variables are the state used during the resynchronization
    156     // process to store information about the hardware vsync event times used
    157     // to compute the model.
    158     nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES];
    159     size_t mFirstResyncSample;
    160     size_t mNumResyncSamples;
    161     int mNumResyncSamplesSincePresent;
    162 
    163     // These member variables store information about the present fences used
    164     // to validate the currently computed model.
    165     sp<Fence> mPresentFences[NUM_PRESENT_SAMPLES];
    166     nsecs_t mPresentTimes[NUM_PRESENT_SAMPLES];
    167     size_t mPresentSampleOffset;
    168 
    169     int mRefreshSkipCount;
    170 
    171     // mThread is the thread from which all the callbacks are called.
    172     sp<DispSyncThread> mThread;
    173 
    174     // mMutex is used to protect access to all member variables.
    175     mutable Mutex mMutex;
    176 
    177     // This is the offset from the present fence timestamps to the corresponding
    178     // vsync event.
    179     int64_t mPresentTimeOffset;
    180 
    181     // Ignore present (retire) fences if the device doesn't have support for the
    182     // sync framework
    183     bool mIgnorePresentFences;
    184 };
    185 
    186 }
    187 
    188 #endif // ANDROID_DISPSYNC_H
    189