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

Commit 85b3f01b authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: better fit content to refresh rate

Enhance the current algorithm for content based refresh rate selection
to choose a refresh rate that aligns better to the content. If no refresh
rate fits to the content we choose the lower one.

Fixes: 129874336
Test: Swappy render at 90fps, 45fps, 30fps
Test: Youtube video playback on 24fps, 25fps, 30fps, and 60fps
Change-Id: Ia6b1f2a1d78e257e0de99ba12c14ca3721b4ad26
parent 8f1ee7fd
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -405,23 +405,34 @@ Scheduler::RefreshRateType Scheduler::calculateRefreshRateType() {
    }

    // Content detection is on, find the appropriate refresh rate
    // Start with the smallest refresh rate which is greater than the content
    // Start with the smallest refresh rate which is within a margin of the content
    RefreshRateType currRefreshRateType = RefreshRateType::PERFORMANCE;
    constexpr float MARGIN = 0.05f;
    auto iter = mRefreshRateConfigs.getRefreshRates().cbegin();
    RefreshRateType currRefreshRateType = iter->first;
    while (iter != mRefreshRateConfigs.getRefreshRates().cend()) {
        if (iter->second->fps >= mContentRefreshRate) {
        if (iter->second->fps >= mContentRefreshRate * (1 - MARGIN)) {
            currRefreshRateType = iter->first;
            break;
        }
        ++iter;
    }

    if (iter == mRefreshRateConfigs.getRefreshRates().cend()) {
        return RefreshRateType::PERFORMANCE;
    }
    // Some content aligns better on higher refresh rate. For example for 45fps we should choose
    // 90Hz config. However we should still prefer a lower refresh rate if the content doesn't
    // align well with both
    float ratio = mRefreshRateConfigs.getRefreshRate(currRefreshRateType)->fps /
            float(mContentRefreshRate);
    if (std::abs(std::round(ratio) - ratio) > MARGIN) {
        while (iter != mRefreshRateConfigs.getRefreshRates().cend()) {
            ratio = iter->second->fps / float(mContentRefreshRate);

    // TODO(b/129874336): This logic is sub-optimal for content refresh rate that aligns better
    // with a higher refresh rate. For example for 45fps we should choose 90Hz config.
            if (std::abs(std::round(ratio) - ratio) <= MARGIN) {
                currRefreshRateType = iter->first;
                break;
            }
            ++iter;
        }
    }

    return currRefreshRateType;
}