Skip to content

Commit 2c710c3

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Use power mode of all independent displays to control power optimisations." into main
2 parents 89366b4 + 00a764e commit 2c710c3

2 files changed

Lines changed: 98 additions & 13 deletions

File tree

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

41364144
void 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

58235893
void 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
}

services/surfaceflinger/SurfaceFlinger.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,22 @@ class SurfaceFlinger : public BnSurfaceComposer,
735735
// Called on the main thread in response to setPowerMode()
736736
void setPhysicalDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
737737
REQUIRES(mStateLock, kMainThreadContext);
738+
void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
739+
REQUIRES(mStateLock, kMainThreadContext);
740+
741+
// Returns whether to optimize globally for performance instead of power.
742+
bool shouldOptimizeForPerformance() REQUIRES(mStateLock);
743+
744+
// Turns on power optimizations, for example when there are no displays to be optimized for
745+
// performance.
746+
static void enablePowerOptimizations(const char* whence);
747+
748+
// Turns off power optimizations.
749+
static void disablePowerOptimizations(const char* whence);
750+
751+
// Enables or disables power optimizations depending on whether there are displays that should
752+
// be optimized for performance.
753+
void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock);
738754

739755
// Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that
740756
// display. Falls back to the display's defaultModeId otherwise.

0 commit comments

Comments
 (0)