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
This commit is contained in:
Haixia Shi 2015-10-28 13:22:22 -07:00 committed by Steve Kondik
parent a5761b164a
commit 95cda3b92f
2 changed files with 7 additions and 2 deletions

View File

@ -317,6 +317,7 @@ void DispSync::reset() {
mNumResyncSamples = 0; mNumResyncSamples = 0;
mFirstResyncSample = 0; mFirstResyncSample = 0;
mResyncReferenceTime = 0;
mNumResyncSamplesSincePresent = 0; mNumResyncSamplesSincePresent = 0;
resetErrorLocked(); resetErrorLocked();
} }
@ -356,6 +357,9 @@ bool DispSync::addResyncSample(nsecs_t timestamp) {
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES; size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp; mResyncSamples[idx] = timestamp;
if (mNumResyncSamples == 0) {
mResyncReferenceTime = timestamp;
}
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) { if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++; mNumResyncSamples++;
@ -432,7 +436,7 @@ void DispSync::updateModelLocked() {
double scale = 2.0 * M_PI / double(mPeriod); double scale = 2.0 * M_PI / double(mPeriod);
for (size_t i = 0; i < mNumResyncSamples; i++) { for (size_t i = 0; i < mNumResyncSamples; i++) {
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES; 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; double samplePhase = double(sample % mPeriod) * scale;
sampleAvgX += cos(samplePhase); sampleAvgX += cos(samplePhase);
sampleAvgY += sin(samplePhase); sampleAvgY += sin(samplePhase);
@ -472,7 +476,7 @@ void DispSync::updateErrorLocked() {
nsecs_t sqErrSum = 0; nsecs_t sqErrSum = 0;
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) { for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
nsecs_t sample = mPresentTimes[i]; nsecs_t sample = mPresentTimes[i] - mResyncReferenceTime;
if (sample > mPhase) { if (sample > mPhase) {
nsecs_t sampleErr = (sample - mPhase) % period; nsecs_t sampleErr = (sample - mPhase) % period;
if (sampleErr > period / 2) { if (sampleErr > period / 2) {

View File

@ -154,6 +154,7 @@ private:
// These member variables are the state used during the resynchronization // These member variables are the state used during the resynchronization
// process to store information about the hardware vsync event times used // process to store information about the hardware vsync event times used
// to compute the model. // to compute the model.
nsecs_t mResyncReferenceTime;
nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES]; nsecs_t mResyncSamples[MAX_RESYNC_SAMPLES];
size_t mFirstResyncSample; size_t mFirstResyncSample;
size_t mNumResyncSamples; size_t mNumResyncSamples;