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

Commit 7d1d6830 authored by Ana Krulec's avatar Ana Krulec
Browse files

SF: Adding callback to Scheduler for setting refresh rate to 60 and 90.

When device is idle, refresh rate is set to 60. When not it's set to 90.

See go/surface-flinger-scheduler for more info.

Test: All SF tests pass.
Bug: 113612090
Bug: 122347908
Change-Id: Ica6e483118db276f72d3cb4e79535303c76f99d7
parent 426f6e90
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -67,7 +67,13 @@ status_t EventThreadConnection::setVsyncRate(uint32_t count) {
}

void EventThreadConnection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
    ATRACE_NAME("requestNextVsync");
    mEventThread->requestNextVsync(this, true);
}

void EventThreadConnection::requestNextVsyncForHWC() {
    ATRACE_NAME("requestNextVsyncForHWC");
    mEventThread->requestNextVsync(this, false);
}

status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
@@ -184,16 +190,17 @@ void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>&
    }
}

void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
    std::lock_guard<std::mutex> lock(mMutex);
    if (mResetIdleTimer) {
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection, bool reset) {
    if (mResetIdleTimer && reset) {
        ATRACE_NAME("resetIdleTimer");
        mResetIdleTimer();
    }

    if (mResyncWithRateLimitCallback) {
        mResyncWithRateLimitCallback();
    }

    std::lock_guard<std::mutex> lock(mMutex);

    if (connection->count < 0) {
        connection->count = 0;
        mCondition.notify_all();
+11 −2
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ public:
    status_t stealReceiveChannel(gui::BitTube* outChannel) override;
    status_t setVsyncRate(uint32_t count) override;
    void requestNextVsync() override; // asynchronous
    // Requesting Vsync for HWC does not reset the idle timer, since HWC requires a refresh
    // in order to update the configs.
    void requestNextVsyncForHWC();

    // count >= 1 : continuous event. count is the vsync rate
    // count == 0 : one-shot event that has not fired
@@ -105,7 +108,9 @@ public:
    virtual status_t registerDisplayEventConnection(
            const sp<EventThreadConnection>& connection) = 0;
    virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0;
    virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
    // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
    virtual void requestNextVsync(const sp<EventThreadConnection>& connection,
                                  bool resetIdleTimer) = 0;
};

namespace impl {
@@ -129,7 +134,8 @@ public:

    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
    void requestNextVsync(const sp<EventThreadConnection>& connection) override;
    void requestNextVsync(const sp<EventThreadConnection>& connection,
                          bool resetIdleTimer) override;

    // called before the screen is turned off from main thread
    void onScreenReleased() override;
@@ -166,6 +172,9 @@ private:
    // Implements VSyncSource::Callback
    void onVSyncEvent(nsecs_t timestamp) override;

    // Acquires mutex and requests next vsync.
    void requestNextVsyncInternal(const sp<EventThreadConnection>& connection) EXCLUDES(mMutex);

    // TODO(b/113612090): Once the Scheduler is complete this pointer will become obsolete.
    VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
    std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
+4 −0
Original line number Diff line number Diff line
@@ -148,6 +148,10 @@ void MessageQueue::invalidate() {
    mEvents->requestNextVsync();
}

void MessageQueue::invalidateForHWC() {
    mEvents->requestNextVsyncForHWC();
}

void MessageQueue::refresh() {
    mHandler->dispatchRefresh();
}
+4 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ public:
    virtual void waitMessage() = 0;
    virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
    virtual void invalidate() = 0;
    virtual void invalidateForHWC() = 0;
    virtual void refresh() = 0;
};

@@ -134,6 +135,9 @@ public:

    // sends INVALIDATE message at next VSYNC
    void invalidate() override;

    // sends INVALIDATE message at next VSYNC, without resetting the idle timer in the Scheduler
    void invalidateForHWC();
    // sends REFRESH message at next VSYNC
    void refresh() override;
};
+23 −7
Original line number Diff line number Diff line
@@ -238,6 +238,16 @@ void Scheduler::incrementFrameCounter() {
    mLayerHistory.incrementCounter();
}

void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback) {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    mExpiredTimerCallback = expiredTimerCallback;
}

void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    mResetTimerCallback = resetTimerCallback;
}

void Scheduler::updateFrameSkipping(const int64_t skipCount) {
    ATRACE_INT("FrameSkipCount", skipCount);
    if (mSkipCount != skipCount) {
@@ -314,12 +324,12 @@ void Scheduler::determineTimestampAverage(bool isAutoTimestamp, const nsecs_t fr
    // TODO(b/113612090): This are current numbers from trial and error while running videos
    // from YouTube at 24, 30, and 60 fps.
    if (mean > 14 && mean < 18) {
        ATRACE_INT("FPS", 60);
        ATRACE_INT("MediaFPS", 60);
    } else if (mean > 31 && mean < 34) {
        ATRACE_INT("FPS", 30);
        ATRACE_INT("MediaFPS", 30);
        return;
    } else if (mean > 39 && mean < 42) {
        ATRACE_INT("FPS", 24);
        ATRACE_INT("MediaFPS", 24);
    }
}

@@ -328,13 +338,19 @@ void Scheduler::resetIdleTimer() {
        mIdleTimer->reset();
        ATRACE_INT("ExpiredIdleTimer", 0);
    }

    std::lock_guard<std::mutex> lock(mCallbackLock);
    if (mResetTimerCallback) {
        mResetTimerCallback();
    }
}

void Scheduler::expiredTimerCallback() {
    // TODO(b/113612090): Each time a timer expired, we should record the information into
    // a circular buffer. Once this has happened a given amount (TBD) of times, we can comfortably
    // say that the device is sitting in idle.
    std::lock_guard<std::mutex> lock(mCallbackLock);
    if (mExpiredTimerCallback) {
        mExpiredTimerCallback();
        ATRACE_INT("ExpiredIdleTimer", 1);
    }
}

} // namespace android
Loading