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

Commit b15b52de authored by Su Hong Koo's avatar Su Hong Koo Committed by Android (Google) Code Review
Browse files

Merge changes Ic021695e,If37b633d into main

* changes:
  SF: Designate pacesetter display in powerOffDuringConcurrentModeSet
  SF: Use specified pacesetterId in designatePacesetterDisplay
parents b2e0f8cf 5beefff9
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ void Scheduler::startTimers() {
}

bool Scheduler::designatePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterId) {
    if (FlagManager::getInstance().pacesetter_selection()) {
    if (FlagManager::getInstance().pacesetter_selection() && !pacesetterId.has_value()) {
        pacesetterId = selectPacesetterDisplay();
    }

@@ -196,7 +196,7 @@ PhysicalDisplayId Scheduler::getPacesetterDisplayId() const {
}

void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
                                PhysicalDisplayId activeDisplayId) {
                                std::optional<PhysicalDisplayId> defaultPacesetterId) {
    auto schedulePtr =
            std::make_shared<VsyncSchedule>(selectorPtr->getActiveMode().modePtr, mFeatures,
                                            [this](PhysicalDisplayId id, bool enable) {
@@ -204,13 +204,13 @@ void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelector
                                            });

    registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr),
                            activeDisplayId);
                            defaultPacesetterId);
}

void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
                                        RefreshRateSelectorPtr selectorPtr,
                                        VsyncSchedulePtr schedulePtr,
                                        PhysicalDisplayId activeDisplayId) {
                                        std::optional<PhysicalDisplayId> defaultPacesetterId) {
    const bool isPrimary = (ftl::FakeGuard(mDisplayLock), !mPacesetterDisplayId);

    // Start the idle timer for the first registered (i.e. primary) display.
@@ -225,7 +225,7 @@ void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
                                                       std::move(schedulePtr), mFeatures)
                                   .second;

        return std::make_pair(promotePacesetterDisplayLocked(activeDisplayId, promotionParams),
        return std::make_pair(promotePacesetterDisplayLocked(defaultPacesetterId, promotionParams),
                              isNew);
    }();

@@ -239,8 +239,10 @@ void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
    dispatchHotplug(displayId, Hotplug::Connected);
}

void Scheduler::unregisterDisplay(PhysicalDisplayId displayId, PhysicalDisplayId activeDisplayId) {
    LOG_ALWAYS_FATAL_IF(displayId == activeDisplayId, "Cannot unregister the active display!");
void Scheduler::unregisterDisplay(PhysicalDisplayId displayId,
                                  std::optional<PhysicalDisplayId> defaultPacesetterId) {
    LOG_ALWAYS_FATAL_IF(displayId == defaultPacesetterId,
                        "Cannot unregister the front internal display!");

    dispatchHotplug(displayId, Hotplug::Disconnected);

@@ -257,7 +259,8 @@ void Scheduler::unregisterDisplay(PhysicalDisplayId displayId, PhysicalDisplayId
        // headless virtual display.)
        LOG_ALWAYS_FATAL_IF(mDisplays.empty(), "Cannot unregister all displays!");

        pacesetterVsyncSchedule = promotePacesetterDisplayLocked(activeDisplayId, kPromotionParams);
        pacesetterVsyncSchedule =
                promotePacesetterDisplayLocked(defaultPacesetterId, kPromotionParams);
    }
    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
@@ -1147,7 +1150,8 @@ bool Scheduler::updateFrameRateOverridesLocked(GlobalSignals consideredSignals,
    return mFrameRateOverrideMappings.updateFrameRateOverridesByContent(frameRateOverrides);
}

void Scheduler::promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams params) {
void Scheduler::promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterId,
                                         PromotionParams params) {
    std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
    {
        std::scoped_lock lock(mDisplayLock);
@@ -1158,13 +1162,13 @@ void Scheduler::promotePacesetterDisplay(PhysicalDisplayId pacesetterId, Promoti
}

std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
        PhysicalDisplayId pacesetterId, PromotionParams params) {
    if (FlagManager::getInstance().pacesetter_selection()) {
        std::optional<PhysicalDisplayId> pacesetterId, PromotionParams params) {
    if (FlagManager::getInstance().pacesetter_selection() && !pacesetterId.has_value()) {
        pacesetterId = selectPacesetterDisplayLocked();
    }

    mPacesetterDisplayId = pacesetterId;
    ALOGI("Display %s is the pacesetter", to_string(pacesetterId).c_str());
    mPacesetterDisplayId = *pacesetterId;
    ALOGI("Display %s is the pacesetter", to_string(*pacesetterId).c_str());

    std::shared_ptr<VsyncSchedule> newVsyncSchedulePtr;
    if (const auto pacesetterOpt = pacesetterDisplayLocked()) {
@@ -1176,21 +1180,21 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
                                  .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
                     .kernel = {.onReset =
                                        [this, pacesetterId] {
                                            kernelIdleTimerCallback(pacesetterId,
                                            kernelIdleTimerCallback(*pacesetterId,
                                                                    TimerState::Reset);
                                        },
                                .onExpired =
                                        [this, pacesetterId] {
                                            kernelIdleTimerCallback(pacesetterId,
                                            kernelIdleTimerCallback(*pacesetterId,
                                                                    TimerState::Expired);
                                        }},
                     .vrr = {.onReset =
                                     [this, pacesetterId] {
                                         mSchedulerCallback.vrrDisplayIdle(pacesetterId, false);
                                         mSchedulerCallback.vrrDisplayIdle(*pacesetterId, false);
                                     },
                             .onExpired =
                                     [this, pacesetterId] {
                                         mSchedulerCallback.vrrDisplayIdle(pacesetterId, true);
                                         mSchedulerCallback.vrrDisplayIdle(*pacesetterId, true);
                                     }}});

            pacesetter.selectorPtr->startIdleTimer();
@@ -1203,7 +1207,7 @@ std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
        newVsyncSchedulePtr->onDisplayModeChanged(pacesetterActiveModePtr, kForce);

        if (FlagManager::getInstance().pacesetter_selection()) {
            mSchedulerCallback.enableLayerCachingTexturePool(pacesetterId, true);
            mSchedulerCallback.enableLayerCachingTexturePool(*pacesetterId, true);
            onPacesetterDisplaySizeChanged(pacesetterActiveModePtr->getResolution());
        }
    }
+13 −15
Original line number Diff line number Diff line
@@ -91,8 +91,9 @@ public:

    void startTimers();

    // Automatically selects a pacesetter display and designates if required. Returns true if a new
    // display was chosen as the pacesetter.
    // Automatically selects a pacesetter display and designates if |pacesetterId| is not present,
    // otherwise promotes `pacesetterId` to pacesetter. Returns true if a new display was chosen as
    // the pacesetter.
    bool designatePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterId = std::nullopt)
            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);

@@ -103,15 +104,12 @@ public:
    using ConstVsyncSchedulePtr = std::shared_ptr<const VsyncSchedule>;
    using VsyncSchedulePtr = std::shared_ptr<VsyncSchedule>;

    // After registration/unregistration, `activeDisplayId` is promoted to pacesetter. Note that the
    // active display is never unregistered, since hotplug disconnect never happens for activatable
    // displays, i.e. a foldable's internal displays or otherwise the (internal or external) primary
    // display.
    // TODO: b/255635821 - Remove active display parameters.
    // TODO: b/255635821 - Remove `defaultPacesetterId` parameter once the pacesetter_selection flag
    // is live.
    void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr,
                         PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
            EXCLUDES(mDisplayLock);
    void unregisterDisplay(PhysicalDisplayId, PhysicalDisplayId activeDisplayId)
                         std::optional<PhysicalDisplayId> defaultPacesetterId)
            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
    void unregisterDisplay(PhysicalDisplayId, std::optional<PhysicalDisplayId> defaultPacesetterId)
            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);

    void run();
