Skip to content

Commit e0ab7b9

Browse files
author
Vladimir Komsiyski
committed
Handle virtual display power state in SurfaceFlinger
If the state changes while there's no surface, the new power state is lost. Even though there's no DisplayDevice, there's a proper DisplayDeviceState for that virtual display. Storing the power state there and respecting it when creating the display will work. This is tied to android::companion::virtualdevice::flags::correct_virtual_display_power_state since that flag controls whether or not to set the power mode of the SurfaceControl for the virtual display (which ultimately feeds into SurfaceFlinger::setPowerMode). With this change, virtual displays whose PowerMode is OFF will no longer be composited since the correct power mode is now set in SurfaceFlinger (instead of assuming all virtual displays are ON). Bug: 342681202 Flag: android.companion.virtualdevice.flags.correct_virtual_display_power_state Test: manually tested with flag on/off with Android Auto Projected Change-Id: Ib10514da05e277a8ed574c92ff71d2a4d52975b2
1 parent 8520206 commit e0ab7b9

6 files changed

Lines changed: 59 additions & 19 deletions

File tree

services/surfaceflinger/DisplayDevice.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo {
180180
}
181181

182182
void DisplayDevice::setPowerMode(hal::PowerMode mode) {
183-
// TODO(b/241285876): Skip this for virtual displays.
184-
if (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON) {
183+
if (!isVirtual() && (mode == hal::PowerMode::OFF || mode == hal::PowerMode::ON)) {
185184
if (mStagedBrightness && mBrightness != mStagedBrightness) {
186185
getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
187186
mBrightness = *mStagedBrightness;

services/surfaceflinger/DisplayDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ struct DisplayDeviceState {
299299
Fps requestedRefreshRate;
300300
int32_t maxLayerPictureProfiles = 0;
301301
bool hasPictureProcessing = false;
302+
hardware::graphics::composer::hal::PowerMode initialPowerMode{
303+
hardware::graphics::composer::hal::PowerMode::OFF};
302304

303305
private:
304306
static std::atomic<int32_t> sNextSequenceId;

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ sp<IBinder> SurfaceFlinger::createVirtualDisplay(
589589
return nullptr;
590590
}
591591

592+
ALOGD("Creating virtual display: %s", displayName.c_str());
593+
592594
class DisplayToken : public BBinder {
593595
sp<SurfaceFlinger> flinger;
594596
virtual ~DisplayToken() {
@@ -613,6 +615,8 @@ sp<IBinder> SurfaceFlinger::createVirtualDisplay(
613615
// TODO (b/314820005): separate as a different arg when creating the display.
614616
state.isProtected = isSecure;
615617
state.optimizationPolicy = optimizationPolicy;
618+
// Virtual displays start in ON mode.
619+
state.initialPowerMode = hal::PowerMode::ON;
616620
state.displayName = displayName;
617621
state.uniqueId = uniqueId;
618622
state.requestedRefreshRate = Fps::fromValue(requestedRefreshRate);
@@ -634,6 +638,9 @@ status_t SurfaceFlinger::destroyVirtualDisplay(const sp<IBinder>& displayToken)
634638
ALOGE("%s: Invalid operation on physical display", __func__);
635639
return INVALID_OPERATION;
636640
}
641+
642+
ALOGD("Destroying virtual display: %s", state.displayName.c_str());
643+
637644
mCurrentState.displays.removeItemsAt(index);
638645
setTransactionFlags(eDisplayTransactionNeeded);
639646
return NO_ERROR;
@@ -3901,7 +3908,12 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
39013908
getPhysicalDisplayOrientation(compositionDisplay->getId(), creationArgs.isPrimary);
39023909
ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
39033910

3904-
creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
3911+
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
3912+
creationArgs.initialPowerMode = state.initialPowerMode;
3913+
} else {
3914+
creationArgs.initialPowerMode =
3915+
state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
3916+
}
39053917

39063918
creationArgs.requestedRefreshRate = state.requestedRefreshRate;
39073919

@@ -3975,6 +3987,8 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
39753987
// Virtual displays without a surface are dormant:
39763988
// they have external state (layer stack, projection,
39773989
// etc.) but no internal state (i.e. a DisplayDevice).
3990+
ALOGD("Not adding dormant virtual display with token %p: %s", displayToken.unsafe_get(),
3991+
state.displayName.c_str());
39783992
return;
39793993
}
39803994

@@ -5806,16 +5820,32 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:
58065820
}
58075821

58085822
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
5809-
auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
5810-
kMainThreadContext) {
5823+
auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) {
58115824
mSkipPowerOnForQuiescent = false;
5812-
const auto display = getDisplayDeviceLocked(displayToken);
5825+
const auto display = FTL_FAKE_GUARD(mStateLock, getDisplayDeviceLocked(displayToken));
58135826
if (!display) {
5814-
ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
5815-
displayToken.get());
5827+
Mutex::Autolock lock(mStateLock);
5828+
const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
5829+
if (index >= 0) {
5830+
auto& state = mCurrentState.displays.editValueFor(displayToken);
5831+
if (state.isVirtual()) {
5832+
ALOGD("Setting power mode %d for a dormant virtual display with token %p", mode,
5833+
displayToken.get());
5834+
state.initialPowerMode = static_cast<hal::PowerMode>(mode);
5835+
return;
5836+
}
5837+
}
5838+
ALOGE("Failed to set power mode %d for display token %p", mode, displayToken.get());
58165839
} else if (display->isVirtual()) {
5817-
ALOGW("Attempt to set power mode %d for virtual display", mode);
5840+
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));
5844+
} else {
5845+
ALOGW("Attempt to set power mode %d for virtual display", mode);
5846+
}
58185847
} else {
5848+
ftl::FakeGuard guard(mStateLock);
58195849
setPowerModeInternal(display, static_cast<hal::PowerMode>(mode));
58205850
}
58215851
});

