Skip to content

Commit 208f88a

Browse files
Dennis KiilerichAndroid (Google) Code Review
authored andcommitted
Merge "Turn off synthetic VSYNC when adjusting thread scheduling for performance" into main
2 parents ad6adb7 + bac7071 commit 208f88a

5 files changed

Lines changed: 95 additions & 71 deletions

File tree

services/surfaceflinger/DisplayDevice.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,6 @@ namespace android {
5050

5151
namespace hal = hardware::graphics::composer::hal;
5252

53-
namespace gui {
54-
inline std::string_view to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
55-
switch (optimizationPolicy) {
56-
case ISurfaceComposer::OptimizationPolicy::optimizeForPower:
57-
return "optimizeForPower";
58-
case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance:
59-
return "optimizeForPerformance";
60-
}
61-
}
62-
} // namespace gui
63-
6453
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
6554
const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
6655
std::shared_ptr<compositionengine::Display> compositionDisplay)

services/surfaceflinger/DisplayDevice.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ namespace display {
6767
class DisplaySnapshot;
6868
} // namespace display
6969

70+
namespace gui {
71+
inline const char* to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
72+
switch (optimizationPolicy) {
73+
case ISurfaceComposer::OptimizationPolicy::optimizeForPower:
74+
return "optimizeForPower";
75+
case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance:
76+
return "optimizeForPerformance";
77+
}
78+
}
79+
} // namespace gui
80+
7081
class DisplayDevice : public RefBase {
7182
public:
7283
constexpr static float sDefaultMinLumiance = 0.0;

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5719,7 +5719,13 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57195719
incRefreshableDisplays();
57205720
}
57215721

5722+
if (displayId == mActiveDisplayId &&
5723+
FlagManager::getInstance().correct_virtual_display_power_state()) {
5724+
applyOptimizationPolicy(__func__);
5725+
}
5726+
57225727
const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
5728+
using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
57235729
if (currentMode == hal::PowerMode::OFF) {
57245730
// Turn on the display
57255731

@@ -5734,12 +5740,10 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57345740
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
57355741
}
57365742

5737-
if (displayId == mActiveDisplayId) {
5738-
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5739-
applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)");
5740-
} else {
5741-
disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)");
5742-
}
5743+
if (displayId == mActiveDisplayId &&
5744+
!FlagManager::getInstance().correct_virtual_display_power_state()) {
5745+
optimizeThreadScheduling("setPhysicalDisplayPowerMode(ON/DOZE)",
5746+
OptimizationPolicy::optimizeForPerformance);
57435747
}
57445748

57455749
getHwComposer().setPowerMode(displayId, mode);
@@ -5748,7 +5752,8 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57485752
mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState();
57495753
requestHardwareVsync(displayId, enable);
57505754

5751-
if (displayId == mActiveDisplayId) {
5755+
if (displayId == mActiveDisplayId &&
5756+
!FlagManager::getInstance().correct_virtual_display_power_state()) {
57525757
mScheduler->enableSyntheticVsync(false);
57535758
}
57545759

@@ -5765,13 +5770,13 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57655770
if (const auto display = getActivatableDisplay()) {
57665771
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
57675772
} else {
5768-
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5769-
applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)");
5770-
} else {
5771-
enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)");
5773+
if (!FlagManager::getInstance().correct_virtual_display_power_state()) {
5774+
optimizeThreadScheduling("setPhysicalDisplayPowerMode(OFF)",
5775+
OptimizationPolicy::optimizeForPower);
57725776
}
57735777

5774-
if (currentModeNotDozeSuspend) {
5778+
if (currentModeNotDozeSuspend &&
5779+
!FlagManager::getInstance().correct_virtual_display_power_state()) {
57755780
mScheduler->enableSyntheticVsync();
57765781
}
57775782
}
@@ -5799,7 +5804,9 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57995804
ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
58005805
mVisibleRegionsDirty = true;
58015806
scheduleRepaint();
5802-
mScheduler->enableSyntheticVsync(false);
5807+
if (!FlagManager::getInstance().correct_virtual_display_power_state()) {
5808+
mScheduler->enableSyntheticVsync(false);
5809+
}
58035810
}
58045811
constexpr bool kAllowToEnable = true;
58055812
mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
@@ -5809,7 +5816,8 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
58095816
constexpr bool kDisallow = true;
58105817
mScheduler->disableHardwareVsync(displayId, kDisallow);
58115818

