Loading services/surfaceflinger/SurfaceFlinger.cpp +82 −13 Original line number Original line Diff line number Diff line Loading @@ -4075,6 +4075,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, incRefreshableDisplays(); incRefreshableDisplays(); } } if (FlagManager::getInstance().correct_virtual_display_power_state()) { applyOptimizationPolicy(__func__); } mDisplays.try_emplace(displayToken, std::move(display)); mDisplays.try_emplace(displayToken, std::move(display)); // For an external display, loadDisplayModes already attempted to select the same mode // For an external display, loadDisplayModes already attempted to select the same mode Loading Loading @@ -4131,6 +4135,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { // not be accessible. // not be accessible. })); })); } } if (FlagManager::getInstance().correct_virtual_display_power_state()) { applyOptimizationPolicy(__func__); } } } void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, Loading Loading @@ -5680,7 +5688,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } } const auto displayId = display->getPhysicalId(); const auto displayId = display->getPhysicalId(); ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str()); ALOGD("Setting power mode %d on physical display %s", mode, to_string(displayId).c_str()); const auto currentMode = display->getPowerMode(); const auto currentMode = display->getPowerMode(); if (currentMode == mode) { if (currentMode == mode) { Loading Loading @@ -5723,11 +5731,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } } if (displayId == mActiveDisplayId) { if (displayId == mActiveDisplayId) { // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall if (FlagManager::getInstance().correct_virtual_display_power_state()) { // and set it before SCHED_FIFO due to b/190237315. applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)"); constexpr const char* kWhence = "setPowerMode(ON)"; } else { setSchedAttr(true, kWhence); disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)"); setSchedFifo(true, kWhence); } } } getHwComposer().setPowerMode(displayId, mode); getHwComposer().setPowerMode(displayId, mode); Loading @@ -5754,9 +5762,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa if (const auto display = getActivatableDisplay()) { if (const auto display = getActivatableDisplay()) { onActiveDisplayChangedLocked(activeDisplay.get(), *display); onActiveDisplayChangedLocked(activeDisplay.get(), *display); } else { } else { constexpr const char* kWhence = "setPowerMode(OFF)"; if (FlagManager::getInstance().correct_virtual_display_power_state()) { setSchedFifo(false, kWhence); applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)"); setSchedAttr(false, kWhence); } else { enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)"); } if (currentModeNotDozeSuspend) { if (currentModeNotDozeSuspend) { if (!FlagManager::getInstance().multithreaded_present()) { if (!FlagManager::getInstance().multithreaded_present()) { Loading Loading @@ -5817,7 +5827,67 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa mScheduler->setDisplayPowerMode(displayId, mode); mScheduler->setDisplayPowerMode(displayId, mode); ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str()); ALOGD("Finished setting power mode %d on physical display %s", mode, to_string(displayId).c_str()); } void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) { if (!display->isVirtual()) { ALOGE("%s: Invalid operation on physical display", __func__); return; } const auto displayId = display->getVirtualId(); ALOGD("Setting power mode %d on virtual display %s %s", mode, to_string(displayId).c_str(), display->getDisplayName().c_str()); display->setPowerMode(static_cast<hal::PowerMode>(mode)); applyOptimizationPolicy(__func__); ALOGD("Finished setting power mode %d on virtual display %s", mode, to_string(displayId).c_str()); } bool SurfaceFlinger::shouldOptimizeForPerformance() { for (const auto& [_, display] : mDisplays) { // Displays that are optimized for power are always powered on and should not influence // whether there is an active display for the purpose of power optimization, etc. If these // displays are being shown somewhere, a different (physical or virtual) display that is // optimized for performance will be powered on in addition. Displays optimized for // performance will change power mode, so if they are off then they are not active. if (display->isPoweredOn() && display->getOptimizationPolicy() == gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) { return true; } } return false; } void SurfaceFlinger::enablePowerOptimizations(const char* whence) { ALOGD("%s: Enabling power optimizations", whence); setSchedAttr(false, whence); setSchedFifo(false, whence); } void SurfaceFlinger::disablePowerOptimizations(const char* whence) { ALOGD("%s: Disabling power optimizations", whence); // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall // and set it before SCHED_FIFO due to b/190237315. setSchedAttr(true, whence); setSchedFifo(true, whence); } void SurfaceFlinger::applyOptimizationPolicy(const char* whence) { if (shouldOptimizeForPerformance()) { disablePowerOptimizations(whence); } else { enablePowerOptimizations(whence); } } } void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { Loading @@ -5839,9 +5909,8 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get()); ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get()); } else if (display->isVirtual()) { } else if (display->isVirtual()) { if (FlagManager::getInstance().correct_virtual_display_power_state()) { if (FlagManager::getInstance().correct_virtual_display_power_state()) { ALOGD("Setting power mode %d on virtual display %s", mode, ftl::FakeGuard guard(mStateLock); display->getDisplayName().c_str()); setVirtualDisplayPowerMode(display, static_cast<hal::PowerMode>(mode)); display->setPowerMode(static_cast<hal::PowerMode>(mode)); } else { } else { ALOGW("Attempt to set power mode %d for virtual display", mode); ALOGW("Attempt to set power mode %d for virtual display", mode); } } Loading services/surfaceflinger/SurfaceFlinger.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -735,6 +735,22 @@ private: // Called on the main thread in response to setPowerMode() // Called on the main thread in response to setPowerMode() void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); REQUIRES(mStateLock, kMainThreadContext); void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); // Returns whether to optimize globally for performance instead of power. bool shouldOptimizeForPerformance() REQUIRES(mStateLock); // Turns on power optimizations, for example when there are no displays to be optimized for // performance. static void enablePowerOptimizations(const char* whence); // Turns off power optimizations. static void disablePowerOptimizations(const char* whence); // Enables or disables power optimizations depending on whether there are displays that should // be optimized for performance. void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock); // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // display. Falls back to the display's defaultModeId otherwise. // display. Falls back to the display's defaultModeId otherwise. Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +82 −13 Original line number Original line Diff line number Diff line Loading @@ -4075,6 +4075,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, incRefreshableDisplays(); incRefreshableDisplays(); } } if (FlagManager::getInstance().correct_virtual_display_power_state()) { applyOptimizationPolicy(__func__); } mDisplays.try_emplace(displayToken, std::move(display)); mDisplays.try_emplace(displayToken, std::move(display)); // For an external display, loadDisplayModes already attempted to select the same mode // For an external display, loadDisplayModes already attempted to select the same mode Loading Loading @@ -4131,6 +4135,10 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { // not be accessible. // not be accessible. })); })); } } if (FlagManager::getInstance().correct_virtual_display_power_state()) { applyOptimizationPolicy(__func__); } } } void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, Loading Loading @@ -5680,7 +5688,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } } const auto displayId = display->getPhysicalId(); const auto displayId = display->getPhysicalId(); ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str()); ALOGD("Setting power mode %d on physical display %s", mode, to_string(displayId).c_str()); const auto currentMode = display->getPowerMode(); const auto currentMode = display->getPowerMode(); if (currentMode == mode) { if (currentMode == mode) { Loading Loading @@ -5723,11 +5731,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa } } if (displayId == mActiveDisplayId) { if (displayId == mActiveDisplayId) { // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall if (FlagManager::getInstance().correct_virtual_display_power_state()) { // and set it before SCHED_FIFO due to b/190237315. applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)"); constexpr const char* kWhence = "setPowerMode(ON)"; } else { setSchedAttr(true, kWhence); disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)"); setSchedFifo(true, kWhence); } } } getHwComposer().setPowerMode(displayId, mode); getHwComposer().setPowerMode(displayId, mode); Loading @@ -5754,9 +5762,11 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa if (const auto display = getActivatableDisplay()) { if (const auto display = getActivatableDisplay()) { onActiveDisplayChangedLocked(activeDisplay.get(), *display); onActiveDisplayChangedLocked(activeDisplay.get(), *display); } else { } else { constexpr const char* kWhence = "setPowerMode(OFF)"; if (FlagManager::getInstance().correct_virtual_display_power_state()) { setSchedFifo(false, kWhence); applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)"); setSchedAttr(false, kWhence); } else { enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)"); } if (currentModeNotDozeSuspend) { if (currentModeNotDozeSuspend) { if (!FlagManager::getInstance().multithreaded_present()) { if (!FlagManager::getInstance().multithreaded_present()) { Loading Loading @@ -5817,7 +5827,67 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa mScheduler->setDisplayPowerMode(displayId, mode); mScheduler->setDisplayPowerMode(displayId, mode); ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str()); ALOGD("Finished setting power mode %d on physical display %s", mode, to_string(displayId).c_str()); } void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) { if (!display->isVirtual()) { ALOGE("%s: Invalid operation on physical display", __func__); return; } const auto displayId = display->getVirtualId(); ALOGD("Setting power mode %d on virtual display %s %s", mode, to_string(displayId).c_str(), display->getDisplayName().c_str()); display->setPowerMode(static_cast<hal::PowerMode>(mode)); applyOptimizationPolicy(__func__); ALOGD("Finished setting power mode %d on virtual display %s", mode, to_string(displayId).c_str()); } bool SurfaceFlinger::shouldOptimizeForPerformance() { for (const auto& [_, display] : mDisplays) { // Displays that are optimized for power are always powered on and should not influence // whether there is an active display for the purpose of power optimization, etc. If these // displays are being shown somewhere, a different (physical or virtual) display that is // optimized for performance will be powered on in addition. Displays optimized for // performance will change power mode, so if they are off then they are not active. if (display->isPoweredOn() && display->getOptimizationPolicy() == gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) { return true; } } return false; } void SurfaceFlinger::enablePowerOptimizations(const char* whence) { ALOGD("%s: Enabling power optimizations", whence); setSchedAttr(false, whence); setSchedFifo(false, whence); } void SurfaceFlinger::disablePowerOptimizations(const char* whence) { ALOGD("%s: Disabling power optimizations", whence); // TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall // and set it before SCHED_FIFO due to b/190237315. setSchedAttr(true, whence); setSchedFifo(true, whence); } void SurfaceFlinger::applyOptimizationPolicy(const char* whence) { if (shouldOptimizeForPerformance()) { disablePowerOptimizations(whence); } else { enablePowerOptimizations(whence); } } } void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { Loading @@ -5839,9 +5909,8 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get()); ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get()); } else if (display->isVirtual()) { } else if (display->isVirtual()) { if (FlagManager::getInstance().correct_virtual_display_power_state()) { if (FlagManager::getInstance().correct_virtual_display_power_state()) { ALOGD("Setting power mode %d on virtual display %s", mode, ftl::FakeGuard guard(mStateLock); display->getDisplayName().c_str()); setVirtualDisplayPowerMode(display, static_cast<hal::PowerMode>(mode)); display->setPowerMode(static_cast<hal::PowerMode>(mode)); } else { } else { ALOGW("Attempt to set power mode %d for virtual display", mode); ALOGW("Attempt to set power mode %d for virtual display", mode); } } Loading
services/surfaceflinger/SurfaceFlinger.h +16 −0 Original line number Original line Diff line number Diff line Loading @@ -735,6 +735,22 @@ private: // Called on the main thread in response to setPowerMode() // Called on the main thread in response to setPowerMode() void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); REQUIRES(mStateLock, kMainThreadContext); void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); // Returns whether to optimize globally for performance instead of power. bool shouldOptimizeForPerformance() REQUIRES(mStateLock); // Turns on power optimizations, for example when there are no displays to be optimized for // performance. static void enablePowerOptimizations(const char* whence); // Turns off power optimizations. static void disablePowerOptimizations(const char* whence); // Enables or disables power optimizations depending on whether there are displays that should // be optimized for performance. void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock); // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // display. Falls back to the display's defaultModeId otherwise. // display. Falls back to the display's defaultModeId otherwise. Loading