From 95cda3b92faf69f2ed594ee87a7e1e7499bd0060 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Wed, 28 Oct 2015 13:22:22 -0700 Subject: [PATCH] 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 --- services/surfaceflinger/DispSync.cpp | 8 ++++++-- 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 73b389730..dda896ebf 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 ebe19a5b8..fabb875a2 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;