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

Commit 671249c8 authored by Leon Scroggins's avatar Leon Scroggins Committed by Automerger Merge Worker
Browse files

Merge "Rename "leader" display to "pacesetter"" into udc-dev am: 43e9083b

parents d0b6ac5f 43e9083b
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -510,21 +510,21 @@ void DisplayDevice::clearDesiredActiveModeState() {
    mDesiredActiveModeChanged = false;
}

void DisplayDevice::adjustRefreshRate(Fps leaderDisplayRefreshRate) {
void DisplayDevice::adjustRefreshRate(Fps pacesetterDisplayRefreshRate) {
    using fps_approx_ops::operator==;
    if (mRequestedRefreshRate == 0_Hz) {
        return;
    }

    using fps_approx_ops::operator>;
    if (mRequestedRefreshRate > leaderDisplayRefreshRate) {
        mAdjustedRefreshRate = leaderDisplayRefreshRate;
    if (mRequestedRefreshRate > pacesetterDisplayRefreshRate) {
        mAdjustedRefreshRate = pacesetterDisplayRefreshRate;
        return;
    }

    unsigned divisor = static_cast<unsigned>(
            std::round(leaderDisplayRefreshRate.getValue() / mRequestedRefreshRate.getValue()));
    mAdjustedRefreshRate = leaderDisplayRefreshRate / divisor;
            std::round(pacesetterDisplayRefreshRate.getValue() / mRequestedRefreshRate.getValue()));
    mAdjustedRefreshRate = pacesetterDisplayRefreshRate / divisor;
}

std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
+3 −3
Original line number Diff line number Diff line
@@ -247,9 +247,9 @@ public:

    Fps getAdjustedRefreshRate() const { return mAdjustedRefreshRate; }

    // Round the requested refresh rate to match a divisor of the leader
    // Round the requested refresh rate to match a divisor of the pacesetter
    // display's refresh rate. Only supported for virtual displays.
    void adjustRefreshRate(Fps leaderDisplayRefreshRate);
    void adjustRefreshRate(Fps pacesetterDisplayRefreshRate);

    // release HWC resources (if any) for removable displays
    void disconnect();
@@ -290,7 +290,7 @@ private:
    // for virtual displays to match this requested refresh rate.
    const Fps mRequestedRefreshRate;

    // Adjusted refresh rate, rounded to match a divisor of the leader
    // Adjusted refresh rate, rounded to match a divisor of the pacesetter
    // display's refresh rate. Only supported for virtual displays.
    Fps mAdjustedRefreshRate = 0_Hz;

+2 −1
Original line number Diff line number Diff line
@@ -196,7 +196,8 @@ Layer::Layer(const LayerCreationArgs& args)
        mDrawingState.color.b = -1.0_hf;
    }

    mFrameTracker.setDisplayRefreshPeriod(args.flinger->mScheduler->getLeaderVsyncPeriod().ns());
    mFrameTracker.setDisplayRefreshPeriod(
            args.flinger->mScheduler->getPacesetterVsyncPeriod().ns());

    mOwnerUid = args.ownerUid;
    mOwnerPid = args.ownerPid;
+49 −48
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ Scheduler::~Scheduler() {
    mTouchTimer.reset();

    // Stop idle timer and clear callbacks, as the RefreshRateSelector may outlive the Scheduler.
    demoteLeaderDisplay();
    demotePacesetterDisplay();
}

void Scheduler::startTimers() {
@@ -106,11 +106,11 @@ void Scheduler::startTimers() {
    }
}

void Scheduler::setLeaderDisplay(std::optional<PhysicalDisplayId> leaderIdOpt) {
    demoteLeaderDisplay();
void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
    demotePacesetterDisplay();

    std::scoped_lock lock(mDisplayLock);
    promoteLeaderDisplay(leaderIdOpt);
    promotePacesetterDisplay(pacesetterIdOpt);
}

