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

Commit 6ad3738d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SurfaceFlinger: Scheduler: move reset callback to scheduler thread"

parents 34ac73e1 a1a49af6
Loading
Loading
Loading
Loading
+35 −11
Original line number Diff line number Diff line
@@ -22,8 +22,9 @@
namespace android {
namespace scheduler {

IdleTimer::IdleTimer(const Interval& interval, const TimeoutCallback& timeoutCallback)
      : mInterval(interval), mTimeoutCallback(timeoutCallback) {}
IdleTimer::IdleTimer(const Interval& interval, const ResetCallback& resetCallback,
                     const TimeoutCallback& timeoutCallback)
      : mInterval(interval), mResetCallback(resetCallback), mTimeoutCallback(timeoutCallback) {}

IdleTimer::~IdleTimer() {
    stop();
@@ -49,11 +50,34 @@ void IdleTimer::stop() {
}

void IdleTimer::loop() {
    while (true) {
        bool triggerReset = false;
        bool triggerTimeout = false;
        {
            std::lock_guard<std::mutex> lock(mMutex);
    while (mState != TimerState::STOPPED) {
            if (mState == TimerState::STOPPED) {
                break;
            }

            if (mState == TimerState::IDLE) {
                mCondition.wait(mMutex);
        } else if (mState == TimerState::RESET) {
                continue;
            }

            if (mState == TimerState::RESET) {
                triggerReset = true;
            }
        }
        if (triggerReset && mResetCallback) {
            mResetCallback();
        }

        { // lock the mutex again. someone might have called stop meanwhile
            std::lock_guard<std::mutex> lock(mMutex);
            if (mState == TimerState::STOPPED) {
                break;
            }

            auto triggerTime = std::chrono::steady_clock::now() + mInterval;
            mState = TimerState::WAITING;
            while (mState == TimerState::WAITING) {
@@ -62,14 +86,14 @@ void IdleTimer::loop() {
                if (waitTime > zero) mCondition.wait_for(mMutex, waitTime);
                if (mState == TimerState::WAITING &&
                    (triggerTime - std::chrono::steady_clock::now()) <= zero) {
                    if (mTimeoutCallback) {
                        mTimeoutCallback();
                    }

                    triggerTimeout = true;
                    mState = TimerState::IDLE;
                }
            }
        }
        if (triggerTimeout && mTimeoutCallback) {
            mTimeoutCallback();
        }
    }
} // namespace scheduler

+6 −1
Original line number Diff line number Diff line
@@ -32,9 +32,11 @@ namespace scheduler {
class IdleTimer {
public:
    using Interval = std::chrono::milliseconds;
    using ResetCallback = std::function<void()>;
    using TimeoutCallback = std::function<void()>;

    IdleTimer(const Interval& interval, const TimeoutCallback& timeoutCallback);
    IdleTimer(const Interval& interval, const ResetCallback& resetCallback,
              const TimeoutCallback& timeoutCallback);
    ~IdleTimer();

    void start();
@@ -62,6 +64,9 @@ private:
    // Interval after which timer expires.
    const Interval mInterval;

    // Callback that happens when timer resets.
    const ResetCallback mResetCallback;

    // Callback that happens when timer expires.
    const TimeoutCallback mTimeoutCallback;
};
+19 −17
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function)
    if (mSetIdleTimerMs > 0) {
        mIdleTimer =
                std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(mSetIdleTimerMs),
                                                       [this] { resetTimerCallback(); },
                                                       [this] { expiredTimerCallback(); });
        mIdleTimer->start();
    }
@@ -87,7 +88,6 @@ Scheduler::~Scheduler() {

sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
        const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
        ResetIdleTimerCallback resetIdleTimerCallback,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
    const int64_t id = sNextId++;
    ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
@@ -97,8 +97,7 @@ sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
                            std::move(interceptCallback));

    auto eventThreadConnection =
            createConnectionInternal(eventThread.get(), std::move(resyncCallback),
                                     std::move(resetIdleTimerCallback));
            createConnectionInternal(eventThread.get(), std::move(resyncCallback));
    mConnections.emplace(id,
                         std::make_unique<Connection>(new ConnectionHandle(id),
                                                      eventThreadConnection,
@@ -115,26 +114,17 @@ std::unique_ptr<EventThread> Scheduler::makeEventThread(
                                               std::move(interceptCallback), connectionName);
}

sp<EventThreadConnection> Scheduler::createConnectionInternal(
        EventThread* eventThread, ResyncCallback&& resyncCallback,
        ResetIdleTimerCallback&& resetIdleTimerCallback) {
sp<EventThreadConnection> Scheduler::createConnectionInternal(EventThread* eventThread,
                                                              ResyncCallback&& resyncCallback) {
    return eventThread->createEventConnection(std::move(resyncCallback),
                                              [this,
                                               resetIdleTimerCallback =
                                                       std::move(resetIdleTimerCallback)] {
                                                  resetIdleTimer();
                                                  if (resetIdleTimerCallback) {
                                                      resetIdleTimerCallback();
                                                  }
                                              });
                                              [this] { resetIdleTimer(); });
}

sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback,
        ResetIdleTimerCallback resetIdleTimerCallback) {
        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback) {
    RETURN_VALUE_IF_INVALID(nullptr);
    return createConnectionInternal(mConnections[handle->id]->thread.get(),
                                    std::move(resyncCallback), std::move(resetIdleTimerCallback));
                                    std::move(resyncCallback));
}

EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
@@ -263,6 +253,11 @@ void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expi
    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) {
@@ -351,6 +346,13 @@ void Scheduler::determineTimestampAverage(bool isAutoTimestamp, const nsecs_t fr
void Scheduler::resetIdleTimer() {
    if (mIdleTimer) {
        mIdleTimer->reset();
    }
}

void Scheduler::resetTimerCallback() {
    std::lock_guard<std::mutex> lock(mCallbackLock);
    if (mResetTimerCallback) {
        mResetTimerCallback();
        ATRACE_INT("ExpiredIdleTimer", 0);
    }
}
+9 −6
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ class EventControlThread;
class Scheduler {
public:
    using ExpiredIdleTimerCallback = std::function<void()>;
    using ResetIdleTimerCallback = std::function<void()>;

    // Enum to indicate whether to start the transaction early, or at vsync time.
    enum class TransactionStart { EARLY, NORMAL };
@@ -72,12 +73,11 @@ public:

    /** Creates an EventThread connection. */
    sp<ConnectionHandle> createConnection(const char* connectionName, int64_t phaseOffsetNs,
                                          ResyncCallback, ResetIdleTimerCallback,
                                          ResyncCallback,
                                          impl::EventThread::InterceptVSyncsCallback);

    sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle,
                                                             ResyncCallback,
                                                             ResetIdleTimerCallback);
                                                             ResyncCallback);

    // Getter methods.
    EventThread* getEventThread(const sp<ConnectionHandle>& handle);
@@ -117,6 +117,8 @@ public:
    void incrementFrameCounter();
    // Callback that gets invoked once the idle timer expires.
    void setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback);
    // Callback that gets invoked once the idle timer is reset.
    void setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback);
    // Returns relevant information about Scheduler for dumpsys purposes.
    std::string doDump();

@@ -127,8 +129,7 @@ protected:

private:
    // Creates a connection on the given EventThread and forwards the given callbacks.
    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&,
                                                       ResetIdleTimerCallback&&);
    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&);

    nsecs_t calculateAverage() const;
    void updateFrameSkipping(const int64_t skipCount);