5812-
if (displayId == mActiveDisplayId) {
5819+
if (displayId == mActiveDisplayId &&
5820+
!FlagManager::getInstance().correct_virtual_display_power_state()) {
58135821
mScheduler->enableSyntheticVsync();
58145822
}
58155823
getHwComposer().setPowerMode(displayId, mode);
@@ -5848,43 +5856,44 @@ void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display
58485856
to_string(displayId).c_str());
58495857
}
58505858

5851-
bool SurfaceFlinger::shouldOptimizeForPerformance() {
5852-
for (const auto& [_, display] : mDisplays) {
5853-
// Displays that are optimized for power are always powered on and should not influence
5854-
// whether there is an active display for the purpose of power optimization, etc. If these
5855-
// displays are being shown somewhere, a different (physical or virtual) display that is
5856-
// optimized for performance will be powered on in addition. Displays optimized for
5857-
// performance will change power mode, so if they are off then they are not active.
5858-
if (display->isPoweredOn() &&
5859-
display->getOptimizationPolicy() ==
5860-
gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
5861-
return true;
5862-
}
5863-
}
5864-
return false;
5865-
}
5866-
5867-
void SurfaceFlinger::enablePowerOptimizations(const char* whence) {
5868-
ALOGD("%s: Enabling power optimizations", whence);
5869-
5870-
setSchedAttr(false, whence);
5871-
setSchedFifo(false, whence);
5872-
}
5873-
5874-
void SurfaceFlinger::disablePowerOptimizations(const char* whence) {
5875-
ALOGD("%s: Disabling power optimizations", whence);
5859+
void SurfaceFlinger::optimizeThreadScheduling(
5860+
const char* whence, gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
5861+
ALOGD("%s: Optimizing thread scheduling: %s", whence, to_string(optimizationPolicy));
58765862

5863+
const bool optimizeForPerformance =
5864+
optimizationPolicy == gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
58775865
// TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
58785866
// and set it before SCHED_FIFO due to b/190237315.
5879-
setSchedAttr(true, whence);
5880-
setSchedFifo(true, whence);
5867+
setSchedAttr(optimizeForPerformance, whence);
5868+
setSchedFifo(optimizeForPerformance, whence);
58815869
}
58825870

58835871
void SurfaceFlinger::applyOptimizationPolicy(const char* whence) {
5884-
if (shouldOptimizeForPerformance()) {
5885-
disablePowerOptimizations(whence);
5886-
} else {
5887-
enablePowerOptimizations(whence);
5872+
using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
5873+
5874+
const bool optimizeForPerformance =
5875+
std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
5876+
const auto& display = pair.second;
5877+
return display->isPoweredOn() &&
5878+
display->getOptimizationPolicy() ==
5879+
OptimizationPolicy::optimizeForPerformance;
5880+
});
5881+
5882+
optimizeThreadScheduling(whence,
5883+
optimizeForPerformance ? OptimizationPolicy::optimizeForPerformance
5884+
: OptimizationPolicy::optimizeForPower);
5885+
5886+
if (mScheduler) {
5887+
const bool disableSyntheticVsync =
5888+
std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
5889+
const auto& display = pair.second;
5890+
const hal::PowerMode powerMode = display->getPowerMode();
5891+
return powerMode != hal::PowerMode::OFF &&
5892+
powerMode != hal::PowerMode::DOZE_SUSPEND &&
5893+
display->getOptimizationPolicy() ==
5894+
OptimizationPolicy::optimizeForPerformance;
5895+
});
5896+
mScheduler->enableSyntheticVsync(!disableSyntheticVsync);
58885897
}
58895898
}
58905899

services/surfaceflinger/SurfaceFlinger.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,19 +733,14 @@ class SurfaceFlinger : public BnSurfaceComposer,
733733
void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
734734
REQUIRES(mStateLock, kMainThreadContext);
735735

736-
// Returns whether to optimize globally for performance instead of power.
737-
bool shouldOptimizeForPerformance() REQUIRES(mStateLock);
738-
739-
// Turns on power optimizations, for example when there are no displays to be optimized for
740-
// performance.
741-
static void enablePowerOptimizations(const char* whence);
742-
743-
// Turns off power optimizations.
744-
static void disablePowerOptimizations(const char* whence);
736+
// Adjusts thread scheduling according to the optimization policy
737+
static void optimizeThreadScheduling(
738+
const char* whence, gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy);
745739

746740
// Enables or disables power optimizations depending on whether there are displays that should
747741
// be optimized for performance.
748-
void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock);
742+
void applyOptimizationPolicy(const char* whence) REQUIRES(kMainThreadContext)
743+
REQUIRES(mStateLock);
749744

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

