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

Commit 616b8329 authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: tune FPS detection logic

Keep 200ms of history for layer instead of 100ms to accomodate
scenarios of YouTube playing music and renders at ~6Hz.
In addition, change the way layers are considered relevant for fps
detection to have a time based mechanism as well. Going by frame number
only makes slow layers to become relevant too late.

Fixes: 135009095
Test: YouTube playing music
Change-Id: Id38290e453111c5cfd4a23383b36b6862c2dd386
parent a9bf4cad
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -38,6 +38,12 @@ void LayerInfo::setLastPresentTime(nsecs_t lastPresentTime) {
    mLastUpdatedTime = std::max(lastPresentTime, systemTime());
    mLastUpdatedTime = std::max(lastPresentTime, systemTime());
    mPresentTimeHistory.insertPresentTime(mLastUpdatedTime);
    mPresentTimeHistory.insertPresentTime(mLastUpdatedTime);


    if (mLastPresentTime == 0) {
        // First frame
        mLastPresentTime = lastPresentTime;
        return;
    }

    const nsecs_t timeDiff = lastPresentTime - mLastPresentTime;
    const nsecs_t timeDiff = lastPresentTime - mLastPresentTime;
    mLastPresentTime = lastPresentTime;
    mLastPresentTime = lastPresentTime;
    // Ignore time diff that are too high - those are stale values
    // Ignore time diff that are too high - those are stale values
+17 −7
Original line number Original line Diff line number Diff line
@@ -55,7 +55,7 @@ class LayerInfo {


        float getRefreshRateAvg() const {
        float getRefreshRateAvg() const {
            nsecs_t refreshDuration = mMinRefreshDuration;
            nsecs_t refreshDuration = mMinRefreshDuration;
            if (mElements.size() == HISTORY_SIZE) {
            if (mElements.size() > 0) {
                refreshDuration = scheduler::calculate_mean(mElements);
                refreshDuration = scheduler::calculate_mean(mElements);
            }
            }


@@ -86,21 +86,31 @@ class LayerInfo {
        // Checks whether the present time that was inserted HISTORY_SIZE ago is within a
        // Checks whether the present time that was inserted HISTORY_SIZE ago is within a
        // certain threshold: TIME_EPSILON_NS.
        // certain threshold: TIME_EPSILON_NS.
        bool isRelevant() const {
        bool isRelevant() const {
            const int64_t obsoleteEpsilon = systemTime() - scheduler::TIME_EPSILON_NS.count();
            if (mElements.size() < 2) {
            // The layer had to publish at least HISTORY_SIZE of updates, and the first
                return false;
            // update should not be older than TIME_EPSILON_NS nanoseconds.
            if (mElements.size() == HISTORY_SIZE &&
                mElements.at(HISTORY_SIZE - 1) > obsoleteEpsilon) {
                return true;
            }
            }

            // The layer had to publish at least HISTORY_SIZE or HISTORY_TIME of updates
            if (mElements.size() != HISTORY_SIZE &&
                mElements.at(mElements.size() - 1) - mElements.at(0) < HISTORY_TIME.count()) {
                return false;
                return false;
            }
            }


            // The last update should not be older than TIME_EPSILON_NS nanoseconds.
            const int64_t obsoleteEpsilon = systemTime() - scheduler::TIME_EPSILON_NS.count();
            if (mElements.at(mElements.size() - 1) < obsoleteEpsilon) {
                return false;
            }

            return true;
        }

        void clearHistory() { mElements.clear(); }
        void clearHistory() { mElements.clear(); }


    private:
    private:
        std::deque<nsecs_t> mElements;
        std::deque<nsecs_t> mElements;
        static constexpr size_t HISTORY_SIZE = 10;
        static constexpr size_t HISTORY_SIZE = 10;
        static constexpr std::chrono::nanoseconds HISTORY_TIME = 500ms;
    };
    };


public:
public:
+4 −4
Original line number Original line Diff line number Diff line
@@ -37,12 +37,12 @@ static constexpr int SCREEN_OFF_CONFIG_ID = -1;
static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff;
static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff;


// This number is used when we try to determine how long does a given layer stay relevant.
// This number is used when we try to determine how long does a given layer stay relevant.
// Currently it is set to 100ms, because that would indicate 10Hz rendering.
// The value is set based on testing different scenarios.
static constexpr std::chrono::nanoseconds TIME_EPSILON_NS = 100ms;
static constexpr std::chrono::nanoseconds TIME_EPSILON_NS = 200ms;


// This number is used when we try to determine how long do we keep layer information around
// This number is used when we try to determine how long do we keep layer information around
// before we remove it. Currently it is set to 100ms.
// before we remove it.
static constexpr std::chrono::nanoseconds OBSOLETE_TIME_EPSILON_NS = 100ms;
static constexpr std::chrono::nanoseconds OBSOLETE_TIME_EPSILON_NS = 200ms;


// Calculates the statistical mean (average) in the data structure (array, vector). The
// Calculates the statistical mean (average) in the data structure (array, vector). The
// function does not modify the contents of the array.
// function does not modify the contents of the array.