diff options
| author | 2023-06-05 17:49:32 -0400 | |
|---|---|---|
| committer | 2023-08-04 11:24:16 -0400 | |
| commit | 689c80f4cb31d6903295aa69a706e7a2c16f8500 (patch) | |
| tree | d820f2476b52ffa2edc43b9bf804b9dbbbd8db99 | |
| parent | 4c1b3b73463318ccaedd6864b30cf7f5047de4c2 (diff) | |
HWComposer: setPowerMode to DOZE even if support is unknown
If a display has not been turned on since boot, we do not know whether
it supports doze. Rather than treating this as not supported, make
Display::supportsDoze return an error if the capabilities have not been
queried yet. If supportsDoze returns this error, try to set the mode to
DOZE(_SUSPEND) anyway. This allows properly waking from AOD.
If the call to Display::setPowerMode fails, this means it truly is not
supported, so fallback to the old behavior of turning it ON.
Fixes: 274722476
Test: manual
Test: GraphicsComposerAidlTest#SetPowerModeUnsupported
Change-Id: Ia88603565713ea4b6ec5142b693d2df1302131ea
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWC2.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 22 |
2 files changed, 24 insertions, 6 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index aaf2523338..0c2b77de7d 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -311,6 +311,14 @@ bool Display::hasCapability(DisplayCapability capability) const { } Error Display::supportsDoze(bool* outSupport) const { + { + std::scoped_lock lock(mDisplayCapabilitiesMutex); + if (!mDisplayCapabilities) { + // The display has not turned on since boot, so DOZE support is unknown. + ALOGW("%s: haven't queried capabilities yet!", __func__); + return Error::NO_RESOURCES; + } + } *outSupport = hasCapability(DisplayCapability::DOZE); return Error::NONE; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 3177b33538..a9bb928f59 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -616,19 +616,29 @@ status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mo ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str()); { bool supportsDoze = false; - auto error = hwcDisplay->supportsDoze(&supportsDoze); - if (error != hal::Error::NONE) { - LOG_HWC_ERROR("supportsDoze", error, displayId); - } + const auto queryDozeError = hwcDisplay->supportsDoze(&supportsDoze); - if (!supportsDoze) { + // queryDozeError might be NO_RESOURCES, in the case of a display that has never + // been turned on. In that case, attempt to set to DOZE anyway. + if (!supportsDoze && queryDozeError == hal::Error::NONE) { mode = hal::PowerMode::ON; } - error = hwcDisplay->setPowerMode(mode); + auto error = hwcDisplay->setPowerMode(mode); if (error != hal::Error::NONE) { LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId); + // If the display had never been turned on, so its doze + // support was unknown, it may truly not support doze. Try + // switching it to ON instead. + if (queryDozeError == hal::Error::NO_RESOURCES) { + ALOGD("%s: failed to set %s to %s. Trying again with ON", __func__, + to_string(displayId).c_str(), to_string(mode).c_str()); + error = hwcDisplay->setPowerMode(hal::PowerMode::ON); + if (error != hal::Error::NONE) { + LOG_HWC_ERROR("setPowerMode(ON)", error, displayId); + } + } } } break; |