Loading services/surfaceflinger/Scheduler/VSyncPredictor.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -115,10 +115,10 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { auto it = mRateMap.find(mIdealPeriod); auto it = mRateMap.find(mIdealPeriod); auto const currentPeriod = std::get<0>(it->second); auto const currentPeriod = std::get<0>(it->second); // TODO (b/144707443): its important that there's some precision in the mean of the ordinals // 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 // fixed point calculation. Explore expanding // scheduler::utils::calculate_mean to have a fixed point fractional part. // 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++) { for (auto i = 0u; i < mTimestamps.size(); i++) { traceInt64If("VSP-ts", mTimestamps[i]); traceInt64If("VSP-ts", mTimestamps[i]); Loading Loading @@ -147,7 +147,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { return false; return false; } } nsecs_t const anticipatedPeriod = top / bottom * kScalingFactor; nsecs_t const anticipatedPeriod = top * kScalingFactor / bottom; nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor); nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor); auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod; auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod; Loading services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +45 −3 Original line number Original line Diff line number Diff line Loading @@ -204,7 +204,7 @@ TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) { }; }; auto idealPeriod = 2000000; auto idealPeriod = 2000000; auto expectedPeriod = 1999892; auto expectedPeriod = 1999892; auto expectedIntercept = 175409; auto expectedIntercept = 86342; tracker.setPeriod(idealPeriod); tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { for (auto const& timestamp : simulatedVsyncs) { Loading Loading @@ -335,8 +335,8 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { 158929706370359, 158929706370359, }; }; auto const idealPeriod = 11111111; auto const idealPeriod = 11111111; auto const expectedPeriod = 11113500; auto const expectedPeriod = 11113919; auto const expectedIntercept = -395335; auto const expectedIntercept = -1195945; tracker.setPeriod(idealPeriod); tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { for (auto const& timestamp : simulatedVsyncs) { Loading @@ -355,6 +355,32 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { EXPECT_THAT(prediction, Ge(timePoint)); EXPECT_THAT(prediction, Ge(timePoint)); } } // See b/151146131 TEST_F(VSyncPredictorTest, hasEnoughPrecision) { VSyncPredictor tracker{mPeriod, 20, kMinimumSamplesForPrediction, kOutlierTolerancePercent}; std::vector<nsecs_t> const simulatedVsyncs{840873348817, 840890049444, 840906762675, 840923581635, 840940161584, 840956868096, 840973702473, 840990256277, 841007116851, 841023722530, 841040452167, 841057073002, 841073800920, 841090474360, 841107278632, 841123898634, 841140750875, 841157287127, 841591357014, 840856664232 }; auto const idealPeriod = 16666666; auto const expectedPeriod = 16698426; auto const expectedIntercept = 58055; tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { tracker.addVsyncTimestamp(timestamp); } auto [slope, intercept] = tracker.getVSyncPredictionModel(); EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError)); EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError)); } TEST_F(VSyncPredictorTest, resetsWhenInstructed) { TEST_F(VSyncPredictorTest, resetsWhenInstructed) { auto const idealPeriod = 10000; auto const idealPeriod = 10000; auto const realPeriod = 10500; auto const realPeriod = 10500; Loading Loading @@ -390,6 +416,22 @@ TEST_F(VSyncPredictorTest, slopeAlwaysValid) { } } } } constexpr nsecs_t operator""_years(unsigned long long years) noexcept { using namespace std::chrono_literals; return years * 365 * 24 * 3600 * std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); } TEST_F(VSyncPredictorTest, aPhoneThatHasBeenAroundAWhileCanStillComputePeriod) { constexpr nsecs_t timeBase = 100_years; for (auto i = 0; i < kHistorySize; i++) { tracker.addVsyncTimestamp(timeBase + i * mPeriod); } auto [slope, intercept] = tracker.getVSyncPredictionModel(); EXPECT_THAT(slope, IsCloseTo(mPeriod, mMaxRoundingError)); EXPECT_THAT(intercept, Eq(0)); } } // namespace android::scheduler } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues // TODO(b/129481165): remove the #pragma below and fix conversion issues Loading Loading
services/surfaceflinger/Scheduler/VSyncPredictor.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -115,10 +115,10 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { auto it = mRateMap.find(mIdealPeriod); auto it = mRateMap.find(mIdealPeriod); auto const currentPeriod = std::get<0>(it->second); auto const currentPeriod = std::get<0>(it->second); // TODO (b/144707443): its important that there's some precision in the mean of the ordinals // 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 // fixed point calculation. Explore expanding // scheduler::utils::calculate_mean to have a fixed point fractional part. // 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++) { for (auto i = 0u; i < mTimestamps.size(); i++) { traceInt64If("VSP-ts", mTimestamps[i]); traceInt64If("VSP-ts", mTimestamps[i]); Loading Loading @@ -147,7 +147,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { return false; return false; } } nsecs_t const anticipatedPeriod = top / bottom * kScalingFactor; nsecs_t const anticipatedPeriod = top * kScalingFactor / bottom; nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor); nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor); auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod; auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod; Loading
services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +45 −3 Original line number Original line Diff line number Diff line Loading @@ -204,7 +204,7 @@ TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) { }; }; auto idealPeriod = 2000000; auto idealPeriod = 2000000; auto expectedPeriod = 1999892; auto expectedPeriod = 1999892; auto expectedIntercept = 175409; auto expectedIntercept = 86342; tracker.setPeriod(idealPeriod); tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { for (auto const& timestamp : simulatedVsyncs) { Loading Loading @@ -335,8 +335,8 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { 158929706370359, 158929706370359, }; }; auto const idealPeriod = 11111111; auto const idealPeriod = 11111111; auto const expectedPeriod = 11113500; auto const expectedPeriod = 11113919; auto const expectedIntercept = -395335; auto const expectedIntercept = -1195945; tracker.setPeriod(idealPeriod); tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { for (auto const& timestamp : simulatedVsyncs) { Loading @@ -355,6 +355,32 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) { EXPECT_THAT(prediction, Ge(timePoint)); EXPECT_THAT(prediction, Ge(timePoint)); } } // See b/151146131 TEST_F(VSyncPredictorTest, hasEnoughPrecision) { VSyncPredictor tracker{mPeriod, 20, kMinimumSamplesForPrediction, kOutlierTolerancePercent}; std::vector<nsecs_t> const simulatedVsyncs{840873348817, 840890049444, 840906762675, 840923581635, 840940161584, 840956868096, 840973702473, 840990256277, 841007116851, 841023722530, 841040452167, 841057073002, 841073800920, 841090474360, 841107278632, 841123898634, 841140750875, 841157287127, 841591357014, 840856664232 }; auto const idealPeriod = 16666666; auto const expectedPeriod = 16698426; auto const expectedIntercept = 58055; tracker.setPeriod(idealPeriod); for (auto const& timestamp : simulatedVsyncs) { tracker.addVsyncTimestamp(timestamp); } auto [slope, intercept] = tracker.getVSyncPredictionModel(); EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError)); EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError)); } TEST_F(VSyncPredictorTest, resetsWhenInstructed) { TEST_F(VSyncPredictorTest, resetsWhenInstructed) { auto const idealPeriod = 10000; auto const idealPeriod = 10000; auto const realPeriod = 10500; auto const realPeriod = 10500; Loading Loading @@ -390,6 +416,22 @@ TEST_F(VSyncPredictorTest, slopeAlwaysValid) { } } } } constexpr nsecs_t operator""_years(unsigned long long years) noexcept { using namespace std::chrono_literals; return years * 365 * 24 * 3600 * std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); } TEST_F(VSyncPredictorTest, aPhoneThatHasBeenAroundAWhileCanStillComputePeriod) { constexpr nsecs_t timeBase = 100_years; for (auto i = 0; i < kHistorySize; i++) { tracker.addVsyncTimestamp(timeBase + i * mPeriod); } auto [slope, intercept] = tracker.getVSyncPredictionModel(); EXPECT_THAT(slope, IsCloseTo(mPeriod, mMaxRoundingError)); EXPECT_THAT(intercept, Eq(0)); } } // namespace android::scheduler } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues // TODO(b/129481165): remove the #pragma below and fix conversion issues Loading