• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~Callback()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