diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp | 166 |
1 files changed, 49 insertions, 117 deletions
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index 37ecd7c6a9..fc39235a93 100644 --- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp @@ -17,7 +17,6 @@ // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wextra" #undef LOG_TAG #define LOG_TAG "LibSurfaceFlingerUnittests" @@ -60,41 +59,41 @@ struct VSyncPredictorTest : testing::Test { }; TEST_F(VSyncPredictorTest, reportsAnticipatedPeriod) { - auto model = tracker.getVSyncPredictionModel(); + auto [slope, intercept] = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, Eq(mPeriod)); - EXPECT_THAT(model.intercept, Eq(0)); + EXPECT_THAT(slope, Eq(mPeriod)); + EXPECT_THAT(intercept, Eq(0)); auto const changedPeriod = 2000; tracker.setPeriod(changedPeriod); - model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, Eq(changedPeriod)); - EXPECT_THAT(model.intercept, Eq(0)); + std::tie(slope, intercept) = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, Eq(changedPeriod)); + EXPECT_THAT(intercept, Eq(0)); } TEST_F(VSyncPredictorTest, reportsSamplesNeededWhenHasNoDataPoints) { for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { - EXPECT_TRUE(tracker.needsMoreSamples()); - tracker.addVsyncTimestamp(mNow += mPeriod); + EXPECT_TRUE(tracker.needsMoreSamples(mNow += mPeriod)); + tracker.addVsyncTimestamp(mNow); } - EXPECT_FALSE(tracker.needsMoreSamples()); + EXPECT_FALSE(tracker.needsMoreSamples(mNow)); } TEST_F(VSyncPredictorTest, reportsSamplesNeededAfterExplicitRateChange) { for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { tracker.addVsyncTimestamp(mNow += mPeriod); } - EXPECT_FALSE(tracker.needsMoreSamples()); + EXPECT_FALSE(tracker.needsMoreSamples(mNow)); auto const changedPeriod = mPeriod * 2; tracker.setPeriod(changedPeriod); - EXPECT_TRUE(tracker.needsMoreSamples()); + EXPECT_TRUE(tracker.needsMoreSamples(mNow)); for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { - EXPECT_TRUE(tracker.needsMoreSamples()); - tracker.addVsyncTimestamp(mNow += changedPeriod); + EXPECT_TRUE(tracker.needsMoreSamples(mNow += changedPeriod)); + tracker.addVsyncTimestamp(mNow); } - EXPECT_FALSE(tracker.needsMoreSamples()); + EXPECT_FALSE(tracker.needsMoreSamples(mNow)); } TEST_F(VSyncPredictorTest, transitionsToModelledPointsAfterSynthetic) { @@ -265,17 +264,17 @@ TEST_F(VSyncPredictorTest, handlesVsyncChange) { } auto const mMaxRoundingError = 100; - auto model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, IsCloseTo(fastPeriod, mMaxRoundingError)); - EXPECT_THAT(model.intercept, IsCloseTo(0, mMaxRoundingError)); + auto [slope, intercept] = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, IsCloseTo(fastPeriod, mMaxRoundingError)); + EXPECT_THAT(intercept, IsCloseTo(0, mMaxRoundingError)); tracker.setPeriod(slowPeriod); for (auto const& timestamp : simulatedVsyncsSlow) { tracker.addVsyncTimestamp(timestamp); } - model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, IsCloseTo(slowPeriod, mMaxRoundingError)); - EXPECT_THAT(model.intercept, IsCloseTo(0, mMaxRoundingError)); + std::tie(slope, intercept) = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, IsCloseTo(slowPeriod, mMaxRoundingError)); + EXPECT_THAT(intercept, IsCloseTo(0, mMaxRoundingError)); } TEST_F(VSyncPredictorTest, willBeAccurateUsingPriorResultsForRate) { @@ -297,9 +296,9 @@ TEST_F(VSyncPredictorTest, willBeAccurateUsingPriorResultsForRate) { for (auto const& timestamp : simulatedVsyncsFast) { tracker.addVsyncTimestamp(timestamp); } - auto model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, Eq(fastPeriod)); - EXPECT_THAT(model.intercept, Eq(0)); + auto [slope, intercept] = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, Eq(fastPeriod)); + EXPECT_THAT(intercept, Eq(0)); tracker.setPeriod(slowPeriod); for (auto const& timestamp : simulatedVsyncsSlow) { @@ -309,16 +308,30 @@ TEST_F(VSyncPredictorTest, willBeAccurateUsingPriorResultsForRate) { // we had a model for 100ns mPeriod before, use that until the new samples are // sufficiently built up tracker.setPeriod(idealPeriod); - model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, Eq(fastPeriod)); - EXPECT_THAT(model.intercept, Eq(0)); + std::tie(slope, intercept) = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, Eq(fastPeriod)); + EXPECT_THAT(intercept, Eq(0)); for (auto const& timestamp : simulatedVsyncsFast2) { tracker.addVsyncTimestamp(timestamp); } - model = tracker.getVSyncPredictionModel(); - EXPECT_THAT(model.slope, Eq(fastPeriod2)); - EXPECT_THAT(model.intercept, Eq(0)); + std::tie(slope, intercept) = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, Eq(fastPeriod2)); + EXPECT_THAT(intercept, Eq(0)); +} + +TEST_F(VSyncPredictorTest, willBecomeInaccurateAfterA_longTimeWithNoSamples) { + auto const simulatedVsyncs = generateVsyncTimestamps(kMinimumSamplesForPrediction, mPeriod, 0); + + for (auto const& timestamp : simulatedVsyncs) { + tracker.addVsyncTimestamp(timestamp); + } + auto const mNow = *simulatedVsyncs.rbegin(); + EXPECT_FALSE(tracker.needsMoreSamples(mNow)); + + // TODO: would be better to decay this as a result of the variance of the samples + static auto constexpr aLongTimeOut = 1000000000; + EXPECT_TRUE(tracker.needsMoreSamples(mNow + aLongTimeOut)); } TEST_F(VSyncPredictorTest, idealModelPredictionsBeforeRegressionModelIsBuilt) { @@ -408,9 +421,11 @@ TEST_F(VSyncPredictorTest, resetsWhenInstructed) { tracker.addVsyncTimestamp(i * realPeriod); } - EXPECT_THAT(tracker.getVSyncPredictionModel().slope, IsCloseTo(realPeriod, mMaxRoundingError)); + EXPECT_THAT(std::get<0>(tracker.getVSyncPredictionModel()), + IsCloseTo(realPeriod, mMaxRoundingError)); tracker.resetModel(); - EXPECT_THAT(tracker.getVSyncPredictionModel().slope, IsCloseTo(idealPeriod, mMaxRoundingError)); + EXPECT_THAT(std::get<0>(tracker.getVSyncPredictionModel()), + IsCloseTo(idealPeriod, mMaxRoundingError)); } TEST_F(VSyncPredictorTest, slopeAlwaysValid) { @@ -428,7 +443,7 @@ TEST_F(VSyncPredictorTest, slopeAlwaysValid) { // When VsyncPredictor returns the period it means that it doesn't know how to predict and // it needs to get more samples if (slope == mPeriod && intercept == 0) { - EXPECT_TRUE(tracker.needsMoreSamples()); + EXPECT_TRUE(tracker.needsMoreSamples(now)); } } } @@ -449,90 +464,7 @@ TEST_F(VSyncPredictorTest, aPhoneThatHasBeenAroundAWhileCanStillComputePeriod) { EXPECT_THAT(intercept, Eq(0)); } -TEST_F(VSyncPredictorTest, isVSyncInPhase) { - auto last = mNow; - auto const bias = 10; - for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { - EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(last + mPeriod)); - mNow += mPeriod - bias; - last = mNow; - tracker.addVsyncTimestamp(mNow); - mNow += bias; - } - - EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod - bias)); - EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod - bias)); - EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 990), Eq(mNow + 2 * mPeriod - bias)); - - const auto maxDivider = 5; - const auto maxPeriods = 15; - for (int divider = 1; divider < maxDivider; divider++) { - for (int i = 0; i < maxPeriods; i++) { - const bool expectedInPhase = (i % divider) == 0; - EXPECT_THAT(expectedInPhase, - tracker.isVSyncInPhase(mNow + i * mPeriod - bias, - Fps::fromPeriodNsecs(divider * mPeriod))) - << "vsync at " << mNow + (i + 1) * mPeriod - bias << " is " - << (expectedInPhase ? "not " : "") << "in phase for divider " << divider; - } - } -} - -TEST_F(VSyncPredictorTest, inconsistentVsyncValueIsFlushedEventually) { - EXPECT_TRUE(tracker.addVsyncTimestamp(600)); - EXPECT_TRUE(tracker.needsMoreSamples()); - - EXPECT_FALSE(tracker.addVsyncTimestamp(mNow += mPeriod)); - - for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { - EXPECT_TRUE(tracker.needsMoreSamples()); - EXPECT_TRUE(tracker.addVsyncTimestamp(mNow += mPeriod)); - } - - EXPECT_FALSE(tracker.needsMoreSamples()); -} - -TEST_F(VSyncPredictorTest, knownVsyncIsUpdated) { - EXPECT_TRUE(tracker.addVsyncTimestamp(600)); - EXPECT_TRUE(tracker.needsMoreSamples()); - EXPECT_EQ(600, tracker.nextAnticipatedVSyncTimeFrom(mNow)); - - EXPECT_FALSE(tracker.addVsyncTimestamp(mNow += mPeriod)); - EXPECT_EQ(mNow + 1000, tracker.nextAnticipatedVSyncTimeFrom(mNow)); - - for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) { - EXPECT_TRUE(tracker.needsMoreSamples()); - EXPECT_TRUE(tracker.addVsyncTimestamp(mNow += mPeriod)); - EXPECT_EQ(mNow + 1000, tracker.nextAnticipatedVSyncTimeFrom(mNow)); - } - - EXPECT_FALSE(tracker.needsMoreSamples()); - EXPECT_EQ(mNow + 1000, tracker.nextAnticipatedVSyncTimeFrom(mNow)); -} - -TEST_F(VSyncPredictorTest, robustToDuplicateTimestamps_60hzRealTraceData) { - // these are real vsync timestamps from b/190331974 which caused vsync predictor - // period to spike to 18ms due to very close timestamps - std::vector<nsecs_t> const simulatedVsyncs{ - 198353408177, 198370074844, 198371400000, 198374274000, 198390941000, 198407565000, - 198540887994, 198607538588, 198624218276, 198657655939, 198674224176, 198690880955, - 198724204319, 198740988133, 198758166681, 198790869196, 198824205052, 198840871678, - 198857715631, 198890885797, 198924199640, 198940873834, 198974204401, - }; - auto constexpr idealPeriod = 16'666'666; - auto constexpr expectedPeriod = 16'644'742; - auto constexpr expectedIntercept = 125'626; - - 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)); -} - } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion -Wextra" +#pragma clang diagnostic pop // ignored "-Wconversion" |