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

Commit c782ca07 authored by Ady Abraham's avatar Ady Abraham Committed by Android (Google) Code Review
Browse files

Merge changes from topic "VsyncTimeline_VsyncPredictor" into main

* changes:
  SF: change the render rate directly instead of starting a new VsyncTimeline
  SF: don't use minFramePeriod if it is same as vsync
  SF: flush setRenderRate when changing mode
  SF: reduce latency when switching low to high render rate
  SF: fix vsync shift repeatedly when HWC miss a frame
  Revert^2 "SF: Introduce VsyncTimeline to VsyncPredictor"
parents 1abe1a36 4fc2fcea
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -565,7 +565,7 @@ void Scheduler::onHardwareVsyncRequest(PhysicalDisplayId id, bool enabled) {
            }));
            }));
}
}


void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate, bool applyImmediately) {
    std::scoped_lock lock(mDisplayLock);
    std::scoped_lock lock(mDisplayLock);
    ftl::FakeGuard guard(kMainThreadContext);
    ftl::FakeGuard guard(kMainThreadContext);


@@ -586,7 +586,7 @@ void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
    ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
    ALOGV("%s %s (%s)", __func__, to_string(mode.fps).c_str(),
          to_string(mode.modePtr->getVsyncRate()).c_str());
          to_string(mode.modePtr->getVsyncRate()).c_str());


    display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
    display.schedulePtr->getTracker().setRenderRate(renderFrameRate, applyImmediately);
}
}


Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id,
Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id,
+1 −1
Original line number Original line Diff line number Diff line
@@ -188,7 +188,7 @@ public:
    const VsyncConfiguration& getVsyncConfiguration() const { return *mVsyncConfiguration; }
    const VsyncConfiguration& getVsyncConfiguration() const { return *mVsyncConfiguration; }


    // Sets the render rate for the scheduler to run at.
    // Sets the render rate for the scheduler to run at.
    void setRenderRate(PhysicalDisplayId, Fps);
    void setRenderRate(PhysicalDisplayId, Fps, bool applyImmediately);


    void enableHardwareVsync(PhysicalDisplayId) REQUIRES(kMainThreadContext);
    void enableHardwareVsync(PhysicalDisplayId) REQUIRES(kMainThreadContext);
    void disableHardwareVsync(PhysicalDisplayId, bool disallow) REQUIRES(kMainThreadContext);
    void disableHardwareVsync(PhysicalDisplayId, bool disallow) REQUIRES(kMainThreadContext);
+51 −20
Original line number Original line Diff line number Diff line
@@ -20,7 +20,7 @@


#include <android-base/stringprintf.h>
#include <android-base/stringprintf.h>
#include <ftl/concat.h>
#include <ftl/concat.h>
#include <utils/Trace.h>
#include <gui/TraceUtils.h>
#include <log/log_main.h>
#include <log/log_main.h>


#include <scheduler/TimeKeeper.h>
#include <scheduler/TimeKeeper.h>
@@ -44,6 +44,17 @@ ScheduleResult getExpectedCallbackTime(nsecs_t nextVsyncTime,
            TimePoint::fromNs(nextVsyncTime)};
            TimePoint::fromNs(nextVsyncTime)};
}
}


void traceEntry(const VSyncDispatchTimerQueueEntry& entry, nsecs_t now) {
    if (!ATRACE_ENABLED() || !entry.wakeupTime().has_value() || !entry.targetVsync().has_value()) {
        return;
    }

    ftl::Concat trace(ftl::truncated<5>(entry.name()), " alarm in ",
                      ns2us(*entry.wakeupTime() - now), "us; VSYNC in ",
                      ns2us(*entry.targetVsync() - now), "us");
    ATRACE_FORMAT_INSTANT(trace.c_str());
}

} // namespace
} // namespace


