SF: increase precision in VSyncPredictor
An issue was observed where the sf-app timeline woke up 1ms later than
it should have. Issue was tracked down to an imprecision in some of the
math in VSyncPredictor, which this issue corrects.
Fixes: 151146131
Test: 2 new unit tests, one of which was from bug
Test: flash dogfood device with patch
Change-Id: I1994b5b532e292a140d4736c7090b68224f75a02
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 399da19..257b8b1 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -115,10 +115,10 @@
auto it = mRateMap.find(mIdealPeriod);
auto const currentPeriod = std::get<0>(it->second);
// TODO (b/144707443): its important that there's some precision in the mean of the ordinals
- // for the intercept calculation, so scale the ordinals by 10 to continue
+ // for the intercept calculation, so scale the ordinals by 1000 to continue
// fixed point calculation. Explore expanding
// scheduler::utils::calculate_mean to have a fixed point fractional part.
- static constexpr int kScalingFactor = 10;
+ static constexpr int64_t kScalingFactor = 1000;
for (auto i = 0u; i < mTimestamps.size(); i++) {
traceInt64If("VSP-ts", mTimestamps[i]);
@@ -147,7 +147,7 @@
return false;
}
- nsecs_t const anticipatedPeriod = top / bottom * kScalingFactor;
+ nsecs_t const anticipatedPeriod = top * kScalingFactor / bottom;
nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor);
auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod;