Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0c3cf95 authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: enable vsync_predictor_predicts_within_threshold behaviour on resync_on_tx

resync_on_tx depends on vsync_predictor_predicts_within_threshold which is only enable on VRR displays. This CL changes the behaviour of vsync_predictor_predicts_within_threshold to be for all devices.

Bug: 425994753
Test: presubmit
Flag: com.android.graphics.surfaceflinger.flags.resync_on_tx
Change-Id: I5420259e269ea9a3b3e6617a820586c3c2707a7d
parent 9f388aec
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {

    const auto isThresholdEnabled =
            FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
            mDisplayModePtr->getVrrConfig();
            (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx());
    const auto iter =
            std::min_element(mTimestamps.begin(), mTimestamps.end(), [=](nsecs_t a, nsecs_t b) {
                nsecs_t diffA = std::abs(timestamp - a);
@@ -224,10 +224,10 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
    auto it = mRateMap.find(idealPeriod());
    // Calculated slope over the period of time can become outdated as the new timestamps are
    // stored. Using idealPeriod instead provides a rate which is valid at all the times.
    auto const currentPeriod = mDisplayModePtr->getVrrConfig() &&
                    (FlagManager::getInstance().vsync_predictor_predicts_within_threshold())
            ? idealPeriod()
            : it->second.slope;
    const bool useIdealPeriod =
            FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
            (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx());
    auto const currentPeriod = useIdealPeriod ? idealPeriod() : it->second.slope;

    // The mean of the ordinals must be precise for the intercept calculation, so scale them up for
    // fixed-point arithmetic.
@@ -307,7 +307,8 @@ nsecs_t VSyncPredictor::snapToVsync(nsecs_t timePoint) const {
    }

    // See b/145667109, the ordinal calculation must take into account the intercept.
    const auto oldest = mDisplayModePtr->getVrrConfig() &&
    const auto oldest =
            (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx()) &&
                    FlagManager::getInstance().vsync_predictor_predicts_within_threshold()
            ? mOldestVsync
            : *std::min_element(mTimestamps.begin(), mTimestamps.end());
@@ -337,7 +338,7 @@ nsecs_t VSyncPredictor::snapToVsync(nsecs_t timePoint) const {
bool VSyncPredictor::isVsyncWithinThreshold(nsecs_t currentTimestamp,
                                            nsecs_t previousTimestamp) const {
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        mDisplayModePtr->getVrrConfig()) {
        (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx())) {
        return currentTimestamp - previousTimestamp <= kPredictorThreshold.ns();
    }
    return true;
@@ -346,7 +347,7 @@ bool VSyncPredictor::isVsyncWithinThreshold(nsecs_t currentTimestamp,
std::pair<size_t, nsecs_t> VSyncPredictor::getSampleSizeAndOldestVsync(
        nsecs_t currentTimestamp) const {
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        mDisplayModePtr->getVrrConfig()) {
        (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx())) {
        size_t numSamples = 0;
        nsecs_t oldestTimestamp = currentTimestamp;
        for (auto vsync : mTimestamps) {
@@ -364,7 +365,8 @@ std::pair<size_t, nsecs_t> VSyncPredictor::getSampleSizeAndOldestVsync(

size_t VSyncPredictor::getMinSamplesRequiredForPrediction() const {
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        mDisplayModePtr->getVrrConfig() && mRenderRateOpt) {
        (mDisplayModePtr->getVrrConfig() || FlagManager::getInstance().resync_on_tx()) &&
        mRenderRateOpt) {
        const size_t minimumSamplesForPrediction =
                std::max(static_cast<size_t>(kAbsoluteMinSamplesForPrediction),
                         static_cast<size_t>(kPredictorThreshold.ns() /
+32 −8
Original line number Diff line number Diff line
@@ -273,9 +273,15 @@ TEST_F(VSyncPredictorTest, adaptsToFenceTimelinesDiscontinuous_22hzLowVariance)
        tracker.addVsyncTimestamp(timestamp);
    }
    auto [slope, intercept] = tracker.getVSyncPredictionModel();
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        FlagManager::getInstance().resync_on_tx()) {
        EXPECT_EQ(slope, idealPeriod);
        EXPECT_EQ(intercept, 0);
    } else {
        EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError));
    }
}

TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) {
    std::vector<nsecs_t> const simulatedVsyncs{
@@ -300,9 +306,15 @@ TEST_F(VSyncPredictorTest, againstOutliersDiscontinuous_500hzLowVariance) {
    }

    auto [slope, intercept] = tracker.getVSyncPredictionModel();
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        FlagManager::getInstance().resync_on_tx()) {
        EXPECT_EQ(slope, idealPeriod);
        EXPECT_EQ(intercept, 0);
    } else {
        EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError));
    }
}

TEST_F(VSyncPredictorTest, recoverAfterDriftedVSyncAreReplacedWithCorrectVSync) {
    SET_FLAG_FOR_TEST(flags::vsync_predictor_predicts_within_threshold, true);
@@ -503,8 +515,14 @@ TEST_F(VSyncPredictorTest, doesNotPredictBeforeTimePointWithHigherIntercept) {
    }

    auto [slope, intercept] = tracker.getVSyncPredictionModel();
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        FlagManager::getInstance().resync_on_tx()) {
        EXPECT_THAT(slope, IsCloseTo(11603853, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(1016896, mMaxRoundingError));
    } else {
        EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError));
    }

    // (timePoint - oldestTS) % expectedPeriod works out to be: 10702663
    // (timePoint - oldestTS) / expectedPeriod works out to be: 37.96
@@ -713,9 +731,15 @@ TEST_F(VSyncPredictorTest, robustToDuplicateTimestamps_60hzRealTraceData) {
        tracker.addVsyncTimestamp(timestamp);
    }
    auto [slope, intercept] = tracker.getVSyncPredictionModel();
    if (FlagManager::getInstance().vsync_predictor_predicts_within_threshold() &&
        FlagManager::getInstance().resync_on_tx()) {
        EXPECT_THAT(slope, IsCloseTo(16664349, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(38082, mMaxRoundingError));
    } else {
        EXPECT_THAT(slope, IsCloseTo(expectedPeriod, mMaxRoundingError));
        EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError));
    }
}

TEST_F(VSyncPredictorTest, setRenderRateIsRespected) {
    auto last = mNow;