Merge "SF: Requery display modes if the active mode is not supported" into sc-dev
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index cf6bc68..f532e50 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -91,6 +91,12 @@
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 424c511..ad91183 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 @@
// 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 @@
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 @@
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 8fe8bb1..6434ca2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -942,7 +942,8 @@
/*
* 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,