Skip to content

Commit 744e83f

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Turn off synthetic VSYNC when adjusting thread scheduling for performance" into main
2 parents 992d0eb + a28d830 commit 744e83f

File tree

8 files changed

+107
-71
lines changed

8 files changed

+107
-71
lines changed

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: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5679,7 +5679,15 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
56795679
incRefreshableDisplays();
56805680
}
56815681

5682+
const bool shouldApplyOptimizationPolicy =
5683+
FlagManager::getInstance().disable_synthetic_vsync_for_performance() &&
5684+
FlagManager::getInstance().correct_virtual_display_power_state();
5685+
if (isInternalDisplay && shouldApplyOptimizationPolicy) {
5686+
applyOptimizationPolicy(__func__);
5687+
}
5688+
56825689
const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
5690+
using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
56835691
if (currentMode == hal::PowerMode::OFF) {
56845692
// Turn on the display
56855693

@@ -5694,12 +5702,9 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
56945702
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
56955703
}
56965704

5697-
if (displayId == mActiveDisplayId) {
5698-
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5699-
applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)");
5700-
} else {
5701-
disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)");
5702-
}
5705+
if (displayId == mActiveDisplayId && !shouldApplyOptimizationPolicy) {
5706+
optimizeThreadScheduling("setPhysicalDisplayPowerMode(ON/DOZE)",
5707+
OptimizationPolicy::optimizeForPerformance);
57035708
}
57045709

57055710
getHwComposer().setPowerMode(displayId, mode);
@@ -5708,7 +5713,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57085713
mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState();
57095714
requestHardwareVsync(displayId, enable);
57105715

5711-
if (displayId == mActiveDisplayId) {
5716+
if (displayId == mActiveDisplayId && !shouldApplyOptimizationPolicy) {
57125717
mScheduler->enableSyntheticVsync(false);
57135718
}
57145719

@@ -5725,13 +5730,12 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57255730
if (const auto display = getActivatableDisplay()) {
57265731
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
57275732
} else {
5728-
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
5729-
applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)");
5730-
} else {
5731-
enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)");
5733+
if (!shouldApplyOptimizationPolicy) {
5734+
optimizeThreadScheduling("setPhysicalDisplayPowerMode(OFF)",
5735+
OptimizationPolicy::optimizeForPower);
57325736
}
57335737

5734-
if (currentModeNotDozeSuspend) {
5738+
if (currentModeNotDozeSuspend && !shouldApplyOptimizationPolicy) {
57355739
mScheduler->enableSyntheticVsync();
57365740
}
57375741
}
@@ -5759,7 +5763,9 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57595763
ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
57605764
mVisibleRegionsDirty = true;
57615765
scheduleRepaint();
5762-
mScheduler->enableSyntheticVsync(false);
5766+
if (!shouldApplyOptimizationPolicy) {
5767+
mScheduler->enableSyntheticVsync(false);
5768+
}
57635769
}
57645770
constexpr bool kAllowToEnable = true;
57655771
mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
@@ -5769,7 +5775,7 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
57695775
constexpr bool kDisallow = true;
57705776
mScheduler->disableHardwareVsync(displayId, kDisallow);
57715777

5772-
if (displayId == mActiveDisplayId) {
5778+
if (displayId == mActiveDisplayId && !shouldApplyOptimizationPolicy) {
57735779
mScheduler->enableSyntheticVsync();
57745780
}
57755781
getHwComposer().setPowerMode(displayId, mode);
@@ -5808,43 +5814,44 @@ void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display
58085814
to_string(displayId).c_str());
58095815
}
58105816

