Loading services/surfaceflinger/Scheduler/Scheduler.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -742,8 +742,24 @@ void Scheduler::recordLayerHistory(int32_t id, const LayerProps& layerProps, nse } } void Scheduler::setModeChangePending(bool pending) { void Scheduler::setModeChangePending(PhysicalDisplayId displayId, bool pending) { if (!FlagManager::getInstance().pacesetter_selection()) { mLayerHistory.setModeChangePending(pending); return; } std::scoped_lock lock(mDisplayLock); ftl::FakeGuard guard(kMainThreadContext); const auto displayOpt = mDisplays.get(displayId); if (!displayOpt) { ALOGW("%s: Invalid display %s!", __func__, to_string(displayId).c_str()); return; } displayOpt->get().isModeChangePending = pending; mLayerHistory.setModeChangePending( std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& display) { return display.second.isModeChangePending; })); } void Scheduler::setDefaultFrameRateCompatibility( Loading Loading @@ -957,6 +973,7 @@ void Scheduler::dump(utils::Dumper& dumper) const { display.selectorPtr->dump(dumper); display.targeterPtr->dump(dumper); dumper.dump("isModeChangePending"sv, display.isModeChangePending); dumper.eol(); } } Loading services/surfaceflinger/Scheduler/Scheduler.h +2 −1 Original line number Diff line number Diff line Loading @@ -239,7 +239,7 @@ public: void registerLayer(Layer*, FrameRateCompatibility); void recordLayerHistory(int32_t id, const LayerProps& layerProps, nsecs_t presentTime, nsecs_t now, LayerHistory::LayerUpdateType) EXCLUDES(mDisplayLock); void setModeChangePending(bool pending); void setModeChangePending(PhysicalDisplayId, bool pending) EXCLUDES(mDisplayLock); void setDefaultFrameRateCompatibility(int32_t id, scheduler::FrameRateCompatibility); void setLayerProperties(int32_t id, const LayerProps&); void deregisterLayer(Layer*); Loading Loading @@ -539,6 +539,7 @@ private: FrameTargeterPtr targeterPtr; hal::PowerMode powerMode = hal::PowerMode::OFF; bool isModeChangePending = false; }; using DisplayRef = std::reference_wrapper<Display>; Loading services/surfaceflinger/SurfaceFlinger.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -1398,7 +1398,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated); mScheduler->updatePhaseConfiguration(displayId, mode.fps); mScheduler->setModeChangePending(true); mScheduler->setModeChangePending(displayId, true); // The mode set to switch resolution is not initiated until the display transaction that // resizes the display. DM sends this transaction in response to a mode change event, so Loading Loading @@ -1522,9 +1522,8 @@ bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { void SurfaceFlinger::dropModeRequest(PhysicalDisplayId displayId) { mDisplayModeController.clearDesiredMode(displayId); if (displayId == mFrontInternalDisplayId) { // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); if (displayId == mFrontInternalDisplayId || FlagManager::getInstance().pacesetter_selection()) { mScheduler->setModeChangePending(displayId, false); } } Loading Loading @@ -5741,6 +5740,10 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } else if (mode == hal::PowerMode::OFF) { const bool currentModeNotDozeSuspend = (currentMode != hal::PowerMode::DOZE_SUSPEND); // Turn off the display if (FlagManager::getInstance().pacesetter_selection()) { mScheduler->setModeChangePending(displayId, false); } if (displayId == mFrontInternalDisplayId) { if (const auto display = findFrontInternalDisplay()) { const auto frontInternalDisplay = getFrontInternalDisplayLocked(); Loading Loading @@ -8440,14 +8443,12 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte if (oldFrontInternalDisplayPtr) { oldFrontInternalDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled( false); mScheduler->setModeChangePending(oldFrontInternalDisplayPtr->getPhysicalId(), false); } newFrontInternalDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true); } // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); // Whether or not the policy of the new front internal display changed while it was powered off Loading services/surfaceflinger/tests/unittests/SchedulerTest.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -790,6 +790,55 @@ TEST_F(SchedulerTest, enablesLayerCachingTexturePoolForPacesetter) { mScheduler->setPacesetterDisplay(kDisplayId1); } TEST_F(SchedulerTest, pendingModeChangeSingleDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, false); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } TEST_F(SchedulerTest, pendingModeChangeMultiDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); mScheduler->registerDisplay(kDisplayId2, std::make_shared<RefreshRateSelector>(kDisplay2Modes, kDisplay2Mode60->getId())); mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON); mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId2, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, false); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId2, false); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } TEST_F(SchedulerTest, pendingModeChangeInvalidDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); PhysicalDisplayId invalidDisplayId = PhysicalDisplayId::fromPort(123); mScheduler->setModeChangePending(invalidDisplayId, true); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } class AttachedChoreographerTest : public SchedulerTest { protected: void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps, Loading services/surfaceflinger/tests/unittests/TestableScheduler.h +2 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,8 @@ public: return mLayerHistory.mActiveLayerInfos.size(); } bool layerHistoryModeChangePending() const { return mLayerHistory.mModeChangePending; } void replaceTouchTimer(int64_t millis, std::function<void(bool isReset)>&& testCallback = nullptr) { if (mTouchTimer) { Loading Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -742,8 +742,24 @@ void Scheduler::recordLayerHistory(int32_t id, const LayerProps& layerProps, nse } } void Scheduler::setModeChangePending(bool pending) { void Scheduler::setModeChangePending(PhysicalDisplayId displayId, bool pending) { if (!FlagManager::getInstance().pacesetter_selection()) { mLayerHistory.setModeChangePending(pending); return; } std::scoped_lock lock(mDisplayLock); ftl::FakeGuard guard(kMainThreadContext); const auto displayOpt = mDisplays.get(displayId); if (!displayOpt) { ALOGW("%s: Invalid display %s!", __func__, to_string(displayId).c_str()); return; } displayOpt->get().isModeChangePending = pending; mLayerHistory.setModeChangePending( std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& display) { return display.second.isModeChangePending; })); } void Scheduler::setDefaultFrameRateCompatibility( Loading Loading @@ -957,6 +973,7 @@ void Scheduler::dump(utils::Dumper& dumper) const { display.selectorPtr->dump(dumper); display.targeterPtr->dump(dumper); dumper.dump("isModeChangePending"sv, display.isModeChangePending); dumper.eol(); } } Loading
services/surfaceflinger/Scheduler/Scheduler.h +2 −1 Original line number Diff line number Diff line Loading @@ -239,7 +239,7 @@ public: void registerLayer(Layer*, FrameRateCompatibility); void recordLayerHistory(int32_t id, const LayerProps& layerProps, nsecs_t presentTime, nsecs_t now, LayerHistory::LayerUpdateType) EXCLUDES(mDisplayLock); void setModeChangePending(bool pending); void setModeChangePending(PhysicalDisplayId, bool pending) EXCLUDES(mDisplayLock); void setDefaultFrameRateCompatibility(int32_t id, scheduler::FrameRateCompatibility); void setLayerProperties(int32_t id, const LayerProps&); void deregisterLayer(Layer*); Loading Loading @@ -539,6 +539,7 @@ private: FrameTargeterPtr targeterPtr; hal::PowerMode powerMode = hal::PowerMode::OFF; bool isModeChangePending = false; }; using DisplayRef = std::reference_wrapper<Display>; Loading
services/surfaceflinger/SurfaceFlinger.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -1398,7 +1398,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated); mScheduler->updatePhaseConfiguration(displayId, mode.fps); mScheduler->setModeChangePending(true); mScheduler->setModeChangePending(displayId, true); // The mode set to switch resolution is not initiated until the display transaction that // resizes the display. DM sends this transaction in response to a mode change event, so Loading Loading @@ -1522,9 +1522,8 @@ bool SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { void SurfaceFlinger::dropModeRequest(PhysicalDisplayId displayId) { mDisplayModeController.clearDesiredMode(displayId); if (displayId == mFrontInternalDisplayId) { // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); if (displayId == mFrontInternalDisplayId || FlagManager::getInstance().pacesetter_selection()) { mScheduler->setModeChangePending(displayId, false); } } Loading Loading @@ -5741,6 +5740,10 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } else if (mode == hal::PowerMode::OFF) { const bool currentModeNotDozeSuspend = (currentMode != hal::PowerMode::DOZE_SUSPEND); // Turn off the display if (FlagManager::getInstance().pacesetter_selection()) { mScheduler->setModeChangePending(displayId, false); } if (displayId == mFrontInternalDisplayId) { if (const auto display = findFrontInternalDisplay()) { const auto frontInternalDisplay = getFrontInternalDisplayLocked(); Loading Loading @@ -8440,14 +8443,12 @@ void SurfaceFlinger::onNewFrontInternalDisplay(const DisplayDevice* oldFrontInte if (oldFrontInternalDisplayPtr) { oldFrontInternalDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled( false); mScheduler->setModeChangePending(oldFrontInternalDisplayPtr->getPhysicalId(), false); } newFrontInternalDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true); } // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); mScheduler->setPacesetterDisplay(mFrontInternalDisplayId); // Whether or not the policy of the new front internal display changed while it was powered off Loading
services/surfaceflinger/tests/unittests/SchedulerTest.cpp +49 −0 Original line number Diff line number Diff line Loading @@ -790,6 +790,55 @@ TEST_F(SchedulerTest, enablesLayerCachingTexturePoolForPacesetter) { mScheduler->setPacesetterDisplay(kDisplayId1); } TEST_F(SchedulerTest, pendingModeChangeSingleDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, false); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } TEST_F(SchedulerTest, pendingModeChangeMultiDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); mScheduler->registerDisplay(kDisplayId2, std::make_shared<RefreshRateSelector>(kDisplay2Modes, kDisplay2Mode60->getId())); mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON); mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId2, true); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId1, false); EXPECT_TRUE(mScheduler->layerHistoryModeChangePending()); mScheduler->setModeChangePending(kDisplayId2, false); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } TEST_F(SchedulerTest, pendingModeChangeInvalidDisplay) { SET_FLAG_FOR_TEST(flags::pacesetter_selection, true); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); PhysicalDisplayId invalidDisplayId = PhysicalDisplayId::fromPort(123); mScheduler->setModeChangePending(invalidDisplayId, true); EXPECT_FALSE(mScheduler->layerHistoryModeChangePending()); } class AttachedChoreographerTest : public SchedulerTest { protected: void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps, Loading
services/surfaceflinger/tests/unittests/TestableScheduler.h +2 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,8 @@ public: return mLayerHistory.mActiveLayerInfos.size(); } bool layerHistoryModeChangePending() const { return mLayerHistory.mModeChangePending; } void replaceTouchTimer(int64_t millis, std::function<void(bool isReset)>&& testCallback = nullptr) { if (mTouchTimer) { Loading