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
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 3738a55..a342dfe 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -315,6 +315,7 @@
mNumResyncSamples = 0;
mFirstResyncSample = 0;
+ mResyncReferenceTime = 0;
mNumResyncSamplesSincePresent = 0;
resetErrorLocked();
}
@@ -354,6 +355,9 @@
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp;
+ if (mNumResyncSamples == 0) {
+ mResyncReferenceTime = timestamp;
+ }
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
@@ -430,7 +434,7 @@
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);
@@ -470,7 +474,7 @@
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) {