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

Commit a2ca8644 authored by Ady Abraham's avatar Ady Abraham Committed by Automerger Merge Worker
Browse files

Merge "SF: allow more than one client to use eEarly[Start|End] flags" into sc-dev am: 1d5541d4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15287926

Change-Id: I1646d1380aa5e0fa350b50a8ce38409869e98612
parents be5e3975 1d5541d4
Loading
Loading
Loading
Loading
+28 −12
Original line number Original line Diff line number Diff line
@@ -46,27 +46,36 @@ VsyncModulator::VsyncConfig VsyncModulator::setVsyncConfigSet(const VsyncConfigS
    return updateVsyncConfigLocked();
    return updateVsyncConfigLocked();
}
}


VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule(
VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule(TransactionSchedule schedule,
        TransactionSchedule schedule) {
                                                                      const sp<IBinder>& token) {
    std::lock_guard<std::mutex> lock(mMutex);
    switch (schedule) {
    switch (schedule) {
        case Schedule::EarlyStart:
        case Schedule::EarlyStart:
            ALOGW_IF(mEarlyWakeup, "%s: Duplicate EarlyStart", __FUNCTION__);
            if (token) {
            mEarlyWakeup = true;
                mEarlyWakeupRequests.emplace(token);
                token->linkToDeath(this);
            } else {
                ALOGW("%s: EarlyStart requested without a valid token", __func__);
            }
            break;
            break;
        case Schedule::EarlyEnd:
        case Schedule::EarlyEnd: {
            ALOGW_IF(!mEarlyWakeup, "%s: Unexpected EarlyEnd", __FUNCTION__);
            if (token && mEarlyWakeupRequests.erase(token) > 0) {
            mEarlyWakeup = false;
                token->unlinkToDeath(this);
            } else {
                ALOGW("%s: Unexpected EarlyEnd", __func__);
            }
            break;
            break;
        }
        case Schedule::Late:
        case Schedule::Late:
            // No change to mEarlyWakeup for non-explicit states.
            // No change to mEarlyWakeup for non-explicit states.
            break;
            break;
    }
    }


    if (mTraceDetailedInfo) {
    if (mTraceDetailedInfo) {
        ATRACE_INT("mEarlyWakeup", mEarlyWakeup);
        ATRACE_INT("mEarlyWakeup", static_cast<int>(mEarlyWakeupRequests.size()));
    }
    }


    if (!mEarlyWakeup && schedule == Schedule::EarlyEnd) {
    if (mEarlyWakeupRequests.empty() && schedule == Schedule::EarlyEnd) {
        mEarlyTransactionFrames = MIN_EARLY_TRANSACTION_FRAMES;
        mEarlyTransactionFrames = MIN_EARLY_TRANSACTION_FRAMES;
        mEarlyTransactionStartTime = mNow();
        mEarlyTransactionStartTime = mNow();
    }
    }
@@ -76,7 +85,7 @@ VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule(
        return std::nullopt;
        return std::nullopt;
    }
    }
    mTransactionSchedule = schedule;
    mTransactionSchedule = schedule;
    return updateVsyncConfig();
    return updateVsyncConfigLocked();
}
}


