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

Commit 84948a97 authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Android (Google) Code Review
Browse files

Merge changes Ia5afb759,I4dd954bf into main

* changes:
  SF: Stop forcing modeset on fold/unfold
  SF: Skip choosing mode for powered-off followers
parents dba72f56 1746afd8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1153,8 +1153,10 @@ auto Scheduler::chooseDisplayModes() const -> DisplayModeChoiceMap {
        return pacesetterFps;
    }();

    // Choose a mode for powered-on follower displays.
    for (const auto& [id, display] : mDisplays) {
        if (id == *mPacesetterDisplayId) continue;
        if (display.powerMode != hal::PowerMode::ON) continue;

        auto rankedFrameRates =
                display.selectorPtr->getRankedFrameRates(mPolicy.contentRequirements, globalSignals,
+7 −48
Original line number Diff line number Diff line
@@ -1426,11 +1426,6 @@ bool SurfaceFlinger::initiateDisplayModeChanges() {
            continue;
        }

        if (!shouldApplyRefreshRateSelectorPolicy(*display)) {
            dropModeRequest(display);
            continue;
        }

        const auto desiredModeId = desiredModeOpt->mode.modePtr->getId();
        const auto displayModePtrOpt = physical.snapshot().displayModes().get(desiredModeId);

@@ -4240,12 +4235,6 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest

        if (!display) continue;

        if (ftl::FakeGuard guard(kMainThreadContext);
            !shouldApplyRefreshRateSelectorPolicy(*display)) {
            ALOGV("%s(%s): Skipped applying policy", __func__, to_string(displayId).c_str());
            continue;
        }

        if (display->refreshRateSelector().isModeAllowed(request.mode)) {
            setDesiredMode(std::move(request));
        } else {
@@ -8575,35 +8564,11 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal(
            break;
    }

    if (!shouldApplyRefreshRateSelectorPolicy(*display)) {
        ALOGV("%s(%s): Skipped applying policy", __func__, to_string(displayId).c_str());
        return NO_ERROR;
    }

    return applyRefreshRateSelectorPolicy(displayId, selector);
}

bool SurfaceFlinger::shouldApplyRefreshRateSelectorPolicy(const DisplayDevice& display) const {
    if (display.isPoweredOn() || mPhysicalDisplays.size() == 1) return true;

    LOG_ALWAYS_FATAL_IF(display.isVirtual());
    const auto displayId = display.getPhysicalId();

    // The display is powered off, and this is a multi-display device. If the display is the
    // inactive internal display of a dual-display foldable, then the policy will be applied
    // when it becomes active upon powering on.
    //
    // TODO(b/255635711): Remove this function (i.e. returning `false` as a special case) once
    // concurrent mode setting across multiple (potentially powered off) displays is supported.
    //
    return displayId == mActiveDisplayId ||
            !mPhysicalDisplays.get(displayId)
                     .transform(&PhysicalDisplay::isInternal)
                     .value_or(false);
}

status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
        PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector, bool force) {
        PhysicalDisplayId displayId, const scheduler::RefreshRateSelector& selector) {
    const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy();
    ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str());

@@ -8634,7 +8599,7 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy(
        return INVALID_OPERATION;
    }

    setDesiredMode({std::move(preferredMode), .emitEvent = true, .force = force});
    setDesiredMode({std::move(preferredMode), .emitEvent = true});

    // Update the frameRateOverride list as the display render rate might have changed
    if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) {
@@ -8992,13 +8957,8 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD
                                                  const DisplayDevice& activeDisplay) {
    ATRACE_CALL();

    // For the first display activated during boot, there is no need to force setDesiredMode,
    // because DM is about to send its policy via setDesiredDisplayModeSpecs.
    bool forceApplyPolicy = false;

    if (inactiveDisplayPtr) {
        inactiveDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
        forceApplyPolicy = true;
    }

    mActiveDisplayId = activeDisplay.getPhysicalId();
@@ -9015,12 +8975,11 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD
    mActiveDisplayTransformHint = activeDisplay.getTransformHint();
    sActiveDisplayRotationFlags = ui::Transform::toRotationFlags(activeDisplay.getOrientation());

    // The policy of the new active/pacesetter display may have changed while it was inactive. In
    // that case, its preferred mode has not been propagated to HWC (via setDesiredMode). In either
    // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode,
    // and the kernel idle timer of the newly active display must be toggled.
    applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector(),
                                   forceApplyPolicy);
    // Whether or not the policy of the new active/pacesetter display changed while it was inactive
    // (in which case its preferred mode has already been propagated to HWC via setDesiredMode), the
    // Scheduler's cachedModeChangedParams must be initialized to the newly active mode, and the
    // kernel idle timer of the newly active display must be toggled.
    applyRefreshRateSelectorPolicy(mActiveDisplayId, activeDisplay.refreshRateSelector());
}

