@@ -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,
@@ -5679,7 +5687,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
56795687 }
56805688
56815689 const auto displayId = display->getPhysicalId ();
5682- ALOGD (" Setting power mode %d on display %s" , mode, to_string (displayId).c_str ());
5690+ ALOGD (" Setting power mode %d on physical display %s" , mode, to_string (displayId).c_str ());
56835691
56845692 const auto currentMode = display->getPowerMode ();
56855693 if (currentMode == mode) {
@@ -5722,11 +5730,11 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
57225730 }
57235731
57245732 if (displayId == mActiveDisplayId ) {
5725- // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
5726- // and set it before SCHED_FIFO due to b/190237315.
5727- constexpr const char * kWhence = " setPowerMode(ON) " ;
5728- setSchedAttr ( true , kWhence );
5729- setSchedFifo ( true , kWhence );
5733+ if ( FlagManager::getInstance (). correct_virtual_display_power_state ()) {
5734+ applyOptimizationPolicy ( " setPhysicalDisplayPowerMode(ON) " );
5735+ } else {
5736+ disablePowerOptimizations ( " setPhysicalDisplayPowerMode(ON) " );
5737+ }
57305738 }
57315739
57325740 getHwComposer ().setPowerMode (displayId, mode);
@@ -5753,9 +5761,11 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
57535761 if (const auto display = getActivatableDisplay ()) {
57545762 onActiveDisplayChangedLocked (activeDisplay.get (), *display);
57555763 } else {
5756- constexpr const char * kWhence = " setPowerMode(OFF)" ;
5757- setSchedFifo (false , kWhence );
5758- setSchedAttr (false , kWhence );
5764+ if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
5765+ applyOptimizationPolicy (" setPhysicalDisplayPowerMode(OFF)" );
5766+ } else {
5767+ enablePowerOptimizations (" setPhysicalDisplayPowerMode(OFF)" );
5768+ }
57595769
57605770 if (currentModeNotDozeSuspend) {
57615771 if (!FlagManager::getInstance ().multithreaded_present ()) {
@@ -5816,7 +5826,67 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
58165826
58175827 mScheduler ->setDisplayPowerMode (displayId, mode);
58185828
5819- ALOGD (" Finished setting power mode %d on display %s" , mode, to_string (displayId).c_str ());
5829+ ALOGD (" Finished setting power mode %d on physical display %s" , mode,
5830+ to_string (displayId).c_str ());
5831+ }
5832+
5833+ void SurfaceFlinger::setVirtualDisplayPowerMode (const sp<DisplayDevice>& display,
5834+ hal::PowerMode mode) {
5835+ if (!display->isVirtual ()) {
5836+ ALOGE (" %s: Invalid operation on physical display" , __func__);
5837+ return ;
5838+ }
5839+
5840+ const auto displayId = display->getVirtualId ();
5841+ ALOGD (" Setting power mode %d on virtual display %s %s" , mode, to_string (displayId).c_str (),
5842+ display->getDisplayName ().c_str ());
5843+
5844+ display->setPowerMode (static_cast <hal::PowerMode>(mode));
5845+
5846+ applyOptimizationPolicy (__func__);
5847+
5848+ ALOGD (" Finished setting power mode %d on virtual display %s" , mode,
5849+ to_string (displayId).c_str ());
5850+ }
5851+
5852+ bool SurfaceFlinger::shouldOptimizeForPerformance () {
5853+ for (const auto & [_, display] : mDisplays ) {
5854+ // Displays that are optimized for power are always powered on and should not influence
5855+ // whether there is an active display for the purpose of power optimization, etc. If these
5856+ // displays are being shown somewhere, a different (physical or virtual) display that is
5857+ // optimized for performance will be powered on in addition. Displays optimized for
5858+ // performance will change power mode, so if they are off then they are not active.
5859+ if (display->isPoweredOn () &&
5860+ display->getOptimizationPolicy () ==
5861+ gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
5862+ return true ;
5863+ }
5864+ }
5865+ return false ;
5866+ }
5867+
5868+ void SurfaceFlinger::enablePowerOptimizations (const char * whence) {
5869+ ALOGD (" %s: Enabling power optimizations" , whence);
5870+
5871+ setSchedAttr (false , whence);
5872+ setSchedFifo (false , whence);
5873+ }
5874+
5875+ void SurfaceFlinger::disablePowerOptimizations (const char * whence) {
5876+ ALOGD (" %s: Disabling power optimizations" , whence);
5877+
5878+ // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
5879+ // and set it before SCHED_FIFO due to b/190237315.
5880+ setSchedAttr (true , whence);
5881+ setSchedFifo (true , whence);
5882+ }
5883+
5884+ void SurfaceFlinger::applyOptimizationPolicy (const char * whence) {
5885+ if (shouldOptimizeForPerformance ()) {
5886+ disablePowerOptimizations (whence);
5887+ } else {
5888+ enablePowerOptimizations (whence);
5889+ }
58205890}
58215891
58225892void SurfaceFlinger::setPowerMode (const sp<IBinder>& displayToken, int mode) {
@@ -5838,9 +5908,8 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
58385908 ALOGE (" Failed to set power mode %d for display token %p" , mode, displayToken.get ());
58395909 } else if (display->isVirtual ()) {
58405910 if (FlagManager::getInstance ().correct_virtual_display_power_state ()) {
5841- ALOGD (" Setting power mode %d on virtual display %s" , mode,
5842- display->getDisplayName ().c_str ());
5843- display->setPowerMode (static_cast <hal::PowerMode>(mode));
5911+ ftl::FakeGuard guard (mStateLock );
5912+ setVirtualDisplayPowerMode (display, static_cast <hal::PowerMode>(mode));
58445913 } else {
58455914 ALOGW (" Attempt to set power mode %d for virtual display" , mode);
58465915 }
0 commit comments