@@ -419,7 +417,7 @@ private:
        bool toggleIdleTimer;
    };

    void promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams)
    void promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterId, PromotionParams)
            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);

    // Changes to the displays (e.g. registering and unregistering) must be made
@@ -428,8 +426,8 @@ private:
    // MessageQueue and EventThread need to use the new pacesetter's
    // VsyncSchedule, and this must happen while mDisplayLock is *not* locked,
    // or else we may deadlock with EventThread.
    std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(PhysicalDisplayId pacesetterId,
                                                                  PromotionParams)
    std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(
            std::optional<PhysicalDisplayId> pacesetterId, PromotionParams)
            REQUIRES(kMainThreadContext, mDisplayLock);
    void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);

@@ -440,8 +438,8 @@ private:
            EXCLUDES(mDisplayLock, mPolicyLock);

    void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr,
                                 PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
            EXCLUDES(mDisplayLock);
                                 std::optional<PhysicalDisplayId> defaultPacesetterId)
            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);

    struct Policy;

+3 −3
Original line number Diff line number Diff line
@@ -4112,7 +4112,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
    if (mScheduler && !display->isVirtual()) {
        // For hotplug reconnect, renew the registration since display modes have been reloaded.
        mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
                                    mFrontInternalDisplayId);
                                    getDefaultPacesetterDisplay());
    }

    if (display->isVirtual()) {
@@ -4158,7 +4158,7 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
        if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) {
            releaseVirtualDisplay(*virtualDisplayIdVariant);
        } else {
            mScheduler->unregisterDisplay(display->getPhysicalId(), mFrontInternalDisplayId);
            mScheduler->unregisterDisplay(display->getPhysicalId(), getDefaultPacesetterDisplay());
        }

        if (display->isRefreshable()) {
@@ -4731,7 +4731,7 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {

    // The pacesetter must be registered before EventThread creation below.
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
                                mFrontInternalDisplayId);
                                getDefaultPacesetterDisplay());
    if (FlagManager::getInstance().vrr_config()) {
        mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
                                  /*applyImmediately*/ true);
+7 −0
Original line number Diff line number Diff line
@@ -1069,6 +1069,13 @@ private:
        return getFrontInternalDisplayLocked();
    }

    std::optional<PhysicalDisplayId> getDefaultPacesetterDisplay() const {
        if (FlagManager::getInstance().pacesetter_selection()) {
            return std::nullopt;
        }
        return mFrontInternalDisplayId;
    }

    using DisplayDeviceAndSnapshot = std::pair<sp<DisplayDevice>, display::DisplaySnapshotRef>;

    // Combinator for ftl::Optional<PhysicalDisplay>::and_then.
+5 −0
Original line number Diff line number Diff line
@@ -602,6 +602,11 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) {
    EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120));

    // Manually designate the inner display as the pacesetter to prevent pacesetter change when the
    // outer display is powered off. A pacesetter change cancels the refresh rate change on the
    // VsyncModulator which breaks the early phase check in ModeSwitchingTo().
    mFlinger.scheduler()->designatePacesetterDisplay(innerDisplay->getPhysicalId());

    EXPECT_EQ(NO_ERROR,
              mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
Loading