void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
@@ -121,17 +121,17 @@ void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelector
void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
                                        RefreshRateSelectorPtr selectorPtr,
                                        std::shared_ptr<VsyncSchedule> vsyncSchedule) {
    demoteLeaderDisplay();
    demotePacesetterDisplay();

    std::scoped_lock lock(mDisplayLock);
    mRefreshRateSelectors.emplace_or_replace(displayId, std::move(selectorPtr));
    mVsyncSchedules.emplace_or_replace(displayId, std::move(vsyncSchedule));

    promoteLeaderDisplay();
    promotePacesetterDisplay();
}

void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
    demoteLeaderDisplay();
    demotePacesetterDisplay();

    std::scoped_lock lock(mDisplayLock);
    mRefreshRateSelectors.erase(displayId);
@@ -142,7 +142,7 @@ void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
    // headless virtual display.)
    LOG_ALWAYS_FATAL_IF(mRefreshRateSelectors.empty(), "Cannot unregister all displays!");

    promoteLeaderDisplay();
    promotePacesetterDisplay();
}

void Scheduler::run() {
@@ -165,7 +165,7 @@ void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,

std::optional<Fps> Scheduler::getFrameRateOverride(uid_t uid) const {
    const bool supportsFrameRateOverrideByContent =
            leaderSelectorPtr()->supportsAppFrameRateOverrideByContent();
            pacesetterSelectorPtr()->supportsAppFrameRateOverrideByContent();
    return mFrameRateOverrideMappings
            .getFrameRateOverrideForUid(uid, supportsFrameRateOverrideByContent);
}
@@ -192,7 +192,7 @@ impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback()

impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
    return [this](uid_t uid) {
        const Fps refreshRate = leaderSelectorPtr()->getActiveMode().fps;
        const Fps refreshRate = pacesetterSelectorPtr()->getActiveMode().fps;
        const nsecs_t currentPeriod =
                getVsyncSchedule()->period().ns() ?: refreshRate.getPeriodNsecs();

@@ -285,7 +285,7 @@ void Scheduler::enableSyntheticVsync(bool enable) {

void Scheduler::onFrameRateOverridesChanged(ConnectionHandle handle, PhysicalDisplayId displayId) {
    const bool supportsFrameRateOverrideByContent =
            leaderSelectorPtr()->supportsAppFrameRateOverrideByContent();
            pacesetterSelectorPtr()->supportsAppFrameRateOverrideByContent();

    std::vector<FrameRateOverride> overrides =
            mFrameRateOverrideMappings.getAllFrameRateOverrides(supportsFrameRateOverrideByContent);
@@ -326,7 +326,7 @@ void Scheduler::dispatchCachedReportedMode() {
    // If the mode is not the current mode, this means that a
    // mode change is in progress. In that case we shouldn't dispatch an event
    // as it will be dispatched when the current mode changes.
    if (leaderSelectorPtr()->getActiveMode() != mPolicy.modeOpt) {
    if (pacesetterSelectorPtr()->getActiveMode() != mPolicy.modeOpt) {
        return;
    }

@@ -489,7 +489,7 @@ void Scheduler::deregisterLayer(Layer* layer) {

void Scheduler::recordLayerHistory(Layer* layer, nsecs_t presentTime,
                                   LayerHistory::LayerUpdateType updateType) {
    if (leaderSelectorPtr()->canSwitch()) {
    if (pacesetterSelectorPtr()->canSwitch()) {
        mLayerHistory.record(layer, presentTime, systemTime(), updateType);
    }
}
@@ -504,7 +504,7 @@ void Scheduler::setDefaultFrameRateCompatibility(Layer* layer) {
}

void Scheduler::chooseRefreshRateForContent() {
    const auto selectorPtr = leaderSelectorPtr();
    const auto selectorPtr = pacesetterSelectorPtr();
    if (!selectorPtr->canSwitch()) return;

    ATRACE_CALL();
@@ -514,22 +514,22 @@ void Scheduler::chooseRefreshRateForContent() {
}

void Scheduler::resetIdleTimer() {
    leaderSelectorPtr()->resetIdleTimer();
    pacesetterSelectorPtr()->resetIdleTimer();
}

void Scheduler::onTouchHint() {
    if (mTouchTimer) {
        mTouchTimer->reset();
        leaderSelectorPtr()->resetKernelIdleTimer();
        pacesetterSelectorPtr()->resetKernelIdleTimer();
    }
}

void Scheduler::setDisplayPowerMode(PhysicalDisplayId id, hal::PowerMode powerMode) {
    const bool isLeader = [this, id]() REQUIRES(kMainThreadContext) {
    const bool isPacesetter = [this, id]() REQUIRES(kMainThreadContext) {
        ftl::FakeGuard guard(mDisplayLock);
        return id == mLeaderDisplayId;
        return id == mPacesetterDisplayId;
    }();
    if (isLeader) {
    if (isPacesetter) {
        // TODO (b/255657128): This needs to be handled per display.
        std::lock_guard<std::mutex> lock(mPolicyLock);
        mPolicy.displayPowerMode = powerMode;
@@ -539,7 +539,7 @@ void Scheduler::setDisplayPowerMode(PhysicalDisplayId id, hal::PowerMode powerMo
        auto vsyncSchedule = getVsyncScheduleLocked(id);
        vsyncSchedule->getController().setDisplayPowerMode(powerMode);
    }
    if (!isLeader) return;
    if (!isPacesetter) return;

    if (mDisplayPowerTimer) {
        mDisplayPowerTimer->reset();
@@ -560,8 +560,8 @@ std::shared_ptr<const VsyncSchedule> Scheduler::getVsyncScheduleLocked(
        std::optional<PhysicalDisplayId> idOpt) const {
    ftl::FakeGuard guard(kMainThreadContext);
    if (!idOpt) {
        LOG_ALWAYS_FATAL_IF(!mLeaderDisplayId, "Missing a leader!");
        idOpt = mLeaderDisplayId;
        LOG_ALWAYS_FATAL_IF(!mPacesetterDisplayId, "Missing a pacesetter!");
        idOpt = mPacesetterDisplayId;
    }
    auto scheduleOpt = mVsyncSchedules.get(*idOpt);
    LOG_ALWAYS_FATAL_IF(!scheduleOpt);
@@ -573,7 +573,7 @@ void Scheduler::kernelIdleTimerCallback(TimerState state) {

    // TODO(145561154): cleanup the kernel idle timer implementation and the refresh rate
    // magic number
    const Fps refreshRate = leaderSelectorPtr()->getActiveMode().modePtr->getFps();
    const Fps refreshRate = pacesetterSelectorPtr()->getActiveMode().modePtr->getFps();

    constexpr Fps FPS_THRESHOLD_FOR_KERNEL_TIMER = 65_Hz;
    using namespace fps_approx_ops;
@@ -637,7 +637,7 @@ void Scheduler::dump(utils::Dumper& dumper) const {
        {
            std::scoped_lock lock(mDisplayLock);
            ftl::FakeGuard guard(kMainThreadContext);
            dumper.dump("leaderDisplayId"sv, mLeaderDisplayId);
            dumper.dump("pacesetterDisplayId"sv, mPacesetterDisplayId);
        }
        dumper.dump("layerHistory"sv, mLayerHistory.dump());
        dumper.dump("touchTimer"sv, mTouchTimer.transform(&OneShotTimer::interval));
@@ -651,13 +651,13 @@ void Scheduler::dump(utils::Dumper& dumper) const {
void Scheduler::dumpVsync(std::string& out) const {
    std::scoped_lock lock(mDisplayLock);
    ftl::FakeGuard guard(kMainThreadContext);
    if (mLeaderDisplayId) {
        base::StringAppendF(&out, "VsyncSchedule for leader %s:\n",
                            to_string(*mLeaderDisplayId).c_str());
    if (mPacesetterDisplayId) {
        base::StringAppendF(&out, "VsyncSchedule for pacesetter %s:\n",
                            to_string(*mPacesetterDisplayId).c_str());
        getVsyncScheduleLocked()->dump(out);
    }
    for (auto& [id, vsyncSchedule] : mVsyncSchedules) {
        if (id == mLeaderDisplayId) {
        if (id == mPacesetterDisplayId) {
            continue;
        }
        base::StringAppendF(&out, "VsyncSchedule for follower %s:\n", to_string(id).c_str());
@@ -669,7 +669,7 @@ bool Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps di
    if (consideredSignals.idle) return false;

    const auto frameRateOverrides =
            leaderSelectorPtr()->getFrameRateOverrides(mPolicy.contentRequirements,
            pacesetterSelectorPtr()->getFrameRateOverrides(mPolicy.contentRequirements,
                                                           displayRefreshRate, consideredSignals);

    // Note that RefreshRateSelector::supportsFrameRateOverrideByContent is checked when querying
@@ -677,23 +677,23 @@ bool Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps di
    return mFrameRateOverrideMappings.updateFrameRateOverridesByContent(frameRateOverrides);
}

void Scheduler::promoteLeaderDisplay(std::optional<PhysicalDisplayId> leaderIdOpt) {
    // TODO(b/241286431): Choose the leader display.
    mLeaderDisplayId = leaderIdOpt.value_or(mRefreshRateSelectors.begin()->first);
    ALOGI("Display %s is the leader", to_string(*mLeaderDisplayId).c_str());
void Scheduler::promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
    // TODO(b/241286431): Choose the pacesetter display.
    mPacesetterDisplayId = pacesetterIdOpt.value_or(mRefreshRateSelectors.begin()->first);
    ALOGI("Display %s is the pacesetter", to_string(*mPacesetterDisplayId).c_str());

    auto vsyncSchedule = getVsyncScheduleLocked(*mLeaderDisplayId);
    if (const auto leaderPtr = leaderSelectorPtrLocked()) {
        leaderPtr->setIdleTimerCallbacks(
    auto vsyncSchedule = getVsyncScheduleLocked(*mPacesetterDisplayId);
    if (const auto pacesetterPtr = pacesetterSelectorPtrLocked()) {
        pacesetterPtr->setIdleTimerCallbacks(
                {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
                              .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
                 .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
                            .onExpired =
                                    [this] { kernelIdleTimerCallback(TimerState::Expired); }}});

        leaderPtr->startIdleTimer();
        pacesetterPtr->startIdleTimer();

        const Fps refreshRate = leaderPtr->getActiveMode().modePtr->getFps();
        const Fps refreshRate = pacesetterPtr->getActiveMode().modePtr->getFps();
        vsyncSchedule->startPeriodTransition(mSchedulerCallback, refreshRate.getPeriod(),
                                             true /* force */);
    }
@@ -707,14 +707,14 @@ void Scheduler::promoteLeaderDisplay(std::optional<PhysicalDisplayId> leaderIdOp
    }
}

void Scheduler::demoteLeaderDisplay() {
void Scheduler::demotePacesetterDisplay() {
    // No need to lock for reads on kMainThreadContext.
    if (const auto leaderPtr = FTL_FAKE_GUARD(mDisplayLock, leaderSelectorPtrLocked())) {
        leaderPtr->stopIdleTimer();
        leaderPtr->clearIdleTimerCallbacks();
    if (const auto pacesetterPtr = FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
        pacesetterPtr->stopIdleTimer();
        pacesetterPtr->clearIdleTimerCallbacks();
    }

    // Clear state that depends on the leader's RefreshRateSelector.
    // Clear state that depends on the pacesetter's RefreshRateSelector.
    std::scoped_lock lock(mPolicyLock);
    mPolicy = {};
}
@@ -743,10 +743,11 @@ auto Scheduler::applyPolicy(S Policy::*statePtr, T&& newState) -> GlobalSignals

            modeChoices = chooseDisplayModes();

            // TODO(b/240743786): The leader display's mode must change for any DisplayModeRequest
            // to go through. Fix this by tracking per-display Scheduler::Policy and timers.
            // TODO(b/240743786): The pacesetter display's mode must change for any
            // DisplayModeRequest to go through. Fix this by tracking per-display Scheduler::Policy
            // and timers.
            std::tie(modeOpt, consideredSignals) =
                    modeChoices.get(*mLeaderDisplayId)
                    modeChoices.get(*mPacesetterDisplayId)
                            .transform([](const DisplayModeChoice& choice) {
                                return std::make_pair(choice.mode, choice.consideredSignals);
                            })
@@ -879,7 +880,7 @@ GlobalSignals Scheduler::makeGlobalSignals() const {
FrameRateMode Scheduler::getPreferredDisplayMode() {
    std::lock_guard<std::mutex> lock(mPolicyLock);
    const auto frameRateMode =
            leaderSelectorPtr()
            pacesetterSelectorPtr()
                    ->getRankedFrameRates(mPolicy.contentRequirements, makeGlobalSignals())
                    .ranking.front()
                    .frameRateMode;
+26 −26
Original line number Diff line number Diff line
@@ -102,8 +102,8 @@ public:

    void startTimers();

    // TODO(b/241285191): Remove this API by promoting leader in onScreen{Acquired,Released}.
    void setLeaderDisplay(std::optional<PhysicalDisplayId>) REQUIRES(kMainThreadContext)
    // TODO(b/241285191): Remove this API by promoting pacesetter in onScreen{Acquired,Released}.
    void setPacesetterDisplay(std::optional<PhysicalDisplayId>) REQUIRES(kMainThreadContext)
            EXCLUDES(mDisplayLock);

    using RefreshRateSelectorPtr = std::shared_ptr<RefreshRateSelector>;
@@ -167,9 +167,9 @@ public:

    const VsyncModulator& vsyncModulator() const { return *mVsyncModulator; }

    // In some cases, we should only modulate for the leader display. In those
    // In some cases, we should only modulate for the pacesetter display. In those
    // cases, the caller should pass in the relevant display, and the method
    // will no-op if it's not the leader. Other cases are not specific to a
    // will no-op if it's not the pacesetter. Other cases are not specific to a
    // display.
    template <typename... Args,
              typename Handler = std::optional<VsyncConfig> (VsyncModulator::*)(Args...)>
@@ -177,13 +177,13 @@ public:
        if (id) {
            std::scoped_lock lock(mDisplayLock);
            ftl::FakeGuard guard(kMainThreadContext);
            if (id != mLeaderDisplayId) {
            if (id != mPacesetterDisplayId) {
                return;
            }
        }

        if (const auto config = (*mVsyncModulator.*handler)(args...)) {
            setVsyncConfig(*config, getLeaderVsyncPeriod());
            setVsyncConfig(*config, getPacesetterVsyncPeriod());
        }
    }

@@ -254,7 +254,7 @@ public:
    void dump(ConnectionHandle, std::string&) const;
    void dumpVsync(std::string&) const EXCLUDES(mDisplayLock);

    // Returns the preferred refresh rate and frame rate for the leader display.
    // Returns the preferred refresh rate and frame rate for the pacesetter display.
    FrameRateMode getPreferredDisplayMode();

    // Notifies the scheduler about a refresh rate timeline change.
@@ -277,12 +277,12 @@ public:
    // Retrieves the overridden refresh rate for a given uid.
    std::optional<Fps> getFrameRateOverride(uid_t) const EXCLUDES(mDisplayLock);

    Period getLeaderVsyncPeriod() const EXCLUDES(mDisplayLock) {
        return leaderSelectorPtr()->getActiveMode().fps.getPeriod();
    Period getPacesetterVsyncPeriod() const EXCLUDES(mDisplayLock) {
        return pacesetterSelectorPtr()->getActiveMode().fps.getPeriod();
    }

    Fps getLeaderRefreshRate() const EXCLUDES(mDisplayLock) {
        return leaderSelectorPtr()->getActiveMode().fps;
    Fps getPacesetterRefreshRate() const EXCLUDES(mDisplayLock) {
        return pacesetterSelectorPtr()->getActiveMode().fps;
    }

    // Returns the framerate of the layer with the given sequence ID
@@ -318,14 +318,14 @@ private:
    void resyncAllToHardwareVsync(bool allowToEnable) EXCLUDES(mDisplayLock);
    void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod);

    // Chooses a leader among the registered displays, unless `leaderIdOpt` is specified. The new
    // `mLeaderDisplayId` is never `std::nullopt`.
    void promoteLeaderDisplay(std::optional<PhysicalDisplayId> leaderIdOpt = std::nullopt)
    // Chooses a pacesetter among the registered displays, unless `pacesetterIdOpt` is specified.
    // The new `mPacesetterDisplayId` is never `std::nullopt`.
    void promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
            REQUIRES(kMainThreadContext, mDisplayLock);

    // Blocks until the leader's idle timer thread exits. `mDisplayLock` must not be locked by the
    // caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
    void demoteLeaderDisplay() REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock, mPolicyLock);
    // Blocks until the pacesetter's idle timer thread exits. `mDisplayLock` must not be locked by
    // the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
    void demotePacesetterDisplay() REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock, mPolicyLock);

    void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr,
                                 std::shared_ptr<VsyncSchedule>) REQUIRES(kMainThreadContext)
@@ -415,23 +415,23 @@ private:
    display::PhysicalDisplayMap<PhysicalDisplayId, std::shared_ptr<VsyncSchedule>> mVsyncSchedules
            GUARDED_BY(mDisplayLock) GUARDED_BY(kMainThreadContext);

    ftl::Optional<PhysicalDisplayId> mLeaderDisplayId GUARDED_BY(mDisplayLock)
    ftl::Optional<PhysicalDisplayId> mPacesetterDisplayId GUARDED_BY(mDisplayLock)
            GUARDED_BY(kMainThreadContext);

    RefreshRateSelectorPtr leaderSelectorPtr() const EXCLUDES(mDisplayLock) {
    RefreshRateSelectorPtr pacesetterSelectorPtr() const EXCLUDES(mDisplayLock) {
        std::scoped_lock lock(mDisplayLock);
        return leaderSelectorPtrLocked();
        return pacesetterSelectorPtrLocked();
    }

    RefreshRateSelectorPtr leaderSelectorPtrLocked() const REQUIRES(mDisplayLock) {
    RefreshRateSelectorPtr pacesetterSelectorPtrLocked() const REQUIRES(mDisplayLock) {
        ftl::FakeGuard guard(kMainThreadContext);
        const RefreshRateSelectorPtr noLeader;
        return mLeaderDisplayId
                .and_then([this](PhysicalDisplayId leaderId)
        const RefreshRateSelectorPtr noPacesetter;
        return mPacesetterDisplayId
                .and_then([this](PhysicalDisplayId pacesetterId)
                                  REQUIRES(mDisplayLock, kMainThreadContext) {
                                      return mRefreshRateSelectors.get(leaderId);
                                      return mRefreshRateSelectors.get(pacesetterId);
                                  })
                .value_or(std::cref(noLeader));
                .value_or(std::cref(noPacesetter));
    }

    std::shared_ptr<const VsyncSchedule> getVsyncScheduleLocked(
Loading