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

Commit 9ee3113a authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: kernel idle timer is not applicable for VRR

Bug: 356061399
Change-Id: I784de91ae8bd4202e2e3dfe4bdb3d21e6779abd4
Test: Sysui perf test from bug
Flag: EXEMPT bugfix
parent 47bea68c
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -89,7 +89,9 @@ nsecs_t VSyncPredictor::idealPeriod() const {
}

bool VSyncPredictor::validate(nsecs_t timestamp) const {
    SFTRACE_CALL();
    if (mLastTimestampIndex < 0 || mTimestamps.empty()) {
        SFTRACE_INSTANT("timestamp valid (first)");
        return true;
    }

@@ -98,7 +100,11 @@ bool VSyncPredictor::validate(nsecs_t timestamp) const {
            (timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
    if (percent >= kOutlierTolerancePercent &&
        percent <= (kMaxPercent - kOutlierTolerancePercent)) {
        SFTRACE_FORMAT_INSTANT("timestamp is not aligned with model");
        SFTRACE_FORMAT_INSTANT("timestamp not aligned with model. aValidTimestamp %.2fms ago"
                               ", timestamp %.2fms ago, idealPeriod=%.2 percent=%d",
                               (mClock->now() - aValidTimestamp) / 1e6f,
                               (mClock->now() - timestamp) / 1e6f,
                               idealPeriod() / 1e6f, percent);
        return false;
    }

@@ -148,7 +154,10 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
            // Add the timestamp to mTimestamps before clearing it so we could
            // update mKnownTimestamp based on the new timestamp.
            mTimestamps.push_back(timestamp);
            clearTimestamps();

            // Do not clear timelines as we don't want to break the phase while
            // we are still learning.
            clearTimestamps(/* clearTimelines */ false);
        } else if (!mTimestamps.empty()) {
            mKnownTimestamp =
                    std::max(timestamp, *std::max_element(mTimestamps.begin(), mTimestamps.end()));
@@ -235,7 +244,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {

    if (CC_UNLIKELY(bottom == 0)) {
        it->second = {idealPeriod(), 0};
        clearTimestamps();
        clearTimestamps(/* clearTimelines */ true);
        return false;
    }

@@ -245,7 +254,7 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
    auto const percent = std::abs(anticipatedPeriod - idealPeriod()) * kMaxPercent / idealPeriod();
    if (percent >= kOutlierTolerancePercent) {
        it->second = {idealPeriod(), 0};
        clearTimestamps();
        clearTimestamps(/* clearTimelines */ true);
        return false;
    }

@@ -425,6 +434,9 @@ void VSyncPredictor::setDisplayModePtr(ftl::NonNull<DisplayModePtr> modePtr) {
          timeout ? std::to_string(timeout->timeoutNs).c_str() : "N/A");
    std::lock_guard lock(mMutex);

    // do not clear the timelines on VRR displays if we didn't change the mode
    const bool isVrr = modePtr->getVrrConfig().has_value();
    const bool clearTimelines = !isVrr || mDisplayModePtr->getId() != modePtr->getId();
    mDisplayModePtr = modePtr;
    mNumVsyncsForFrame = numVsyncsPerFrame(mDisplayModePtr);
    traceInt64("VSP-setPeriod", modePtr->getVsyncRate().getPeriodNsecs());
@@ -438,8 +450,10 @@ void VSyncPredictor::setDisplayModePtr(ftl::NonNull<DisplayModePtr> modePtr) {
        mRateMap[idealPeriod()] = {idealPeriod(), 0};
    }

    if (clearTimelines) {
      mTimelines.clear();
    clearTimestamps();
    }
    clearTimestamps(clearTimelines);
}

Duration VSyncPredictor::ensureMinFrameDurationIsKept(TimePoint expectedPresentTime,
@@ -556,15 +570,19 @@ VSyncPredictor::Model VSyncPredictor::getVSyncPredictionModelLocked() const {
    return mRateMap.find(idealPeriod())->second;
}

void VSyncPredictor::clearTimestamps() {
    SFTRACE_CALL();
void VSyncPredictor::clearTimestamps(bool clearTimelines) {
    SFTRACE_FORMAT("%s: clearTimelines=%d", __func__, clearTimelines);

    if (!mTimestamps.empty()) {
        auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
        if (mKnownTimestamp) {
            mKnownTimestamp = std::max(*mKnownTimestamp, maxRb);
            SFTRACE_FORMAT_INSTANT("mKnownTimestamp was %.2fms ago",
                               (mClock->now() - *mKnownTimestamp) / 1e6f);
        } else {
            mKnownTimestamp = maxRb;
            SFTRACE_FORMAT_INSTANT("mKnownTimestamp (maxRb) was %.2fms ago",
                               (mClock->now() - *mKnownTimestamp) / 1e6f);
        }

        mTimestamps.clear();
@@ -575,7 +593,7 @@ void VSyncPredictor::clearTimestamps() {
    if (mTimelines.empty()) {
        mLastCommittedVsync = TimePoint::fromNs(0);
        mTimelines.emplace_back(mLastCommittedVsync, mIdealPeriod, mRenderRateOpt);
    } else {
    } else if (clearTimelines) {
        while (mTimelines.size() > 1) {
            mTimelines.pop_front();
        }
@@ -596,9 +614,10 @@ bool VSyncPredictor::needsMoreSamples() const {
}

void VSyncPredictor::resetModel() {
    SFTRACE_CALL();
    std::lock_guard lock(mMutex);
    mRateMap[idealPeriod()] = {idealPeriod(), 0};
    clearTimestamps();
    clearTimestamps(/* clearTimelines */ true);
}

void VSyncPredictor::dump(std::string& result) const {
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ private:

    VSyncPredictor(VSyncPredictor const&) = delete;
    VSyncPredictor& operator=(VSyncPredictor const&) = delete;
    void clearTimestamps() REQUIRES(mMutex);
    void clearTimestamps(bool clearTimelines) REQUIRES(mMutex);

    const std::unique_ptr<Clock> mClock;
    const PhysicalDisplayId mId;
+3 −1
Original line number Diff line number Diff line
@@ -140,7 +140,9 @@ void VSyncReactor::onDisplayModeChanged(ftl::NonNull<DisplayModePtr> modePtr, bo
    std::lock_guard lock(mMutex);
    mLastHwVsync.reset();

    if (!mSupportKernelIdleTimer && mTracker.isCurrentMode(modePtr) && !force) {
    // kernel idle timer is not applicable for VRR
    const bool supportKernelIdleTimer = mSupportKernelIdleTimer && !modePtr->getVrrConfig();
    if (!supportKernelIdleTimer && mTracker.isCurrentMode(modePtr) && !force) {
        endPeriodTransition();
        setIgnorePresentFencesInternal(false);
        mMoreSamplesNeeded = false;