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     DispSync();
     56     ~DispSync();
     57 
     58     void reset();
     59 
     60     // addPresentFence adds a fence for use in validating the current vsync
     61     // event model.  The fence need not be signaled at the time
     62     // addPresentFence is called.  When the fence does signal, its timestamp
     63     // should correspond to a hardware vsync event.  Unlike the
     64     // addResyncSample method, the timestamps of consecutive fences need not
     65     // correspond to consecutive hardware vsync events.
     66     //
     67     // This method should be called with the retire fence from each HWComposer
     68     // set call that affects the display.
     69     bool addPresentFence(const sp<Fence>& fence);
     70 
     71     // The beginResync, addResyncSample, and endResync methods are used to re-
     72     // synchronize the DispSync's model to the hardware vsync events.  The re-
     73     // synchronization process involves first calling beginResync, then
     74     // calling addResyncSample with a sequence of consecutive hardware vsync
     75     // event timestamps, and finally calling endResync when addResyncSample
     76     // indicates that no more samples are needed by returning false.
     77     //
     78     // This resynchronization process should be performed whenever the display
     79     // is turned on (i.e. once immediately after it's turned on) and whenever
     80     // addPresentFence returns true indicating that the model has drifted away
     81     // from the hardware vsync events.
     82     void beginResync();
     83     bool addResyncSample(nsecs_t timestamp);
     84     void endResync();
     85 
     86     // The setPreiod method sets the vsync event model's period to a specific
     87     // value.  This should be used to prime the model when a display is first
     88     // turned on.  It should NOT be used after that.
     89     void setPeriod(nsecs_t period);
     90 
     91     // addEventListener registers a callback to be called repeatedly at the
     92     // given phase offset from the hardware vsync events.  The callback is
     93     // called from a separate thread and it should return reasonably quickly
     94     // (i.e. within a few hundred microseconds).
     95     status_t addEventListener(nsecs_t phase, const sp<Callback>& callback);
     96 
     97     // removeEventListener removes an already-registered event callback.  Once
     98     // this method returns that callback will no longer be called by the
     99     // DispSync object.
    100     status_t removeEventListener(const sp<Callback>& callback);
    101 
    102 private:
    103 
    104     void updateModelLocked();
    105     void updateErrorLocked();
    106     void resetErrorLocked();
    107 
    108     enum { MAX_RESYNC_SAMPLES = 32 };
    109     enum { MIN_RESYNC_SAMPLES_FOR_UPDATE = 3 };
    110     enum { NUM_PRESENT_SAMPLES = 8 };
    111     enum { MAX_RESYNC_SAMPLES_WITHOUT_PRESENT = 12 };
    112 
    113     // mPeriod is the computed period of the modeled vsync events in
    114     // nanoseconds.
    115     nsecs_t mPeriod;
    116 
    117     // mPhase is the phase offset of the modeled vsync events.  It is the
    118     // number of nanoseconds from time 0 to the first vsync event.
    119     nsecs_t mPhase;
    120 
    121     // mError is the computed model error.  It is based on the difference
    122     // between the estimated vsync event times and those observed in the
    123     // mPresentTimes array.
    124     nsecs_t mError;
    125 
    126     // These member variables are the state used during the resynchronization
    127     // process to store information about the hardware vsync event times used
    128     // to compute the model.
    129     nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES];
    130     size_t mFirstResyncSample;
    131     size_t mNumResyncSamples;
    132     int mNumResyncSamplesSincePresent;
    133 
    134     // These member variables store information about the present fences used
    135     // to validate the currently computed model.
    136     sp<Fence> mPresentFences[NUM_PRESENT_SAMPLES];
    137     nsecs_t mPresentTimes[NUM_PRESENT_SAMPLES];
    138     size_t mPresentSampleOffset;
    139 
    140     // mThread is the thread from which all the callbacks are called.
    141     sp<DispSyncThread> mThread;
    142 
    143     // mMutex is used to protect access to all member variables.
    144     mutable Mutex mMutex;
    145 };
    146 
    147 }
    148 
    149 #endif // ANDROID_DISPSYNC_H
    150