Loading services/surfaceflinger/SurfaceFlinger.cpp +10 −13 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading services/surfaceflinger/SurfaceFlinger.h +4 −1 Original line number Diff line number Diff line Loading @@ -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>&); Loading services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +8 −4 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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( Loading services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -97,7 +97,6 @@ void SurfaceFlingerPowerHintTest::SetUp() { .setNativeWindow(mNativeWindow) .setPowerMode(hal::PowerMode::ON) .inject(); mFlinger.mutableActiveDisplayId() = mDisplay->getPhysicalId(); } void SurfaceFlingerPowerHintTest::setupScheduler() { Loading services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp +32 −6 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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
services/surfaceflinger/SurfaceFlinger.cpp +10 −13 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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); Loading
services/surfaceflinger/SurfaceFlinger.h +4 −1 Original line number Diff line number Diff line Loading @@ -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>&); Loading
services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +8 −4 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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( Loading
services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -97,7 +97,6 @@ void SurfaceFlingerPowerHintTest::SetUp() { .setNativeWindow(mNativeWindow) .setPowerMode(hal::PowerMode::ON) .inject(); mFlinger.mutableActiveDisplayId() = mDisplay->getPhysicalId(); } void SurfaceFlingerPowerHintTest::setupScheduler() { Loading
services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp +32 −6 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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