VSyncDispatch::~VSyncDispatch() = default;
VSyncDispatch::~VSyncDispatch() = default;
@@ -87,6 +98,7 @@ std::optional<nsecs_t> VSyncDispatchTimerQueueEntry::targetVsync() const {


ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
                                                      VSyncTracker& tracker, nsecs_t now) {
                                                      VSyncTracker& tracker, nsecs_t now) {
    ATRACE_NAME("VSyncDispatchTimerQueueEntry::schedule");
    auto nextVsyncTime =
    auto nextVsyncTime =
            tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
            tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
                                                          now + timing.workDuration +
                                                          now + timing.workDuration +
@@ -98,6 +110,8 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim
            mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
            mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
    bool const wouldSkipAWakeup =
    bool const wouldSkipAWakeup =
            mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance)));
            mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance)));
    ATRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
                          wouldSkipAVsyncTarget, wouldSkipAWakeup);
    if (FlagManager::getInstance().dont_skip_on_early_ro()) {
    if (FlagManager::getInstance().dont_skip_on_early_ro()) {
        if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
        if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
            nextVsyncTime = mArmedInfo->mActualVsyncTime;
            nextVsyncTime = mArmedInfo->mActualVsyncTime;
@@ -122,7 +136,7 @@ ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTim
ScheduleResult VSyncDispatchTimerQueueEntry::addPendingWorkloadUpdate(
ScheduleResult VSyncDispatchTimerQueueEntry::addPendingWorkloadUpdate(
        VSyncTracker& tracker, nsecs_t now, VSyncDispatch::ScheduleTiming timing) {
        VSyncTracker& tracker, nsecs_t now, VSyncDispatch::ScheduleTiming timing) {
    mWorkloadUpdateInfo = timing;
    mWorkloadUpdateInfo = timing;
    const auto armedInfo = update(tracker, now, timing, mArmedInfo);
    const auto armedInfo = getArmedInfo(tracker, now, timing, mArmedInfo);
    return {TimePoint::fromNs(armedInfo.mActualWakeupTime),
    return {TimePoint::fromNs(armedInfo.mActualWakeupTime),
            TimePoint::fromNs(armedInfo.mActualVsyncTime)};
            TimePoint::fromNs(armedInfo.mActualVsyncTime)};
}
}
@@ -140,11 +154,13 @@ nsecs_t VSyncDispatchTimerQueueEntry::adjustVsyncIfNeeded(VSyncTracker& tracker,
    bool const nextVsyncTooClose = mLastDispatchTime &&
    bool const nextVsyncTooClose = mLastDispatchTime &&
            (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod;
            (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod;
    if (alreadyDispatchedForVsync) {
    if (alreadyDispatchedForVsync) {
        ATRACE_FORMAT_INSTANT("alreadyDispatchedForVsync");
        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance,
        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance,
                                                    *mLastDispatchTime);
                                                    *mLastDispatchTime);
    }
    }


    if (nextVsyncTooClose) {
    if (nextVsyncTooClose) {
        ATRACE_FORMAT_INSTANT("nextVsyncTooClose");
        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod,
        return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod,
                                                    *mLastDispatchTime + currentPeriod);
                                                    *mLastDispatchTime + currentPeriod);
    }
    }
@@ -152,9 +168,11 @@ nsecs_t VSyncDispatchTimerQueueEntry::adjustVsyncIfNeeded(VSyncTracker& tracker,
    return nextVsyncTime;
    return nextVsyncTime;
}
}


auto VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now,
auto VSyncDispatchTimerQueueEntry::getArmedInfo(VSyncTracker& tracker, nsecs_t now,
                                                VSyncDispatch::ScheduleTiming timing,
                                                VSyncDispatch::ScheduleTiming timing,
                                          std::optional<ArmingInfo> armedInfo) const -> ArmingInfo {
                                                std::optional<ArmingInfo> armedInfo) const
        -> ArmingInfo {
    ATRACE_NAME("VSyncDispatchTimerQueueEntry::getArmedInfo");
    const auto earliestReadyBy = now + timing.workDuration + timing.readyDuration;
    const auto earliestReadyBy = now + timing.workDuration + timing.readyDuration;
    const auto earliestVsync = std::max(earliestReadyBy, timing.lastVsync);
    const auto earliestVsync = std::max(earliestReadyBy, timing.lastVsync);


@@ -165,29 +183,39 @@ auto VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now,
    const auto nextReadyTime = nextVsyncTime - timing.readyDuration;
    const auto nextReadyTime = nextVsyncTime - timing.readyDuration;
    const auto nextWakeupTime = nextReadyTime - timing.workDuration;
    const auto nextWakeupTime = nextReadyTime - timing.workDuration;


    if (FlagManager::getInstance().dont_skip_on_early_ro()) {
        bool const wouldSkipAVsyncTarget =
        bool const wouldSkipAVsyncTarget =
                armedInfo && (nextVsyncTime > (armedInfo->mActualVsyncTime + mMinVsyncDistance));
                armedInfo && (nextVsyncTime > (armedInfo->mActualVsyncTime + mMinVsyncDistance));
        bool const wouldSkipAWakeup =
        bool const wouldSkipAWakeup =
                armedInfo && (nextWakeupTime > (armedInfo->mActualWakeupTime + mMinVsyncDistance));
                armedInfo && (nextWakeupTime > (armedInfo->mActualWakeupTime + mMinVsyncDistance));
    if (FlagManager::getInstance().dont_skip_on_early_ro() &&
        ATRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
        (wouldSkipAVsyncTarget || wouldSkipAWakeup)) {
                              wouldSkipAVsyncTarget, wouldSkipAWakeup);
        if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
            return *armedInfo;
            return *armedInfo;
        }
        }
    }


    return ArmingInfo{nextWakeupTime, nextVsyncTime, nextReadyTime};
    return ArmingInfo{nextWakeupTime, nextVsyncTime, nextReadyTime};
}
}