5811-
bool SurfaceFlinger::shouldOptimizeForPerformance() {
5812-
for (const auto& [_, display] : mDisplays) {
5813-
// Displays that are optimized for power are always powered on and should not influence
5814-
// whether there is an active display for the purpose of power optimization, etc. If these
5815-
// displays are being shown somewhere, a different (physical or virtual) display that is
5816-
// optimized for performance will be powered on in addition. Displays optimized for
5817-
// performance will change power mode, so if they are off then they are not active.
5818-
if (display->isPoweredOn() &&
5819-
display->getOptimizationPolicy() ==
5820-
gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
5821-
return true;
5822-
}
5823-
}
5824-
return false;
5825-
}
5826-
5827-
void SurfaceFlinger::enablePowerOptimizations(const char* whence) {
5828-
ALOGD("%s: Enabling power optimizations", whence);
5829-
5830-
setSchedAttr(false, whence);
5831-
setSchedFifo(false, whence);
5832-
}
5833-
5834-
void SurfaceFlinger::disablePowerOptimizations(const char* whence) {
5835-
ALOGD("%s: Disabling power optimizations", whence);
5817+
void SurfaceFlinger::optimizeThreadScheduling(
5818+
const char* whence, gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
5819+
ALOGD("%s: Optimizing thread scheduling: %s", whence, to_string(optimizationPolicy));
58365820

5821+
const bool optimizeForPerformance =
5822+
optimizationPolicy == gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
58375823
// TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
58385824
// and set it before SCHED_FIFO due to b/190237315.
5839-
setSchedAttr(true, whence);
5840-
setSchedFifo(true, whence);
5825+
setSchedAttr(optimizeForPerformance, whence);
5826+
setSchedFifo(optimizeForPerformance, whence);
58415827
}
58425828

58435829
void SurfaceFlinger::applyOptimizationPolicy(const char* whence) {
5844-
if (shouldOptimizeForPerformance()) {
5845-
disablePowerOptimizations(whence);
5846-
} else {
5847-
enablePowerOptimizations(whence);
5830+
using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
5831+
5832+
const bool optimizeForPerformance =
5833+
std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
5834+
const auto& display = pair.second;
5835+
return display->isPoweredOn() &&
5836+
display->getOptimizationPolicy() ==
5837+
OptimizationPolicy::optimizeForPerformance;
5838+
});
5839+
5840+
optimizeThreadScheduling(whence,
5841+
optimizeForPerformance ? OptimizationPolicy::optimizeForPerformance
5842+
: OptimizationPolicy::optimizeForPower);
5843+
5844+
if (mScheduler) {
5845+
const bool disableSyntheticVsync =
5846+
std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
5847+
const auto& display = pair.second;
5848+
const hal::PowerMode powerMode = display->getPowerMode();
5849+
return powerMode != hal::PowerMode::OFF &&
5850+
powerMode != hal::PowerMode::DOZE_SUSPEND &&
5851+
display->getOptimizationPolicy() ==
5852+
OptimizationPolicy::optimizeForPerformance;
5853+
});
5854+
mScheduler->enableSyntheticVsync(!disableSyntheticVsync);
58485855
}
58495856
}
58505857

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/common/FlagManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ void FlagManager::dump(std::string& result) const {
147147
DUMP_ACONFIG_FLAG(deprecate_frame_tracker);
148148
DUMP_ACONFIG_FLAG(deprecate_vsync_sf);
149149
DUMP_ACONFIG_FLAG(detached_mirror);
150+
DUMP_ACONFIG_FLAG(disable_synthetic_vsync_for_performance);
150151
DUMP_ACONFIG_FLAG(display_config_error_hal);
151152
DUMP_ACONFIG_FLAG(display_protected);
152153
DUMP_ACONFIG_FLAG(dont_skip_on_early_ro);
@@ -284,6 +285,7 @@ FLAG_MANAGER_ACONFIG_FLAG(latch_unsignaled_with_auto_refresh_changed, "");
284285
FLAG_MANAGER_ACONFIG_FLAG(deprecate_vsync_sf, "");
285286
FLAG_MANAGER_ACONFIG_FLAG(allow_n_vsyncs_in_targeter, "");
286287
FLAG_MANAGER_ACONFIG_FLAG(detached_mirror, "");
288+
FLAG_MANAGER_ACONFIG_FLAG(disable_synthetic_vsync_for_performance, "");
287289
FLAG_MANAGER_ACONFIG_FLAG(commit_not_composited, "");
288290
FLAG_MANAGER_ACONFIG_FLAG(correct_dpi_with_display_size, "");
289291
FLAG_MANAGER_ACONFIG_FLAG(local_tonemap_screenshots, "debug.sf.local_tonemap_screenshots");

services/surfaceflinger/common/include/common/FlagManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class FlagManager {
8181
bool deprecate_frame_tracker() const;
8282
bool deprecate_vsync_sf() const;
8383
bool detached_mirror() const;
84+
bool disable_synthetic_vsync_for_performance() const;
8485
bool display_config_error_hal() const;
8586
bool display_protected() const;
8687
bool dont_skip_on_early_ro() const;

services/surfaceflinger/surfaceflinger_flags_new.aconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ flag {
133133
}
134134
} # detached_mirror
135135

136+
flag {
137+
name: "disable_synthetic_vsync_for_performance"
138+
namespace: "core_graphics"
139+
description: "Turn off synthetic VSYNC when adjusting thread scheduling for performance"
140+
bug: "406147398"
141+
metadata {
142+
purpose: PURPOSE_BUGFIX
143+
}
144+
} # disable_synthetic_vsync_for_performance
145+
136146
flag {
137147
name: "display_config_error_hal"
138148
namespace: "core_graphics"

services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp

Lines changed: 26 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,10 @@ void SetPhysicalDisplayPowerModeTest::transitionDisplayCommon() {
335352
// --------------------------------------------------------------------
336353
// Preconditions
337354

355+
SET_FLAG_FOR_TEST(android::companion::virtualdevice::flags::correct_virtual_display_power_state,
356+
true);
357+
SET_FLAG_FOR_TEST(flags::disable_synthetic_vsync_for_performance, true);
358+
338359
Case::Doze::setupComposerCallExpectations(this);
339360
auto display =
340361
Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);

0 commit comments

Comments
 (0)