@@ -140,10 +141,11 @@ private:
    void determineTimestampAverage(bool isAutoTimestamp, const nsecs_t framePresentTime);
    // Function that resets the idle timer.
    void resetIdleTimer();
    // Function that is called when the timer resets.
    void resetTimerCallback();
    // Function that is called when the timer expires.
    void expiredTimerCallback();


    // If fences from sync Framework are supported.
    const bool mHasSyncFramework;

@@ -184,6 +186,7 @@ private:

    std::mutex mCallbackLock;
    ExpiredIdleTimerCallback mExpiredTimerCallback GUARDED_BY(mCallbackLock);
    ExpiredIdleTimerCallback mResetTimerCallback GUARDED_BY(mCallbackLock);
};

} // namespace android
+7 −13
Original line number Diff line number Diff line
@@ -635,17 +635,13 @@ void SurfaceFlinger::init() {
        mPhaseOffsets->setRefreshRateType(
                scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE);

        auto resetIdleTimerCallback =
                std::bind(&SurfaceFlinger::setRefreshRateTo, this, RefreshRateType::PERFORMANCE);

        mAppConnectionHandle =
                mScheduler->createConnection("appConnection", mPhaseOffsets->getCurrentAppOffset(),
                                             resyncCallback, resetIdleTimerCallback,
                                             resyncCallback,
                                             impl::EventThread::InterceptVSyncsCallback());
        mSfConnectionHandle =
                mScheduler->createConnection("sfConnection", mPhaseOffsets->getCurrentSfOffset(),
                                             resyncCallback, resetIdleTimerCallback,
                                             [this](nsecs_t timestamp) {
                                             resyncCallback, [this](nsecs_t timestamp) {
                                                 mInterceptor->saveVSyncEvent(timestamp);
                                             });

@@ -749,6 +745,10 @@ void SurfaceFlinger::init() {
            Mutex::Autolock lock(mStateLock);
            setRefreshRateTo(RefreshRateType::DEFAULT);
        });
        mScheduler->setResetIdleTimerCallback([this] {
            Mutex::Autolock lock(mStateLock);
            setRefreshRateTo(RefreshRateType::PERFORMANCE);
        });

        mRefreshRateStats =
                std::make_unique<scheduler::RefreshRateStats>(getHwComposer().getConfigs(
@@ -1345,16 +1345,10 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
    });

    if (mUseScheduler) {
        auto resetIdleTimerCallback = [this] {
            Mutex::Autolock lock(mStateLock);
            setRefreshRateTo(RefreshRateType::PERFORMANCE);
        };

        const auto& handle = vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle
                                                                       : mAppConnectionHandle;

        return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback),
                                                        std::move(resetIdleTimerCallback));
        return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
    } else {
        if (vsyncSource == eVsyncSourceSurfaceFlinger) {
            return mSFEventThread->createEventConnection(resyncCallback, ResetIdleTimerCallback());
Loading