services/surfaceflinger/common/Android.bp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ cc_defaults {
1616
],
1717
shared_libs: [
1818
"libSurfaceFlingerProp",
19-
"server_configurable_flags",
2019
"libaconfig_storage_read_api_cc",
2120
"libtracing_perfetto",
21+
"server_configurable_flags",
2222
],
2323
static_libs: [
2424
"librenderengine_includes",
@@ -37,11 +37,12 @@ cc_library_static {
3737
"libsurfaceflinger_common_defaults",
3838
],
3939
static_libs: [
40-
"libsurfaceflingerflags",
4140
"aconfig_hardware_flags_c_lib",
41+
"android.companion.virtualdevice.flags-aconfig-cc",
4242
"android.os.flags-aconfig-cc",
4343
"android.server.display.flags-aconfig-cc",
4444
"libguiflags_no_apex",
45+
"libsurfaceflingerflags",
4546
],
4647
}
4748

@@ -51,44 +52,47 @@ cc_library_static {
5152
"libsurfaceflinger_common_defaults",
5253
],
5354
static_libs: [
54-
"libsurfaceflingerflags_test",
5555
"aconfig_hardware_flags_c_lib",
56+
"android.companion.virtualdevice.flags-aconfig-cc",
5657
"android.os.flags-aconfig-cc-test",
5758
"android.server.display.flags-aconfig-cc",
5859
"libguiflags_no_apex",
60+
"libsurfaceflingerflags_test",
5961
],
6062
}
6163

6264
cc_defaults {
6365
name: "libsurfaceflinger_common_deps",
6466
shared_libs: [
65-
"server_configurable_flags",
6667
"libaconfig_storage_read_api_cc",
6768
"libtracing_perfetto",
69+
"server_configurable_flags",
6870
],
6971
static_libs: [
70-
"libsurfaceflinger_common",
71-
"libsurfaceflingerflags",
7272
"aconfig_hardware_flags_c_lib",
73+
"android.companion.virtualdevice.flags-aconfig-cc",
7374
"android.os.flags-aconfig-cc",
7475
"android.server.display.flags-aconfig-cc",
7576
"libguiflags_no_apex",
77+
"libsurfaceflinger_common",
78+
"libsurfaceflingerflags",
7679
],
7780
}
7881

7982
cc_defaults {
8083
name: "libsurfaceflinger_common_test_deps",
8184
shared_libs: [
82-
"server_configurable_flags",
8385
"libaconfig_storage_read_api_cc",
8486
"libtracing_perfetto",
87+
"server_configurable_flags",
8588
],
8689
static_libs: [
87-
"libsurfaceflinger_common_test",
88-
"libsurfaceflingerflags_test",
8990
"aconfig_hardware_flags_c_lib",
91+
"android.companion.virtualdevice.flags-aconfig-cc",
9092
"android.os.flags-aconfig-cc-test",
9193
"android.server.display.flags-aconfig-cc",
9294
"libguiflags_no_apex",
95+
"libsurfaceflinger_common_test",
96+
"libsurfaceflingerflags_test",
9397
],
9498
}

services/surfaceflinger/common/FlagManager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
#include <server_configurable_flags/get_flags.h>
2727
#include <cinttypes>
2828

29-
#include <android_os.h>
29+
#include <android_companion_virtualdevice_flags.h>
3030
#include <android_hardware_flags.h>
31+
#include <android_os.h>
3132
#include <com_android_graphics_libgui_flags.h>
3233
#include <com_android_graphics_surfaceflinger_flags.h>
3334
#include <com_android_server_display_feature_flags.h>
@@ -125,6 +126,7 @@ void FlagManager::dump(std::string& result) const {
125126
DUMP_ACONFIG_FLAG(adpf_gpu_sf);
126127
DUMP_ACONFIG_FLAG(adpf_native_session_manager);
127128
DUMP_ACONFIG_FLAG(adpf_use_fmq_channel);
129+
DUMP_ACONFIG_FLAG(correct_virtual_display_power_state);
128130
DUMP_ACONFIG_FLAG(graphite_renderengine_preview_rollout);
129131
DUMP_ACONFIG_FLAG(increase_missed_frame_jank_threshold);
130132
DUMP_ACONFIG_FLAG(refresh_rate_overlay_on_external_display);
@@ -309,6 +311,8 @@ FLAG_MANAGER_ACONFIG_FLAG(vsync_predictor_recovery, "");
309311

310312
/// Trunk stable server (R/W) flags from outside SurfaceFlinger ///
311313
FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(adpf_use_fmq_channel, "", android::os)
314+
FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(correct_virtual_display_power_state, "",
315+
android::companion::virtualdevice::flags)
312316

313317
/// Trunk stable readonly flags from outside SurfaceFlinger ///
314318
FLAG_MANAGER_ACONFIG_FLAG_IMPORTED(idle_screen_refresh_rate_timeout, "",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class FlagManager {
6060
bool adpf_native_session_manager() const;
6161
bool adpf_use_fmq_channel() const;
6262
bool adpf_use_fmq_channel_fixed() const;
63+
bool correct_virtual_display_power_state() const;
6364
bool graphite_renderengine_preview_rollout() const;
6465
bool increase_missed_frame_jank_threshold() const;
6566
bool refresh_rate_overlay_on_external_display() const;

0 commit comments

Comments
 (0)