summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp15
-rw-r--r--services/surfaceflinger/DisplayDevice.h2
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayMode.h6
-rw-r--r--services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp9
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp52
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
6 files changed, 60 insertions, 26 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 36c4c4d5ba..f4a2a3f03a 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -145,9 +145,9 @@ bool DisplayDevice::isPoweredOn() const {
}
void DisplayDevice::setActiveMode(DisplayModeId id) {
- LOG_FATAL_IF(id.value() >= mSupportedModes.size(),
- "Cannot set active mode which is not supported.");
- mActiveModeId = id;
+ const auto mode = getMode(id);
+ LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported.");
+ mActiveMode = mode;
}
status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
@@ -164,7 +164,7 @@ status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
}
const DisplayModePtr& DisplayDevice::getActiveMode() const {
- return mSupportedModes[mActiveModeId.value()];
+ return mActiveMode;
}
const DisplayModes& DisplayDevice::getSupportedModes() const {
@@ -172,9 +172,10 @@ const DisplayModes& DisplayDevice::getSupportedModes() const {
}
DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
- const auto id = modeId.value();
- if (static_cast<size_t>(id) < mSupportedModes.size()) {
- return mSupportedModes[id];
+ const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
+ [&](DisplayModePtr mode) { return mode->getId() == modeId; });
+ if (it != mSupportedModes.end()) {
+ return *it;
}
return nullptr;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index a94bfa269d..7156613631 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -208,7 +208,7 @@ private:
hardware::graphics::composer::hal::PowerMode mPowerMode =
hardware::graphics::composer::hal::PowerMode::OFF;
- DisplayModeId mActiveModeId;
+ DisplayModePtr mActiveMode;
const DisplayModes mSupportedModes;
std::atomic<nsecs_t> mLastHwVsync = 0;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayMode.h b/services/surfaceflinger/DisplayHardware/DisplayMode.h
index 853c05b244..85cc993c67 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayMode.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayMode.h
@@ -125,6 +125,12 @@ public:
// without visual interruptions such as a black screen.
int32_t getGroup() const { return mGroup; }
+ bool equalsExceptDisplayModeId(const DisplayModePtr& other) const {
+ return mHwcId == other->mHwcId && mWidth == other->mWidth && mHeight == other->mHeight &&
+ getVsyncPeriod() == other->getVsyncPeriod() && mDpiX == other->mDpiX &&
+ mDpiY == other->mDpiY && mGroup == other->mGroup;
+ }
+
private:
explicit DisplayMode(hal::HWConfigId id) : mHwcId(id) {}
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index de11c16f64..91e80432a4 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -610,15 +610,16 @@ RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId
void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes,
DisplayModeId currentModeId) {
std::lock_guard lock(mLock);
- LOG_ALWAYS_FATAL_IF(modes.empty());
- LOG_ALWAYS_FATAL_IF(currentModeId.value() >= modes.size());
+ // The current mode should be supported
+ LOG_ALWAYS_FATAL_IF(std::none_of(modes.begin(), modes.end(), [&](DisplayModePtr mode) {
+ return mode->getId() == currentModeId;
+ }));
mRefreshRates.clear();
for (const auto& mode : modes) {
const auto modeId = mode->getId();
- const auto fps = Fps::fromPeriodNsecs(mode->getVsyncPeriod());
mRefreshRates.emplace(modeId,
- std::make_unique<RefreshRate>(modeId, mode, fps,
+ std::make_unique<RefreshRate>(modeId, mode, mode->getFps(),
RefreshRate::ConstructorTag(0)));
if (modeId == currentModeId) {
mCurrentRefreshRate = mRefreshRates.at(modeId).get();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 350a3c81f3..056dd9f4a2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2308,20 +2308,47 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) {
DisplayModes SurfaceFlinger::loadSupportedDisplayModes(PhysicalDisplayId displayId) const {
const auto hwcModes = getHwComposer().getModes(displayId);
- DisplayModes modes;
- int32_t nextModeId = 0;
+
+ DisplayModes oldModes;
+
+ if (const auto token = getPhysicalDisplayTokenLocked(displayId)) {
+ oldModes = getDisplayDeviceLocked(token)->getSupportedModes();
+ }
+
+ int largestUsedModeId = -1; // Use int instead of DisplayModeId for signedness
+ for (const auto& mode : oldModes) {
+ const auto id = static_cast<int>(mode->getId().value());
+ if (id > largestUsedModeId) {
+ largestUsedModeId = id;
+ }
+ }
+
+ DisplayModes newModes;
+ int32_t nextModeId = largestUsedModeId + 1;
for (const auto& hwcMode : hwcModes) {
- modes.push_back(DisplayMode::Builder(hwcMode.hwcId)
- .setId(DisplayModeId{nextModeId++})
- .setWidth(hwcMode.width)
- .setHeight(hwcMode.height)
- .setVsyncPeriod(hwcMode.vsyncPeriod)
- .setDpiX(hwcMode.dpiX)
- .setDpiY(hwcMode.dpiY)
- .setGroup(hwcMode.configGroup)
- .build());
+ newModes.push_back(DisplayMode::Builder(hwcMode.hwcId)
+ .setId(DisplayModeId{nextModeId++})
+ .setWidth(hwcMode.width)
+ .setHeight(hwcMode.height)
+ .setVsyncPeriod(hwcMode.vsyncPeriod)
+ .setDpiX(hwcMode.dpiX)
+ .setDpiY(hwcMode.dpiY)
+ .setGroup(hwcMode.configGroup)
+ .build());
}
- return modes;
+
+ const bool modesAreSame =
+ std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
+ [](DisplayModePtr left, DisplayModePtr right) {
+ return left->equalsExceptDisplayModeId(right);
+ });
+
+ if (modesAreSame) {
+ // The supported modes have not changed, keep the old IDs.
+ return oldModes;
+ }
+
+ return newModes;
}
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
@@ -2414,7 +2441,6 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
const sp<IGraphicBufferProducer>& producer) {
DisplayDeviceCreationArgs creationArgs(this, getHwComposer(), displayToken, compositionDisplay);
creationArgs.sequenceId = state.sequenceId;
- creationArgs.hwComposer = getHwComposer();
creationArgs.isSecure = state.isSecure;
creationArgs.displaySurface = displaySurface;
creationArgs.hasWideColorGamut = false;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1615ab6d35..d1eae1ca61 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -906,7 +906,7 @@ private:
/*
* Display management
*/
- DisplayModes loadSupportedDisplayModes(PhysicalDisplayId) const;
+ DisplayModes loadSupportedDisplayModes(PhysicalDisplayId) const REQUIRES(mStateLock);
sp<DisplayDevice> setupNewDisplayDeviceInternal(
const wp<IBinder>& displayToken,
std::shared_ptr<compositionengine::Display> compositionDisplay,