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

Commit 532a3ae5 authored by Su Hong Koo's avatar Su Hong Koo
Browse files

SF: Use specified pacesetterId in designatePacesetterDisplay

Currently, if the pacesetter_selection flag is enabled, Scheduler
ignores any pacesetterId argument passed into
Scheduler::designatePacesetterDisplay() and invokes
selectPacesetterDisplay() to select a new pacesetter. Same behavior
is present in Scheduler::promotePacesetterDisplayLocked().

This CL changes the condition for invoking selectPacesetterDisplay() in
both methods to only when a pacesetterId is not specified. This change
allows the caller to specify the pacesetter display.

Flag: com.android.graphics.surfaceflinger.flags.pacesetter_selection
Bug: 389983418
Test: atest libsurfaceflinger_unittests with and without the flag
Change-Id: If37b633d05f4be69615a44d2c3fb01502cf23d67
parent 761bc2da
Loading
Loading
Loading
Loading
+22 −18
Original line number Original line Diff line number Diff line
@@ -111,7 +111,7 @@ void Scheduler::startTimers() {
}
}


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


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


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


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


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


    // Start the idle timer for the first registered (i.e. primary) display.
    // 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)
                                                       std::move(schedulePtr), mFeatures)
                                   .second;
                                   .second;


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


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


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


    dispatchHotplug(displayId, Hotplug::Disconnected);
    dispatchHotplug(displayId, Hotplug::Disconnected);


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


        pacesetterVsyncSchedule = promotePacesetterDisplayLocked(activeDisplayId, kPromotionParams);
        pacesetterVsyncSchedule =
                promotePacesetterDisplayLocked(defaultPacesetterId, kPromotionParams);
    }
    }
    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
}
@@ -1147,7 +1150,8 @@ bool Scheduler::updateFrameRateOverridesLocked(GlobalSignals consideredSignals,
    return mFrameRateOverrideMappings.updateFrameRateOverridesByContent(frameRateOverrides);
    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::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
    {
    {
        std::scoped_lock lock(mDisplayLock);
        std::scoped_lock lock(mDisplayLock);
@@ -1158,13 +1162,13 @@ void Scheduler::promotePacesetterDisplay(PhysicalDisplayId pacesetterId, Promoti
}
}


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


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


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


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


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


    void startTimers();
    void startTimers();


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


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


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


    void run();
    void run();
@@ -418,7 +416,7 @@ private:
        bool toggleIdleTimer;
        bool toggleIdleTimer;
    };
    };


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


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


@@ -439,8 +437,8 @@ private:
            EXCLUDES(mDisplayLock, mPolicyLock);
            EXCLUDES(mDisplayLock, mPolicyLock);


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


    struct Policy;
    struct Policy;


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


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


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


    // The pacesetter must be registered before EventThread creation below.
    // The pacesetter must be registered before EventThread creation below.
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
                                mFrontInternalDisplayId);
                                getDefaultPacesetterDisplay());
    if (FlagManager::getInstance().vrr_config()) {
    if (FlagManager::getInstance().vrr_config()) {
        mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
        mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
                                  /*applyImmediately*/ true);
                                  /*applyImmediately*/ true);
+7 −0
Original line number Original line Diff line number Diff line
@@ -1069,6 +1069,13 @@ private:
        return getFrontInternalDisplayLocked();
        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>;
    using DisplayDeviceAndSnapshot = std::pair<sp<DisplayDevice>, display::DisplaySnapshotRef>;


    // Combinator for ftl::Optional<PhysicalDisplay>::and_then.
    // Combinator for ftl::Optional<PhysicalDisplay>::and_then.
+8 −4
Original line number Original line Diff line number Diff line
@@ -83,16 +83,20 @@ public:


    void registerDisplay(
    void registerDisplay(
            PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
            PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
            std::optional<PhysicalDisplayId> activeDisplayIdOpt = {},
            std::optional<PhysicalDisplayId> defaultPacesetterId = {},
            std::shared_ptr<VSyncTracker> vsyncTracker = std::make_shared<mock::VSyncTracker>()) {
            std::shared_ptr<VSyncTracker> vsyncTracker = std::make_shared<mock::VSyncTracker>()) {
        if (!FlagManager::getInstance().pacesetter_selection() && !defaultPacesetterId) {
            defaultPacesetterId = displayId;
        }
        registerDisplay(displayId, std::move(selectorPtr),
        registerDisplay(displayId, std::move(selectorPtr),
                        std::make_unique<mock::VsyncController>(), vsyncTracker,
                        std::make_unique<mock::VsyncController>(), vsyncTracker,
                        activeDisplayIdOpt.value_or(displayId));
                        defaultPacesetterId);
    }
    }


    void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
    void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
                         std::unique_ptr<VsyncController> controller,
                         std::unique_ptr<VsyncController> controller,
                         std::shared_ptr<VSyncTracker> tracker, PhysicalDisplayId activeDisplayId) {
                         std::shared_ptr<VSyncTracker> tracker,
                         std::optional<PhysicalDisplayId> defaultPacesetterId) {
        ftl::FakeGuard guard(kMainThreadContext);
        ftl::FakeGuard guard(kMainThreadContext);
        Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr),
        Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr),
                                           std::shared_ptr<VsyncSchedule>(
                                           std::shared_ptr<VsyncSchedule>(
@@ -102,7 +106,7 @@ public:
                                                                     std::move(controller),
                                                                     std::move(controller),
                                                                     mockRequestHardwareVsync
                                                                     mockRequestHardwareVsync
                                                                             .AsStdFunction())),
                                                                             .AsStdFunction())),
                                           activeDisplayId);
                                           defaultPacesetterId);
    }
    }


    testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync;
    testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync;
Loading