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

Commit 53b5d03f authored by Alec Mouri's avatar Alec Mouri Committed by Ana Krulec
Browse files

[SurfaceFlinger] Don't touch hw vsync in DEFAULT RR with kernel timeout

As a power optimization, hw vsync shouldn't be enabled when the kernel
timer resets if the display is going to run at 60hz anyways.

Bug: 136197211
Test: systrace when scrolling at peak refresh rate of 60hz.
Change-Id: Ic7df3e7b735f79b183cdd91f770de83082e491b4
(cherry picked from commit 7f01518e)
Merged-In: Ic7df3e7b735f79b183cdd91f770de83082e491b4
parent a133f037
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -393,11 +393,17 @@ void Scheduler::updateFpsBasedOnContent() {
}

void Scheduler::setChangeRefreshRateCallback(
        const ChangeRefreshRateCallback& changeRefreshRateCallback) {
        const ChangeRefreshRateCallback&& changeRefreshRateCallback) {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    mChangeRefreshRateCallback = changeRefreshRateCallback;
}

void Scheduler::setGetCurrentRefreshRateTypeCallback(
        const GetCurrentRefreshRateTypeCallback&& getCurrentRefreshRateTypeCallback) {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    mGetCurrentRefreshRateTypeCallback = getCurrentRefreshRateTypeCallback;
}

void Scheduler::setGetVsyncPeriodCallback(const GetVsyncPeriod&& getVsyncPeriod) {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    mGetVsyncPeriod = getVsyncPeriod;
@@ -455,10 +461,15 @@ void Scheduler::resetTimerCallback() {
void Scheduler::resetKernelTimerCallback() {
    ATRACE_INT("ExpiredKernelIdleTimer", 0);
    std::lock_guard<std::mutex> lock(mCallbackLock);
    if (mGetVsyncPeriod) {
    if (mGetVsyncPeriod && mGetCurrentRefreshRateTypeCallback) {
        // If we're not in performance mode then the kernel timer shouldn't do
        // anything, as the refresh rate during DPU power collapse will be the
        // same.
        if (mGetCurrentRefreshRateTypeCallback() == Scheduler::RefreshRateType::PERFORMANCE) {
            resyncToHardwareVsync(true, mGetVsyncPeriod());
        }
    }
}

void Scheduler::expiredTimerCallback() {
    handleTimerStateChanged(&mCurrentIdleTimerState, IdleTimerState::EXPIRED, false);
@@ -486,11 +497,17 @@ void Scheduler::expiredDisplayPowerTimerCallback() {
}

void Scheduler::expiredKernelTimerCallback() {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    ATRACE_INT("ExpiredKernelIdleTimer", 1);
    if (mGetCurrentRefreshRateTypeCallback) {
        if (mGetCurrentRefreshRateTypeCallback() != Scheduler::RefreshRateType::PERFORMANCE) {
            // Disable HW Vsync if the timer expired, as we don't need it
    // enabled if we're not pushing frames.
            // enabled if we're not pushing frames, and if we're in PERFORMANCE
            // mode then we'll need to re-update the DispSync model anyways.
            disableHardwareVsync(false);
        }
    }
}

std::string Scheduler::doDump() {
    std::ostringstream stream;
+5 −1
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ public:
    }

    using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
    using GetCurrentRefreshRateTypeCallback = std::function<RefreshRateType()>;
    using ChangeRefreshRateCallback = std::function<void(RefreshRateType, ConfigEvent)>;
    using GetVsyncPeriod = std::function<nsecs_t()>;

@@ -165,7 +166,9 @@ public:
    // Updates FPS based on the most content presented.
    void updateFpsBasedOnContent();
    // Callback that gets invoked when Scheduler wants to change the refresh rate.
    void setChangeRefreshRateCallback(const ChangeRefreshRateCallback& changeRefreshRateCallback);
    void setChangeRefreshRateCallback(const ChangeRefreshRateCallback&& changeRefreshRateCallback);
    void setGetCurrentRefreshRateTypeCallback(
            const GetCurrentRefreshRateTypeCallback&& getCurrentRefreshRateType);
    void setGetVsyncPeriodCallback(const GetVsyncPeriod&& getVsyncPeriod);

    // Returns whether idle timer is enabled or not
@@ -294,6 +297,7 @@ private:
    std::unique_ptr<scheduler::IdleTimer> mDisplayPowerTimer;

    std::mutex mCallbackLock;
    GetCurrentRefreshRateTypeCallback mGetCurrentRefreshRateTypeCallback GUARDED_BY(mCallbackLock);
    ChangeRefreshRateCallback mChangeRefreshRateCallback GUARDED_BY(mCallbackLock);
    GetVsyncPeriod mGetVsyncPeriod GUARDED_BY(mCallbackLock);

+19 −0
Original line number Diff line number Diff line
@@ -715,6 +715,24 @@ void SurfaceFlinger::init() {
                Mutex::Autolock lock(mStateLock);
                setRefreshRateTo(type, event);
            });
    mScheduler->setGetCurrentRefreshRateTypeCallback([this] {
        Mutex::Autolock lock(mStateLock);
        const auto display = getDefaultDisplayDeviceLocked();
        if (!display) {
            // If we don't have a default display the fallback to the default
            // refresh rate type
            return RefreshRateType::DEFAULT;
        }

        const int configId = display->getActiveConfig();
        for (const auto& [type, refresh] : mRefreshRateConfigs.getRefreshRates()) {
            if (refresh && refresh->configId == configId) {
                return type;
            }
        }
        // This should never happen, but just gracefully fallback to default.
        return RefreshRateType::DEFAULT;
    });
    mScheduler->setGetVsyncPeriodCallback([this] {
        Mutex::Autolock lock(mStateLock);
        return getVsyncPeriod();
@@ -1047,6 +1065,7 @@ bool SurfaceFlinger::performSetActiveConfig() {
        desiredActiveConfigChangeDone();
        return false;
    }

    mUpcomingActiveConfig = desiredActiveConfig;
    const auto displayId = display->getId();
    LOG_ALWAYS_FATAL_IF(!displayId);