void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) {
void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) {
    ATRACE_NAME("VSyncDispatchTimerQueueEntry::update");
    if (!mArmedInfo && !mWorkloadUpdateInfo) {
    if (!mArmedInfo && !mWorkloadUpdateInfo) {
        return;
        return;
    }
    }


    if (mWorkloadUpdateInfo) {
    if (mWorkloadUpdateInfo) {
        const auto workDelta = mWorkloadUpdateInfo->workDuration - mScheduleTiming.workDuration;
        const auto readyDelta = mWorkloadUpdateInfo->readyDuration - mScheduleTiming.readyDuration;
        const auto lastVsyncDelta = mWorkloadUpdateInfo->lastVsync - mScheduleTiming.lastVsync;
        ATRACE_FORMAT_INSTANT("Workload updated workDelta=%" PRId64 " readyDelta=%" PRId64
                              " lastVsyncDelta=%" PRId64,
                              workDelta, readyDelta, lastVsyncDelta);
        mScheduleTiming = *mWorkloadUpdateInfo;
        mScheduleTiming = *mWorkloadUpdateInfo;
        mWorkloadUpdateInfo.reset();
        mWorkloadUpdateInfo.reset();
    }
    }


    mArmedInfo = update(tracker, now, mScheduleTiming, mArmedInfo);
    mArmedInfo = getArmedInfo(tracker, now, mScheduleTiming, mArmedInfo);
}
}


void VSyncDispatchTimerQueueEntry::disarm() {
void VSyncDispatchTimerQueueEntry::disarm() {
@@ -282,6 +310,7 @@ void VSyncDispatchTimerQueue::rearmTimer(nsecs_t now) {


void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
        nsecs_t now, CallbackMap::const_iterator skipUpdateIt) {
        nsecs_t now, CallbackMap::const_iterator skipUpdateIt) {
    ATRACE_CALL();
    std::optional<nsecs_t> min;
    std::optional<nsecs_t> min;
    std::optional<nsecs_t> targetVsync;
    std::optional<nsecs_t> targetVsync;
    std::optional<std::string_view> nextWakeupName;
    std::optional<std::string_view> nextWakeupName;
@@ -294,7 +323,10 @@ void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
        if (it != skipUpdateIt) {
        if (it != skipUpdateIt) {
            callback->update(*mTracker, now);
            callback->update(*mTracker, now);
        }
        }
        auto const wakeupTime = *callback->wakeupTime();

        traceEntry(*callback, now);

        const auto wakeupTime = *callback->wakeupTime();
        if (!min || *min > wakeupTime) {
        if (!min || *min > wakeupTime) {
            nextWakeupName = callback->name();
            nextWakeupName = callback->name();
            min = wakeupTime;
            min = wakeupTime;
@@ -303,11 +335,6 @@ void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
    }
    }


    if (min && min < mIntendedWakeupTime) {
    if (min && min < mIntendedWakeupTime) {
        if (ATRACE_ENABLED() && nextWakeupName && targetVsync) {
            ftl::Concat trace(ftl::truncated<5>(*nextWakeupName), " alarm in ", ns2us(*min - now),
                              "us; VSYNC in ", ns2us(*targetVsync - now), "us");
            ATRACE_NAME(trace.c_str());
        }
        setTimer(*min, now);
        setTimer(*min, now);
    } else {
    } else {
        ATRACE_NAME("cancel timer");
        ATRACE_NAME("cancel timer");
@@ -316,6 +343,7 @@ void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
}
}


void VSyncDispatchTimerQueue::timerCallback() {
void VSyncDispatchTimerQueue::timerCallback() {
    ATRACE_CALL();
    struct Invocation {
    struct Invocation {
        std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
        std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
        nsecs_t vsyncTimestamp;
        nsecs_t vsyncTimestamp;
@@ -338,8 +366,9 @@ void VSyncDispatchTimerQueue::timerCallback() {
                continue;
                continue;
            }
            }


            auto const readyTime = callback->readyTime();
            traceEntry(*callback, now);


            auto const readyTime = callback->readyTime();
            auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
            auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
            if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
            if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
                callback->executing();
                callback->executing();
@@ -353,6 +382,8 @@ void VSyncDispatchTimerQueue::timerCallback() {
    }
    }


    for (auto const& invocation : invocations) {
    for (auto const& invocation : invocations) {
        ftl::Concat trace(ftl::truncated<5>(invocation.callback->name()));
        ATRACE_FORMAT("%s: %s", __func__, trace.c_str());
        invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp,
        invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp,
                                      invocation.deadlineTimestamp);
                                      invocation.deadlineTimestamp);
    }
    }
+2 −2
Original line number Original line Diff line number Diff line
@@ -91,7 +91,7 @@ private:
    };
    };


    nsecs_t adjustVsyncIfNeeded(VSyncTracker& tracker, nsecs_t nextVsyncTime) const;
    nsecs_t adjustVsyncIfNeeded(VSyncTracker& tracker, nsecs_t nextVsyncTime) const;
    ArmingInfo update(VSyncTracker&, nsecs_t now, VSyncDispatch::ScheduleTiming,
    ArmingInfo getArmedInfo(VSyncTracker&, nsecs_t now, VSyncDispatch::ScheduleTiming,
                            std::optional<ArmingInfo>) const;
                            std::optional<ArmingInfo>) const;


    const std::string mName;
    const std::string mName;
+281 −88

File changed.

Preview size limit exceeded, changes collapsed.

Loading