summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp')
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp166
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"