status_t SurfaceFlinger::addWindowInfosListener(const sp<IWindowInfosListener>& windowInfosListener,
+1 −5
Original line number Diff line number Diff line
@@ -756,13 +756,9 @@ private:
            const sp<DisplayDevice>&, const scheduler::RefreshRateSelector::PolicyVariant&)
            EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);

    bool shouldApplyRefreshRateSelectorPolicy(const DisplayDevice&) const
            REQUIRES(mStateLock, kMainThreadContext);

    // TODO(b/241285191): Look up RefreshRateSelector on Scheduler to remove redundant parameter.
    status_t applyRefreshRateSelectorPolicy(PhysicalDisplayId,
                                            const scheduler::RefreshRateSelector&,
                                            bool force = false)
                                            const scheduler::RefreshRateSelector&)
            REQUIRES(mStateLock, kMainThreadContext);

    void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+4 −0
Original line number Diff line number Diff line
@@ -350,6 +350,9 @@ TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
                                std::make_shared<RefreshRateSelector>(kDisplay2Modes,
                                                                      kDisplay2Mode60->getId()));

    mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
    mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);

    using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
    TestableScheduler::DisplayModeChoiceMap expectedChoices;

@@ -412,6 +415,7 @@ TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
                ->registerDisplay(kDisplayId3,
                                  std::make_shared<RefreshRateSelector>(kDisplay3Modes,
                                                                        kDisplay3Mode60->getId()));
        mScheduler->setDisplayPowerMode(kDisplayId3, hal::PowerMode::ON);

        const GlobalSignals globalSignals = {.touch = true};
        mScheduler->replaceTouchTimer(10);
+41 −37
Original line number Diff line number Diff line
@@ -327,7 +327,9 @@ MATCHER_P2(ModeSwitchingTo, flinger, modeId, "") {
        return false;
    }

    if (!flinger->scheduler()->vsyncModulator().isVsyncConfigEarly()) {
    // VsyncModulator should react to mode switches on the pacesetter display.
    if (arg->getPhysicalId() == flinger->scheduler()->pacesetterDisplayId() &&
        !flinger->scheduler()->vsyncModulator().isVsyncConfigEarly()) {
        *result_listener << "VsyncModulator did not shift to early phase";
        return false;
    }
@@ -368,8 +370,8 @@ TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) {
    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));

    // Only the inner display is powered on.
    mFlinger.onActiveDisplayChanged(nullptr, *innerDisplay);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::OFF);
    mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON);

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
@@ -385,40 +387,44 @@ TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) {
                                                                               0.f, 120.f)));

    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));

    const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));

    innerDisplay->setPowerMode(hal::PowerMode::OFF);
    outerDisplay->setPowerMode(hal::PowerMode::ON);
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));

    // Only the outer display is powered on.
    mFlinger.onActiveDisplayChanged(innerDisplay.get(), *outerDisplay);
    mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::OFF);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON);

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));

    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
    EXPECT_EQ(NO_ERROR,
              mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
                                                  mock::createDisplayModeSpecs(kModeId60, false,
                                                                               0.f, 120.f)));

    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId60);

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));
}

@@ -437,10 +443,8 @@ TEST_F(DisplayModeSwitchingTest, innerAndOuterDisplay) {
    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));

    outerDisplay->setPowerMode(hal::PowerMode::ON);

    // Both displays are powered on.
    mFlinger.onActiveDisplayChanged(nullptr, *innerDisplay);
    mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON);

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
@@ -485,7 +489,7 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringModeSet) {
    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));

    // Power off the display before the mode has been set.
    mDisplay->setPowerMode(hal::PowerMode::OFF);
    mFlinger.setPowerModeInternal(mDisplay, hal::PowerMode::OFF);

    const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
@@ -517,10 +521,8 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) {
    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));

    outerDisplay->setPowerMode(hal::PowerMode::ON);

    // Both displays are powered on.
    mFlinger.onActiveDisplayChanged(nullptr, *innerDisplay);
    mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::ON);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON);

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
@@ -539,40 +541,42 @@ TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) {
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));

    // Power off the outer display before the mode has been set.
    outerDisplay->setPowerMode(hal::PowerMode::OFF);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::OFF);

    const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);

    mFlinger.commit();

    // Powering off the inactive display should abort the mode set.
    // Powering off the inactive display should not abort the mode set.
    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));

    innerDisplay->setPowerMode(hal::PowerMode::OFF);
    outerDisplay->setPowerMode(hal::PowerMode::ON);
    mFlinger.setPowerModeInternal(innerDisplay, hal::PowerMode::OFF);
    mFlinger.setPowerModeInternal(outerDisplay, hal::PowerMode::ON);

    // Only the outer display is powered on.
    mFlinger.onActiveDisplayChanged(innerDisplay.get(), *outerDisplay);
    EXPECT_EQ(NO_ERROR,
              mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
                                                  mock::createDisplayModeSpecs(kModeId120, false,
                                                                               0.f, 120.f)));

    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId120);

    mFlinger.commit();

    // The mode set should resume once the display becomes active.
    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId120));

    mFlinger.commit();

    EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId60));
    EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
}

} // namespace
Loading