diff options
Diffstat (limited to 'services/surfaceflinger/DispSync.cpp')
-rw-r--r-- | services/surfaceflinger/DispSync.cpp | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index 3738a55..192d746 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -21,6 +21,7 @@ #include <math.h> +#include <cutils/iosched_policy.h> #include <cutils/log.h> #include <ui/Fence.h> @@ -56,15 +57,17 @@ public: mStop(false), mPeriod(0), mPhase(0), + mReferenceTime(0), mWakeupLatency(0) { } virtual ~DispSyncThread() {} - void updateModel(nsecs_t period, nsecs_t phase) { + void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) { Mutex::Autolock lock(mMutex); mPeriod = period; mPhase = phase; + mReferenceTime = referenceTime; mCond.signal(); } @@ -246,7 +249,7 @@ private: ref = lastEventTime; } - nsecs_t phase = mPhase + listener.mPhase; + nsecs_t phase = mReferenceTime + mPhase + listener.mPhase; nsecs_t t = (((ref - phase) / mPeriod) + 1) * mPeriod + phase; if (t - listener.mLastEventTime < mPeriod / 2) { @@ -266,6 +269,7 @@ private: nsecs_t mPeriod; nsecs_t mPhase; + nsecs_t mReferenceTime; nsecs_t mWakeupLatency; Vector<EventListener> mEventListeners; @@ -292,6 +296,7 @@ DispSync::DispSync() : mThread(new DispSyncThread()) { mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); + android_set_rt_ioprio(mThread->getTid(), 1); reset(); beginResync(); @@ -313,6 +318,9 @@ DispSync::~DispSync() {} void DispSync::reset() { Mutex::Autolock lock(mMutex); + mPhase = 0; + mReferenceTime = 0; + mModelUpdated = false; mNumResyncSamples = 0; mFirstResyncSample = 0; mNumResyncSamplesSincePresent = 0; @@ -340,12 +348,13 @@ bool DispSync::addPresentFence(const sp<Fence>& fence) { updateErrorLocked(); - return mPeriod == 0 || mError > kErrorThreshold; + return !mModelUpdated || mError > kErrorThreshold; } void DispSync::beginResync() { Mutex::Autolock lock(mMutex); + mModelUpdated = false; mNumResyncSamples = 0; } @@ -354,6 +363,10 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES; mResyncSamples[idx] = timestamp; + if (mNumResyncSamples == 0) { + mPhase = 0; + mReferenceTime = timestamp; + } if (mNumResyncSamples < MAX_RESYNC_SAMPLES) { mNumResyncSamples++; @@ -376,7 +389,7 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { return mThread->hasAnyEventListeners(); } - return mPeriod == 0 || mError > kErrorThreshold; + return !mModelUpdated || mError > kErrorThreshold; } void DispSync::endResync() { @@ -405,7 +418,8 @@ void DispSync::setPeriod(nsecs_t period) { Mutex::Autolock lock(mMutex); mPeriod = period; mPhase = 0; - mThread->updateModel(mPeriod, mPhase); + mReferenceTime = 0; + mThread->updateModel(mPeriod, mPhase, mReferenceTime); } nsecs_t DispSync::getPeriod() { @@ -430,7 +444,7 @@ void DispSync::updateModelLocked() { double scale = 2.0 * M_PI / double(mPeriod); for (size_t i = 0; i < mNumResyncSamples; i++) { size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES; - nsecs_t sample = mResyncSamples[idx]; + nsecs_t sample = mResyncSamples[idx] - mReferenceTime; double samplePhase = double(sample % mPeriod) * scale; sampleAvgX += cos(samplePhase); sampleAvgY += sin(samplePhase); @@ -453,12 +467,13 @@ void DispSync::updateModelLocked() { // Artificially inflate the period if requested. mPeriod += mPeriod * mRefreshSkipCount; - mThread->updateModel(mPeriod, mPhase); + mThread->updateModel(mPeriod, mPhase, mReferenceTime); + mModelUpdated = true; } } void DispSync::updateErrorLocked() { - if (mPeriod == 0) { + if (!mModelUpdated) { return; } @@ -470,7 +485,7 @@ void DispSync::updateErrorLocked() { nsecs_t sqErrSum = 0; for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) { - nsecs_t sample = mPresentTimes[i]; + nsecs_t sample = mPresentTimes[i] - mReferenceTime; if (sample > mPhase) { nsecs_t sampleErr = (sample - mPhase) % period; if (sampleErr > period / 2) { @@ -504,7 +519,8 @@ void DispSync::resetErrorLocked() { nsecs_t DispSync::computeNextRefresh(int periodOffset) const { Mutex::Autolock lock(mMutex); nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - return (((now - mPhase) / mPeriod) + periodOffset + 1) * mPeriod + mPhase; + nsecs_t phase = mReferenceTime + mPhase; + return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase; } void DispSync::dump(String8& result) const { |