VsyncModulator::VsyncConfigOpt VsyncModulator::onTransactionCommit() {
VsyncModulator::VsyncConfigOpt VsyncModulator::onTransactionCommit() {
@@ -128,8 +137,8 @@ VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const {
const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const {
const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const {
    // Early offsets are used if we're in the middle of a refresh rate
    // Early offsets are used if we're in the middle of a refresh rate
    // change, or if we recently begin a transaction.
    // change, or if we recently begin a transaction.
    if (mEarlyWakeup || mTransactionSchedule == Schedule::EarlyEnd || mEarlyTransactionFrames > 0 ||
    if (!mEarlyWakeupRequests.empty() || mTransactionSchedule == Schedule::EarlyEnd ||
        mRefreshRateChangePending) {
        mEarlyTransactionFrames > 0 || mRefreshRateChangePending) {
        return mVsyncConfigSet.early;
        return mVsyncConfigSet.early;
    } else if (mEarlyGpuFrames > 0) {
    } else if (mEarlyGpuFrames > 0) {
        return mVsyncConfigSet.earlyGpu;
        return mVsyncConfigSet.earlyGpu;
@@ -160,4 +169,11 @@ VsyncModulator::VsyncConfig VsyncModulator::updateVsyncConfigLocked() {
    return offsets;
    return offsets;
}
}


void VsyncModulator::binderDied(const wp<IBinder>& who) {
    std::lock_guard<std::mutex> lock(mMutex);
    mEarlyWakeupRequests.erase(who);

    static_cast<void>(updateVsyncConfigLocked());
}

} // namespace android::scheduler
} // namespace android::scheduler
+16 −3
Original line number Original line Diff line number Diff line
@@ -19,8 +19,10 @@
#include <chrono>
#include <chrono>
#include <mutex>
#include <mutex>
#include <optional>
#include <optional>
#include <unordered_set>


#include <android-base/thread_annotations.h>
#include <android-base/thread_annotations.h>
#include <binder/IBinder.h>
#include <utils/Timers.h>
#include <utils/Timers.h>


namespace android::scheduler {
namespace android::scheduler {
@@ -35,7 +37,7 @@ enum class TransactionSchedule {
};
};


// Modulates VSYNC phase depending on transaction schedule and refresh rate changes.
// Modulates VSYNC phase depending on transaction schedule and refresh rate changes.
class VsyncModulator {
class VsyncModulator : public IBinder::DeathRecipient {
public:
public:
    // Number of frames to keep early offsets after an early transaction or GPU composition.
    // Number of frames to keep early offsets after an early transaction or GPU composition.
    // This acts as a low-pass filter in case subsequent transactions are delayed, or if the
    // This acts as a low-pass filter in case subsequent transactions are delayed, or if the
@@ -91,7 +93,8 @@ public:
    [[nodiscard]] VsyncConfig setVsyncConfigSet(const VsyncConfigSet&) EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfig setVsyncConfigSet(const VsyncConfigSet&) EXCLUDES(mMutex);


    // Changes offsets in response to transaction flags or commit.
    // Changes offsets in response to transaction flags or commit.
    [[nodiscard]] VsyncConfigOpt setTransactionSchedule(TransactionSchedule);
    [[nodiscard]] VsyncConfigOpt setTransactionSchedule(TransactionSchedule,
                                                        const sp<IBinder>& = {}) EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfigOpt onTransactionCommit();
    [[nodiscard]] VsyncConfigOpt onTransactionCommit();


    // Called when we send a refresh rate change to hardware composer, so that
    // Called when we send a refresh rate change to hardware composer, so that
@@ -104,6 +107,10 @@ public:


    [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition);
    [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition);


protected:
    // Called from unit tests as well
    void binderDied(const wp<IBinder>&) override EXCLUDES(mMutex);

private:
private:
    const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex);
    const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex);
@@ -116,8 +123,14 @@ private:


    using Schedule = TransactionSchedule;
    using Schedule = TransactionSchedule;
    std::atomic<Schedule> mTransactionSchedule = Schedule::Late;
    std::atomic<Schedule> mTransactionSchedule = Schedule::Late;
    std::atomic<bool> mEarlyWakeup = false;


    struct WpHash {
        size_t operator()(const wp<IBinder>& p) const {
            return std::hash<IBinder*>()(p.unsafe_get());
        }
    };

    std::unordered_set<wp<IBinder>, WpHash> mEarlyWakeupRequests GUARDED_BY(mMutex);
    std::atomic<bool> mRefreshRateChangePending = false;
    std::atomic<bool> mRefreshRateChangePending = false;


    std::atomic<int> mEarlyTransactionFrames = 0;
    std::atomic<int> mEarlyTransactionFrames = 0;
+5 −4
Original line number Original line Diff line number Diff line
@@ -3157,7 +3157,7 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
                                                                      hal::PowerMode::OFF);
                                                                      hal::PowerMode::OFF);


    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
    mVsyncModulator.emplace(mVsyncConfiguration->getCurrentConfigs());
    mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());


    // start the EventThread
    // start the EventThread
    mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
    mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
@@ -3437,9 +3437,10 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
    return setTransactionFlags(flags, TransactionSchedule::Late);
    return setTransactionFlags(flags, TransactionSchedule::Late);
}
}


uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, TransactionSchedule schedule) {
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, TransactionSchedule schedule,
                                             const sp<IBinder>& token) {
    uint32_t old = mTransactionFlags.fetch_or(flags);
    uint32_t old = mTransactionFlags.fetch_or(flags);
    modulateVsync(&VsyncModulator::setTransactionSchedule, schedule);
    modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, token);
    if ((old & flags) == 0) signalTransaction();
    if ((old & flags) == 0) signalTransaction();
    return old;
    return old;
}
}
@@ -3659,7 +3660,7 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) {
        return TransactionSchedule::Late;
        return TransactionSchedule::Late;
    }(state.flags);
    }(state.flags);


    setTransactionFlags(eTransactionFlushNeeded, schedule);
    setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken);
}
}


void SurfaceFlinger::waitForSynchronousTransaction(
void SurfaceFlinger::waitForSynchronousTransaction(
+2 −2
Original line number Original line Diff line number Diff line
@@ -851,7 +851,7 @@ private:
    // but there is no need to try and wake up immediately to do it. Rather we rely on
    // but there is no need to try and wake up immediately to do it. Rather we rely on
    // onFrameAvailable or another layer update to wake us up.
    // onFrameAvailable or another layer update to wake us up.
    void setTraversalNeeded();
    void setTraversalNeeded();
    uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule);
    uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule, const sp<IBinder>& = {});
    void commitTransaction() REQUIRES(mStateLock);
    void commitTransaction() REQUIRES(mStateLock);
    void commitOffscreenLayers();
    void commitOffscreenLayers();
    bool transactionIsReadyToBeApplied(
    bool transactionIsReadyToBeApplied(
@@ -1389,7 +1389,7 @@ private:
    std::unique_ptr<scheduler::VsyncConfiguration> mVsyncConfiguration;
    std::unique_ptr<scheduler::VsyncConfiguration> mVsyncConfiguration;


    // Optional to defer construction until PhaseConfiguration is created.
    // Optional to defer construction until PhaseConfiguration is created.
    std::optional<scheduler::VsyncModulator> mVsyncModulator;
    sp<VsyncModulator> mVsyncModulator;


    std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
    std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
    std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
    std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
+2 −1
Original line number Original line Diff line number Diff line
@@ -230,7 +230,8 @@ public:
                std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps,
                std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps,
                                                              /*powerMode=*/hal::PowerMode::OFF);
                                                              /*powerMode=*/hal::PowerMode::OFF);
        mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(currFps);
        mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(currFps);
        mFlinger->mVsyncModulator.emplace(mFlinger->mVsyncConfiguration->getCurrentConfigs());
        mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make(
                mFlinger->mVsyncConfiguration->getCurrentConfigs());


        mScheduler = new TestableScheduler(std::move(vsyncController), std::move(vsyncTracker),
        mScheduler = new TestableScheduler(std::move(vsyncController), std::move(vsyncTracker),
                                           *mFlinger->mRefreshRateConfigs, *(callback ?: this));
                                           *mFlinger->mRefreshRateConfigs, *(callback ?: this));
Loading