diff options
| -rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 47 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 |
3 files changed, 42 insertions, 14 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index cf6bc68897..f532e50df0 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -91,6 +91,12 @@ public: int32_t dpiX = -1; int32_t dpiY = -1; int32_t configGroup = -1; + + friend std::ostream& operator<<(std::ostream& os, const HWCDisplayMode& mode) { + return os << "id=" << mode.hwcId << " res=" << mode.width << "x" << mode.height + << " vsyncPeriod=" << mode.vsyncPeriod << " dpi=" << mode.dpiX << "x" + << mode.dpiY << " group=" << mode.configGroup; + } }; virtual ~HWComposer(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 424c511272..ad91183f18 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -104,6 +104,7 @@ #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" +#include "DisplayHardware/Hal.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "DisplayRenderArea.h" #include "EffectLayer.h" @@ -131,6 +132,7 @@ #include "TimeStats/TimeStats.h" #include "android-base/parseint.h" #include "android-base/stringprintf.h" +#include "android-base/strings.h" #define MAIN_THREAD ACQUIRE(mStateLock) RELEASE(mStateLock) @@ -2306,8 +2308,28 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) { // here the transaction has been committed } -DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId displayId) const { - const auto hwcModes = getHwComposer().getModes(displayId); +void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes, + DisplayModePtr& outActiveMode) const { + std::vector<HWComposer::HWCDisplayMode> hwcModes; + std::optional<hal::HWDisplayId> activeModeHwcId; + bool activeModeIsSupported; + int attempt = 0; + constexpr int kMaxAttempts = 3; + do { + hwcModes = getHwComposer().getModes(displayId); + activeModeHwcId = getHwComposer().getActiveMode(displayId); + LOG_ALWAYS_FATAL_IF(!activeModeHwcId, "HWC returned no active mode"); + + activeModeIsSupported = + std::any_of(hwcModes.begin(), hwcModes.end(), + [activeModeHwcId](const HWComposer::HWCDisplayMode& mode) { + return mode.hwcId == *activeModeHwcId; + }); + } while (!activeModeIsSupported && ++attempt < kMaxAttempts); + LOG_ALWAYS_FATAL_IF(!activeModeIsSupported, + "After %d attempts HWC still returns an active mode which is not" + " supported. Active mode ID = %" PRIu64 " . Supported modes = %s", + kMaxAttempts, *activeModeHwcId, base::Join(hwcModes, ", ").c_str()); DisplayModes oldModes; @@ -2345,10 +2367,15 @@ DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId display if (modesAreSame) { // The supported modes have not changed, keep the old IDs. - return oldModes; + outModes = oldModes; + } else { + outModes = newModes; } - return newModes; + outActiveMode = *std::find_if(outModes.begin(), outModes.end(), + [activeModeHwcId](const DisplayModePtr& mode) { + return mode->getHwcId() == *activeModeHwcId; + }); } void SurfaceFlinger::processDisplayHotplugEventsLocked() { @@ -2364,15 +2391,9 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { const auto it = mPhysicalDisplayTokens.find(displayId); if (event.connection == hal::Connection::CONNECTED) { - auto supportedModes = loadSupportedDisplayModes(displayId); - const auto activeModeHwcId = getHwComposer().getActiveMode(displayId); - LOG_ALWAYS_FATAL_IF(!activeModeHwcId, "HWC returned no active mode"); - - const auto activeMode = *std::find_if(supportedModes.begin(), supportedModes.end(), - [activeModeHwcId](const DisplayModePtr& mode) { - return mode->getHwcId() == *activeModeHwcId; - }); - // TODO(b/175678215) Handle the case when activeMode is not in supportedModes + DisplayModes supportedModes; + DisplayModePtr activeMode; + loadDisplayModes(displayId, supportedModes, activeMode); if (it == mPhysicalDisplayTokens.end()) { ALOGV("Creating display %s", to_string(displayId).c_str()); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 8fe8bb16df..6434ca29ff 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -942,7 +942,8 @@ private: /* * Display management */ - DisplayModes loadSupportedDisplayModes(PhysicalDisplayId) const REQUIRES(mStateLock); + void loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes, + DisplayModePtr& outActiveMode) const REQUIRES(mStateLock); sp<DisplayDevice> setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, |