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

Commit b4d42f97 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Fix condition to activate display on power-on"

parents 4be4b81b c132a156
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -4731,18 +4731,18 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
                                           .value_or(false);

    const auto activeDisplay = getDisplayDeviceLocked(mActiveDisplayId);
    if (isInternalDisplay && activeDisplay != display && activeDisplay &&
        activeDisplay->isPoweredOn()) {
        ALOGW("Trying to change power mode on non active display while the active display is ON");
    }
    const bool isActiveDisplayPoweredOn = activeDisplay && activeDisplay->isPoweredOn();

    ALOGW_IF(display != activeDisplay && isInternalDisplay && isActiveDisplayPoweredOn,
             "Trying to change power mode on inactive display without powering off active display");

    display->setPowerMode(mode);

    const auto refreshRate = display->refreshRateSelector().getActiveMode().modePtr->getFps();
    if (!currentModeOpt || *currentModeOpt == hal::PowerMode::OFF) {
        // Turn on the display
        if (isInternalDisplay && (!activeDisplay || !activeDisplay->isPoweredOn())) {
            onActiveDisplayChangedLocked(display);
        if (isInternalDisplay && !isActiveDisplayPoweredOn) {
            onActiveDisplayChangedLocked(activeDisplay, display);
        }
        // Keep uclamp in a separate syscall and set it before changing to RT due to b/190237315.
        // We can merge the syscall later.
@@ -7042,17 +7042,14 @@ void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<const DisplayDevice>& a
    getRenderEngine().onActiveDisplaySizeChanged(activeDisplay->getSize());
}

void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay) {
void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& inactiveDisplay,
                                                  const sp<DisplayDevice>& activeDisplay) {
    ATRACE_CALL();

    if (const auto display = getDisplayDeviceLocked(mActiveDisplayId)) {
        display->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
    if (inactiveDisplay) {
        inactiveDisplay->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
    }

    if (!activeDisplay) {
        ALOGE("%s: activeDisplay is null", __func__);
        return;
    }
    mActiveDisplayId = activeDisplay->getPhysicalId();
    activeDisplay->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);

+4 −1
Original line number Diff line number Diff line
@@ -1002,7 +1002,10 @@ private:
    VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat) REQUIRES(mStateLock);
    void releaseVirtualDisplay(VirtualDisplayId);

    void onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay)
    // TODO(b/255635821): Replace pointers with references. `inactiveDisplay` is only ever `nullptr`
    // in tests, and `activeDisplay` must not be `nullptr` as a precondition.
    void onActiveDisplayChangedLocked(const sp<DisplayDevice>& inactiveDisplay,
                                      const sp<DisplayDevice>& activeDisplay)
            REQUIRES(mStateLock, kMainThreadContext);

    void onActiveDisplaySizeChanged(const sp<const DisplayDevice>&);
+8 −4
Original line number Diff line number Diff line
@@ -359,6 +359,7 @@ struct HwcDisplayVariant {
    }

    // Called by tests to inject a HWC display setup
    template <bool kInitPowerMode = true>
    static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
        const auto displayId = DisplayVariant::DISPLAY_ID::get();
        ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
@@ -367,18 +368,21 @@ struct HwcDisplayVariant {
                .setHwcDisplayId(HWC_DISPLAY_ID)
                .setResolution(DisplayVariant::RESOLUTION)
                .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
                .setPowerMode(INIT_POWER_MODE)
                .setPowerMode(kInitPowerMode ? std::make_optional(INIT_POWER_MODE) : std::nullopt)
                .inject(&test->mFlinger, test->mComposer);
    }

    // Called by tests to inject a HWC display setup
    template <bool kInitPowerMode = true>
    static void injectHwcDisplay(DisplayTransactionTest* test) {
        EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
                .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
                                Return(Error::NONE)));
        if constexpr (kInitPowerMode) {
            EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
                    .WillOnce(Return(Error::NONE));
        injectHwcDisplayWithNoDefaultCapabilities(test);
        }
        injectHwcDisplayWithNoDefaultCapabilities<kInitPowerMode>(test);
    }

    static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
+0 −1
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ void SurfaceFlingerPowerHintTest::SetUp() {
                    .setNativeWindow(mNativeWindow)
                    .setPowerMode(hal::PowerMode::ON)
                    .inject();
    mFlinger.mutableActiveDisplayId() = mDisplay->getPhysicalId();
}

void SurfaceFlingerPowerHintTest::setupScheduler() {
+32 −6
Original line number Diff line number Diff line
@@ -259,12 +259,6 @@ struct DisplayPowerCase {
        auto injector = Display::makeFakeExistingDisplayInjector(test);
        const auto display = injector.inject();
        display->setPowerMode(mode);
        if (injector.physicalDisplay()
                    .transform(&display::PhysicalDisplay::isInternal)
                    .value_or(false)) {
            test->mFlinger.mutableActiveDisplayId() = display->getPhysicalId();
        }

        return display;
    }

@@ -490,5 +484,37 @@ TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDispla
    transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
}

TEST_F(SetPowerModeInternalTest, designatesLeaderDisplay) {
    using Case = SimplePrimaryDisplayCase;

    // --------------------------------------------------------------------
    // Preconditions

    // Inject a primary display with uninitialized power mode.
    constexpr bool kInitPowerMode = false;
    Case::Display::injectHwcDisplay<kInitPowerMode>(this);
    auto injector = Case::Display::makeFakeExistingDisplayInjector(this);
    injector.setPowerMode(std::nullopt);
    const auto display = injector.inject();

    // --------------------------------------------------------------------
    // Invocation

    // FakeDisplayDeviceInjector registers the display with Scheduler, so it has already been
    // designated as the leader. Set an arbitrary leader to verify that `setPowerModeInternal`
    // designates a leader regardless of any preceding `Scheduler::registerDisplay` call(s).
    constexpr PhysicalDisplayId kPlaceholderId = PhysicalDisplayId::fromPort(42);
    ASSERT_NE(display->getPhysicalId(), kPlaceholderId);
    mFlinger.scheduler()->setLeaderDisplay(kPlaceholderId);

    mFlinger.setPowerModeInternal(display, PowerMode::ON);

    // --------------------------------------------------------------------
    // Postconditions

    // The primary display should be designated as the leader.
    EXPECT_EQ(mFlinger.scheduler()->leaderDisplayId(), display->getPhysicalId());
}

} // namespace
} // namespace android
Loading