SF: Clean up plumbing for boot display mode
Avoid CE round trip, and validate API against virtual displays.
Bug: 182939859
Test: Boot
Change-Id: Ic4e14dcc06218097c65f9374f2962a345d347820
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 6a3fcb7..16cb41b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -56,9 +56,6 @@
// similar requests if needed.
virtual void createClientCompositionCache(uint32_t cacheSize) = 0;
- // Returns the boot display mode preferred by HWC.
- virtual int32_t getPreferredBootHwcConfigId() const = 0;
-
protected:
~Display() = default;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 58d2530..e12d1b4 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -62,7 +62,6 @@
bool isSecure() const override;
bool isVirtual() const override;
void disconnect() override;
- int32_t getPreferredBootHwcConfigId() const override;
void createDisplayColorProfile(
const compositionengine::DisplayColorProfileCreationArgs&) override;
void createRenderSurface(const compositionengine::RenderSurfaceCreationArgs&) override;
@@ -88,7 +87,6 @@
DisplayId mId;
bool mIsDisconnected = false;
Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
- int32_t mPreferredBootHwcConfigId = -1;
};
// This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 6a75283..2165e1d 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -58,16 +58,6 @@
editState().isSecure = args.isSecure;
editState().displaySpace.setBounds(args.pixels);
setName(args.name);
- bool isBootModeSupported = getCompositionEngine().getHwComposer().getBootDisplayModeSupport();
- const auto physicalId = PhysicalDisplayId::tryCast(mId);
- if (!physicalId || !isBootModeSupported) {
- return;
- }
- std::optional<hal::HWConfigId> preferredBootModeId =
- getCompositionEngine().getHwComposer().getPreferredBootDisplayMode(*physicalId);
- if (preferredBootModeId.has_value()) {
- mPreferredBootHwcConfigId = static_cast<int32_t>(preferredBootModeId.value());
- }
}
bool Display::isValid() const {
@@ -90,10 +80,6 @@
return mId;
}
-int32_t Display::getPreferredBootHwcConfigId() const {
- return mPreferredBootHwcConfigId;
-}
-
void Display::disconnect() {
if (mIsDisconnected) {
return;
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 1f1dd1a..a8cad53 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -112,8 +112,8 @@
MOCK_METHOD1(getPreferredBootDisplayMode, std::optional<hal::HWConfigId>(PhysicalDisplayId));
MOCK_METHOD0(getBootDisplayModeSupport, bool());
MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
- MOCK_METHOD2(getSupportedContentTypes,
- status_t(PhysicalDisplayId, std::vector<hal::ContentType>*));
+ MOCK_METHOD(status_t, getSupportedContentTypes,
+ (PhysicalDisplayId, std::vector<hal::ContentType>*), (const, override));
MOCK_METHOD2(setContentType, status_t(PhysicalDisplayId, hal::ContentType));
MOCK_CONST_METHOD0(getSupportedLayerGenericMetadata,
const std::unordered_map<std::string, bool>&());
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 45b98bb..99335e5 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -227,21 +227,23 @@
}
DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
- const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
- [&](DisplayModePtr mode) { return mode->getId() == modeId; });
+ const auto it =
+ std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
+ [&](const DisplayModePtr& mode) { return mode->getId() == modeId; });
if (it != mSupportedModes.end()) {
return *it;
}
return nullptr;
}
-DisplayModePtr DisplayDevice::getModefromHwcId(uint32_t hwcId) const {
- const auto it = std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
- [&](DisplayModePtr mode) { return mode->getHwcId() == hwcId; });
+std::optional<DisplayModeId> DisplayDevice::translateModeId(hal::HWConfigId hwcId) const {
+ const auto it =
+ std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
+ [&](const DisplayModePtr& mode) { return mode->getHwcId() == hwcId; });
if (it != mSupportedModes.end()) {
- return *it;
+ return (*it)->getId();
}
- return nullptr;
+ return {};
}
nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
@@ -468,16 +470,6 @@
capabilities.getDesiredMinLuminance());
}
-ui::DisplayModeId DisplayDevice::getPreferredBootModeId() const {
- const auto preferredBootHwcModeId = mCompositionDisplay->getPreferredBootHwcConfigId();
- const auto mode = getModefromHwcId(preferredBootHwcModeId);
- if (mode == nullptr) {
- ALOGE("%s: invalid display mode (%d)", __FUNCTION__, preferredBootHwcModeId);
- return BAD_VALUE;
- }
- return mode->getId().value();
-}
-
void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
if (!enable) {
mRefreshRateOverlay.reset();
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 690f240..2c4a300 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -157,9 +157,6 @@
// respectively if hardware composer doesn't return meaningful values.
HdrCapabilities getHdrCapabilities() const;
- // Returns the boot display mode preferred by the implementation.
- ui::DisplayModeId getPreferredBootModeId() const;
-
// Return true if intent is supported by the display.
bool hasRenderIntent(ui::RenderIntent intent) const;
@@ -232,8 +229,7 @@
// set-top boxes after a hotplug reconnect.
DisplayModePtr getMode(DisplayModeId) const;
- // Returns nullptr if the given mode ID is not supported.
- DisplayModePtr getModefromHwcId(uint32_t) const;
+ std::optional<DisplayModeId> translateModeId(hal::HWConfigId) const;
// Returns the refresh rate configs for this display.
scheduler::RefreshRateConfigs& refreshRateConfigs() const { return *mRefreshRateConfigs; }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 02b3772..7b9ffed 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -814,10 +814,11 @@
}
status_t HWComposer::getSupportedContentTypes(
- PhysicalDisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
+ PhysicalDisplayId displayId,
+ std::vector<hal::ContentType>* outSupportedContentTypes) const {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- const auto error =
- mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
+ const auto error = mDisplayData.at(displayId).hwcDisplay->getSupportedContentTypes(
+ outSupportedContentTypes);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f9637f0..3dd910b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -234,8 +234,16 @@
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
virtual status_t getSupportedContentTypes(
- PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
+ PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) const = 0;
+
+ bool supportsContentType(PhysicalDisplayId displayId, hal::ContentType type) const {
+ std::vector<hal::ContentType> types;
+ return getSupportedContentTypes(displayId, &types) == NO_ERROR &&
+ std::find(types.begin(), types.end(), type) != types.end();
+ }
+
virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
+
virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
const = 0;
@@ -390,7 +398,8 @@
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
- status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
+ status_t getSupportedContentTypes(PhysicalDisplayId,
+ std::vector<hal::ContentType>*) const override;
status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 425b78b..94b16b4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -578,13 +578,13 @@
const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
if (index < 0) {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
return;
}
const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
if (state.physical) {
- ALOGE("%s: Invalid operation on physical display", __FUNCTION__);
+ ALOGE("%s: Invalid operation on physical display", __func__);
return;
}
mInterceptor->saveDisplayDeletion(state.sequenceId);
@@ -1039,7 +1039,7 @@
return INVALID_OPERATION;
}
- info->activeDisplayModeId = static_cast<int32_t>(display->getActiveMode()->getId().value());
+ info->activeDisplayModeId = display->getActiveMode()->getId().value();
const auto& supportedModes = display->getSupportedModes();
info->supportedDisplayModes.clear();
@@ -1104,13 +1104,17 @@
info->autoLowLatencyModeSupported =
getHwComposer().hasDisplayCapability(*displayId,
DisplayCapability::AUTO_LOW_LATENCY_MODE);
- std::vector<hal::ContentType> types;
- getHwComposer().getSupportedContentTypes(*displayId, &types);
- info->gameContentTypeSupported = std::any_of(types.begin(), types.end(), [](auto type) {
- return type == hal::ContentType::GAME;
- });
+ info->gameContentTypeSupported =
+ getHwComposer().supportsContentType(*displayId, hal::ContentType::GAME);
- info->preferredBootDisplayMode = display->getPreferredBootModeId();
+ info->preferredBootDisplayMode = static_cast<ui::DisplayModeId>(-1);
+ if (getHwComposer().getBootDisplayModeSupport()) {
+ if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(*displayId)) {
+ if (const auto modeId = display->translateModeId(*hwcId)) {
+ info->preferredBootDisplayMode = modeId->value();
+ }
+ }
+ }
return NO_ERROR;
}
@@ -1432,31 +1436,41 @@
return future.get();
}
-status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) {
+status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken,
+ ui::DisplayModeId modeId) {
+ const char* const whence = __func__;
auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
- if (const auto displayDevice = getDisplayDeviceLocked(displayToken)) {
- const auto mode = displayDevice->getMode(DisplayModeId{id});
- if (mode == nullptr) {
- ALOGE("%s: invalid display mode (%d)", __FUNCTION__, id);
- return BAD_VALUE;
- }
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
+ ALOGE("%s: Invalid display token %p", whence, displayToken.get());
+ return NAME_NOT_FOUND;
+ }
- return getHwComposer().setBootDisplayMode(displayDevice->getPhysicalId(),
- mode->getHwcId());
- } else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ if (display->isVirtual()) {
+ ALOGE("%s: Invalid operation on virtual display", whence);
+ return INVALID_OPERATION;
+ }
+
+ const auto displayId = display->getPhysicalId();
+ const auto mode = display->getMode(DisplayModeId{modeId});
+ if (!mode) {
+ ALOGE("%s: Invalid mode %d for display %s", whence, modeId,
+ to_string(displayId).c_str());
return BAD_VALUE;
}
+
+ return getHwComposer().setBootDisplayMode(displayId, mode->getHwcId());
});
return future.get();
}
status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
+ const char* const whence = __func__;
auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().clearBootDisplayMode(*displayId);
} else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", whence, displayToken.get());
return BAD_VALUE;
}
});
@@ -1504,7 +1518,7 @@
auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ ALOGE("%s: Invalid display token %p", __func__, displayToken.get());
return NAME_NOT_FOUND;
}
@@ -4805,7 +4819,7 @@
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
if (display->isVirtual()) {
- ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
+ ALOGE("%s: Invalid operation on virtual display", __func__);
return;
}