@@ -4075,6 +4075,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
40754075 incRefreshableDisplays ();
40764076 }
40774077
4078+ if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
4079+ applyOptimizationPolicy (__func__);
4080+ }
4081+
40784082 mDisplays .try_emplace (displayToken, std::move (display));
40794083
40804084 // For an external display, loadDisplayModes already attempted to select the same mode
@@ -4131,6 +4135,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
41314135 // not be accessible.
41324136 }));
41334137 }
4138+
4139+ if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
4140+ applyOptimizationPolicy (__func__);
4141+ }
41344142}
41354143
41364144void SurfaceFlinger::processDisplayChanged (const wp<IBinder>& displayToken,
@@ -5680,7 +5688,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
56805688 }
56815689
56825690 const auto displayId = display->getPhysicalId ();
5683- ALOGD (" Setting power mode %d on display %s" , mode, to_string (displayId).c_str ());
5691+ ALOGD (" Setting power mode %d on physical display %s" , mode, to_string (displayId).c_str ());
56845692
56855693 const auto currentMode = display->getPowerMode ();
56865694 if (currentMode == mode) {
@@ -5723,11 +5731,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57235731 }
57245732
57255733 if (displayId == mActiveDisplayId ) {
5726- // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
5727- // and set it before SCHED_FIFO due to b/190237315.
5728- constexpr const char * kWhence = " setPowerMode(ON) " ;
5729- setSchedAttr ( true , kWhence );
5730- setSchedFifo ( true , kWhence );
5734+ if ( FlagManager::getInstance (). correct_virtual_display_power_state ()) {
5735+ applyOptimizationPolicy ( " setPhysicalDisplayPowerMode(ON) " );
5736+ } else {
5737+ disablePowerOptimizations ( " setPhysicalDisplayPowerMode(ON) " );
5738+ }
57315739 }
57325740
57335741 getHwComposer ().setPowerMode (displayId, mode);
@@ -5754,9 +5762,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57545762 if (const auto display = getActivatableDisplay ()) {
57555763 onActiveDisplayChangedLocked (activeDisplay.get (), *display);
57565764 } else {
5757- constexpr const char * kWhence = " setPowerMode(OFF)" ;
5758- setSchedFifo (false , kWhence );
5759- setSchedAttr (false , kWhence );
5765+ if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
5766+ applyOptimizationPolicy (" setPhysicalDisplayPowerMode(OFF)" );
5767+ } else {
5768+ enablePowerOptimizations (" setPhysicalDisplayPowerMode(OFF)" );
5769+ }
57605770
57615771 if (currentModeNotDozeSuspend) {
57625772 if (!FlagManager::getInstance ().multithreaded_present ()) {
@@ -5817,7 +5827,67 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
58175827
58185828 mScheduler ->setDisplayPowerMode (displayId, mode);
58195829
5820- ALOGD (" Finished setting power mode %d on display %s" , mode, to_string (displayId).c_str ());
5830+ ALOGD (" Finished setting power mode %d on physical display %s" , mode,
5831+ to_string (displayId).c_str ());
5832+ }
5833+
5834+ void SurfaceFlinger::setVirtualDisplayPowerMode (const sp<DisplayDevice>& display,
5835+ hal::PowerMode mode) {
5836+ if (!display->isVirtual ()) {
5837+ ALOGE (" %s: Invalid operation on physical display" , __func__);
5838+ return ;
5839+ }
5840+
5841+ const auto displayId = display->getVirtualId ();
5842+ ALOGD (" Setting power mode %d on virtual display %s %s" , mode, to_string (displayId).c_str (),
5843+ display->getDisplayName ().c_str ());
5844+
5845+ display->setPowerMode (static_cast <hal::PowerMode>(mode));
5846+
5847+ applyOptimizationPolicy (__func__);
5848+
5849+ ALOGD (" Finished setting power mode %d on virtual display %s" , mode,
5850+ to_string (displayId).c_str ());
5851+ }
5852+
5853+ bool SurfaceFlinger::shouldOptimizeForPerformance () {
5854+ for (const auto & [_, display] : mDisplays ) {
5855+ // Displays that are optimized for power are always powered on and should not influence
5856+ // whether there is an active display for the purpose of power optimization, etc. If these
5857+ // displays are being shown somewhere, a different (physical or virtual) display that is
5858+ // optimized for performance will be powered on in addition. Displays optimized for
5859+ // performance will change power mode, so if they are off then they are not active.
5860+ if (display->isPoweredOn () &&
5861+ display->getOptimizationPolicy () ==
5862+ gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
5863+ return true ;
5864+ }
5865+ }
5866+ return false ;
5867+ }
5868+
5869+ void SurfaceFlinger::enablePowerOptimizations (const char * whence) {
5870+ ALOGD (" %s: Enabling power optimizations" , whence);
5871+
5872+ setSchedAttr (false , whence);
5873+ setSchedFifo (false , whence);
5874+ }
5875+
5876+ void SurfaceFlinger::disablePowerOptimizations (const char * whence) {
5877+ ALOGD (" %s: Disabling power optimizations" , whence);
5878+
5879+ // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
5880+ // and set it before SCHED_FIFO due to b/190237315.
5881+ setSchedAttr (true , whence);
5882+ setSchedFifo (true , whence);
5883+ }
5884+
5885+ void SurfaceFlinger::applyOptimizationPolicy (const char * whence) {
5886+ if (shouldOptimizeForPerformance ()) {
5887+ disablePowerOptimizations (whence);
5888+ } else {
5889+ enablePowerOptimizations (whence);
5890+ }
58215891}
58225892
58235893void SurfaceFlinger::setPowerMode (const sp<IBinder>& displayToken, int mode) {
@@ -5839,9 +5909,8 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
58395909 ALOGE (" Failed to set power mode %d for display token %p" , mode, displayToken.get ());
58405910 } else if (display->isVirtual ()) {
58415911 if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
5842- ALOGD (" Setting power mode %d on virtual display %s" , mode,
5843- display->getDisplayName ().c_str ());
5844- display->setPowerMode (static_cast <hal::PowerMode>(mode));
5912+ ftl::FakeGuard guard (mStateLock );
5913+ setVirtualDisplayPowerMode (display, static_cast <hal::PowerMode>(mode));
58455914 } else {
58465915 ALOGW (" Attempt to set power mode %d for virtual display" , mode);
58475916 }
0 commit comments