diff options
author | Haixia Shi <hshi@google.com> | 2015-10-28 13:22:22 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-07-20 04:16:16 -0700 |
commit | 95cda3b92faf69f2ed594ee87a7e1e7499bd0060 (patch) | |
tree | 38881e2de5e4ae432ede70ca7848488d428e01d2 | |
parent | a5761b164a27d2894f8abc0652dd8cda7326f564 (diff) | |
download | frameworks_native-95cda3b92faf69f2ed594ee87a7e1e7499bd0060.zip frameworks_native-95cda3b92faf69f2ed594ee87a7e1e7499bd0060.tar.gz frameworks_native-95cda3b92faf69f2ed594ee87a7e1e7499bd0060.tar.bz2 |
SF: use first sample timestamp as reference.
Do not use the absolute 64-bit nsecs_t timestamp directly in phase
and error calculations. Compared to the estimated vsync period, the
timestamp tend to many orders of magnitudes larger, and consequently
the integer modulo operation used to calculate phase and error can
be very sensitive to tiny fluctuation in vsync period.
Bug: 25113115
Test: set kTraceDetailedInfo=true; see Phase and Error are stable in systrace
Change-Id: I687703eec31b1072c606898c0424a96c0a8ca033
-rw-r--r-- | services/surfaceflinger/DispSync.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/DispSync.h | 1 |
2 files changed, 7 insertions, 2 deletions
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index 73b3897..dda896e 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -317,6 +317,7 @@ void DispSync::reset() { mNumResyncSamples = 0; mFirstResyncSample = 0; + mResyncReferenceTime = 0; mNumResyncSamplesSincePresent = 0; resetErrorLocked(); } @@ -356,6 +357,9 @@ bool DispSync::addResyncSample(nsecs_t timestamp) { size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES; mResyncSamples[idx] = timestamp; + if (mNumResyncSamples == 0) { + mResyncReferenceTime = timestamp; + } if (mNumResyncSamples < MAX_RESYNC_SAMPLES) { mNumResyncSamples++; @@ -432,7 +436,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] - mResyncReferenceTime; double samplePhase = double(sample % mPeriod) * scale; sampleAvgX += cos(samplePhase); sampleAvgY += sin(samplePhase); @@ -472,7 +476,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] - mResyncReferenceTime; if (sample > mPhase) { nsecs_t sampleErr = (sample - mPhase) % period; if (sampleErr > period / 2) { diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h index ebe19a5..fabb875 100644 --- a/services/surfaceflinger/DispSync.h +++ b/services/surfaceflinger/DispSync.h @@ -154,6 +154,7 @@ private: // These member variables are the state used during the resynchronization // process to store information about the hardware vsync event times used // to compute the model. + nsecs_t mResyncReferenceTime; nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES]; size_t mFirstResyncSample; size_t mNumResyncSamples; |