services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#undef LOG_TAG
1818
#define LOG_TAG "LibSurfaceFlingerUnittests"
1919

20+
#include <android_companion_virtualdevice_flags.h>
2021
#include <com_android_graphics_surfaceflinger_flags.h>
2122
#include <common/test/FlagUtils.h>
2223
#include "DisplayTransactionTestHelpers.h"
@@ -78,11 +79,19 @@ struct EventThreadBaseSupportedVariant {
7879
struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
7980
static void setupEnableVsyncCallExpectations(DisplayTransactionTest* test) {
8081
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, true)).Times(1);
82+
setupDisableSyntheticVsyncCallExpectations(test);
83+
}
84+
85+
static void setupDisableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
8186
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(_)).Times(0);
8287
}
8388

8489
static void setupDisableVsyncCallExpectations(DisplayTransactionTest* test) {
8590
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, false)).Times(1);
91+
setupEnableSyntheticVsyncCallExpectations(test);
92+
}
93+
94+
static void setupEnableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
8695
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(_)).Times(0);
8796
}
8897
};
@@ -91,12 +100,20 @@ struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
91100
static void setupEnableVsyncCallExpectations(DisplayTransactionTest* test) {
92101
// Expect to enable hardware VSYNC and disable synthetic VSYNC.
93102
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, true)).Times(1);
103+
setupDisableSyntheticVsyncCallExpectations(test);
104+
}
105+
106+
static void setupDisableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
94107
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(false)).Times(1);
95108
}
96109

97110
static void setupDisableVsyncCallExpectations(DisplayTransactionTest* test) {
98111
// Expect to disable hardware VSYNC and enable synthetic VSYNC.
99112
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, false)).Times(1);
113+
setupEnableSyntheticVsyncCallExpectations(test);
114+
}
115+
116+
static void setupEnableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
100117
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(true)).Times(1);
101118
}
102119
};
@@ -151,7 +168,7 @@ struct TransitionOffToDozeSuspendVariant
151168
template <typename Case>
152169
static void setupCallExpectations(DisplayTransactionTest* test) {
153170
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
154-
Case::EventThread::setupVsyncNoCallExpectations(test);
171+
Case::EventThread::setupEnableSyntheticVsyncCallExpectations(test);
155172
Case::setupRepaintEverythingCallExpectations(test);
156173
}
157174

@@ -176,7 +193,7 @@ struct TransitionDozeSuspendToOffVariant
176193
: public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::OFF> {
177194
template <typename Case>
178195
static void setupCallExpectations(DisplayTransactionTest* test) {
179-
Case::EventThread::setupVsyncNoCallExpectations(test);
196+
Case::EventThread::setupEnableSyntheticVsyncCallExpectations(test);
180197
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
181198
}
182199

@@ -188,7 +205,7 @@ struct TransitionDozeSuspendToOffVariant
188205
struct TransitionOnToDozeVariant : public TransitionVariantCommon<PowerMode::ON, PowerMode::DOZE> {
189206
template <typename Case>
190207
static void setupCallExpectations(DisplayTransactionTest* test) {
191-
Case::EventThread::setupVsyncNoCallExpectations(test);
208+
Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
192209
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
193210
}
194211
};
@@ -206,7 +223,7 @@ struct TransitionDozeSuspendToDozeVariant
206223
struct TransitionDozeToOnVariant : public TransitionVariantCommon<PowerMode::DOZE, PowerMode::ON> {
207224
template <typename Case>
208225
static void setupCallExpectations(DisplayTransactionTest* test) {
209-
Case::EventThread::setupVsyncNoCallExpectations(test);
226+
Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
210227
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
211228
}
212229
};
@@ -234,7 +251,7 @@ struct TransitionOnToUnknownVariant
234251
: public TransitionVariantCommon<PowerMode::ON, static_cast<PowerMode>(POWER_MODE_LEET)> {
235252
template <typename Case>
236253
static void setupCallExpectations(DisplayTransactionTest* test) {
237-
Case::EventThread::setupVsyncNoCallExpectations(test);
254+
Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
238255
Case::setupNoComposerPowerModeCallExpectations(test);
239256
}
240257
};
@@ -335,6 +352,9 @@ void SetPhysicalDisplayPowerModeTest::transitionDisplayCommon() {
335352
// --------------------------------------------------------------------
336353
// Preconditions
337354

355+
SET_FLAG_FOR_TEST(android::companion::virtualdevice::flags::correct_virtual_display_power_state,
356+
true);
357+
338358
Case::Doze::setupComposerCallExpectations(this);
339359
auto display =
340360
Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);

0 commit comments

Comments
 (0)