SF: Remove display config functions from HWC2

HWC2 is unnecessary stateful stopgap between HWComposer and
ComposerHal. In this CL the following functions are removed from HWC2
  * getActiveConfig
  * getActiveConfigIndex
  * getDisplayVsyncPeriod

and ComposerHal is called directly from HWComposer. This way display
configs are stored only in HWComposer.

Additionally HWC2::Display::Config is renamed to DisplayMode and
it's extracted in its own file.

From the perspective of SurfaceFlinger this CL is not modifying
behaviour.

Bug: 159590486
Bug: 175678215
Test: atest libsurfaceflinger_unittest
Change-Id: I8cb450209adf038d891cff00d1c2690c8e6d94f7
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6f3987f..ca67935 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -281,6 +281,8 @@
 
 void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId,
                                          PhysicalDisplayId displayId) {
+    mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
+
     if (!mInternalHwcDisplayId) {
         mInternalHwcDisplayId = hwcDisplayId;
     } else if (mInternalHwcDisplayId != hwcDisplayId && !mExternalHwcDisplayId) {
@@ -293,8 +295,41 @@
                                                   hal::DisplayType::PHYSICAL);
     newDisplay->setConnected(true);
     displayData.hwcDisplay = std::move(newDisplay);
-    displayData.configs = displayData.hwcDisplay->getConfigs();
-    mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
+    loadModes(displayData, hwcDisplayId);
+}
+
+int32_t HWComposer::getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId,
+                                 hal::Attribute attribute) {
+    int32_t value = 0;
+    auto error = static_cast<hal::Error>(
+            mComposer->getDisplayAttribute(hwcDisplayId, configId, attribute, &value));
+
+    RETURN_IF_HWC_ERROR_FOR("getDisplayAttribute", error, *toPhysicalDisplayId(hwcDisplayId), -1);
+    return value;
+}
+
+void HWComposer::loadModes(DisplayData& displayData, hal::HWDisplayId hwcDisplayId) {
+    ALOGV("[HWC display %" PRIu64 "] %s", hwcDisplayId, __FUNCTION__);
+
+    std::vector<hal::HWConfigId> configIds;
+    auto error = static_cast<hal::Error>(mComposer->getDisplayConfigs(hwcDisplayId, &configIds));
+    RETURN_IF_HWC_ERROR_FOR("getDisplayConfigs", error, *toPhysicalDisplayId(hwcDisplayId));
+
+    displayData.modes.clear();
+    for (auto configId : configIds) {
+        auto mode = DisplayMode::Builder(configId)
+                            .setId(HwcConfigIndexType(displayData.modes.size()))
+                            .setWidth(getAttribute(hwcDisplayId, configId, hal::Attribute::WIDTH))
+                            .setHeight(getAttribute(hwcDisplayId, configId, hal::Attribute::HEIGHT))
+                            .setVsyncPeriod(getAttribute(hwcDisplayId, configId,
+                                                         hal::Attribute::VSYNC_PERIOD))
+                            .setDpiX(getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_X))
+                            .setDpiY(getAttribute(hwcDisplayId, configId, hal::Attribute::DPI_Y))
+                            .setConfigGroup(getAttribute(hwcDisplayId, configId,
+                                                         hal::Attribute::CONFIG_GROUP))
+                            .build();
+        displayData.modes.push_back(std::move(mode));
+    }
 }
 
 HWC2::Layer* HWComposer::createLayer(HalDisplayId displayId) {
@@ -330,34 +365,38 @@
     return mDisplayData.at(displayId).hwcDisplay->isConnected();
 }
 
-std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
-        PhysicalDisplayId displayId) const {
+DisplayModes HWComposer::getModes(PhysicalDisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, {});
 
-    // We cache the configs when the DisplayData is created on hotplug. If the configs need to
+    // We cache the modes when the DisplayData is created on hotplug. If the modes need to
     // change HWC will send a hotplug event which will recreate displayData.
-    return mDisplayData.at(displayId).configs;
+    return mDisplayData.at(displayId).modes;
 }
 
-std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
-        PhysicalDisplayId displayId) const {
+DisplayModePtr HWComposer::getActiveMode(PhysicalDisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
 
-    std::shared_ptr<const HWC2::Display::Config> config;
-    auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfig(&config);
+    const auto hwcId = *fromPhysicalDisplayId(displayId);
+    ALOGV("[%" PRIu64 "] getActiveMode", hwcId);
+    hal::HWConfigId configId;
+    auto error = static_cast<hal::Error>(mComposer->getActiveConfig(hwcId, &configId));
+
+    const auto& modes = mDisplayData.at(displayId).modes;
     if (error == hal::Error::BAD_CONFIG) {
-        LOG_DISPLAY_ERROR(displayId, "No active config");
+        LOG_DISPLAY_ERROR(displayId, "No active mode");
         return nullptr;
     }
 
     RETURN_IF_HWC_ERROR(error, displayId, nullptr);
 
-    if (!config) {
-        LOG_DISPLAY_ERROR(displayId, "Unknown config");
+    const auto it = std::find_if(modes.begin(), modes.end(),
+                                 [configId](auto mode) { return mode->getHwcId() == configId; });
+    if (it == modes.end()) {
+        LOG_DISPLAY_ERROR(displayId, "Unknown mode");
         return nullptr;
     }
 
-    return config;
+    return *it;
 }
 
 // Composer 2.4
@@ -385,30 +424,24 @@
 nsecs_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, 0);
 
-    nsecs_t vsyncPeriodNanos;
-    auto error = mDisplayData.at(displayId).hwcDisplay->getDisplayVsyncPeriod(&vsyncPeriodNanos);
-    RETURN_IF_HWC_ERROR(error, displayId, 0);
-    return vsyncPeriodNanos;
-}
-
-int HWComposer::getActiveConfigIndex(PhysicalDisplayId displayId) const {
-    RETURN_IF_INVALID_DISPLAY(displayId, -1);
-
-    int index;
-    auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfigIndex(&index);
-    if (error == hal::Error::BAD_CONFIG) {
-        LOG_DISPLAY_ERROR(displayId, "No active config");
-        return -1;
+    if (isVsyncPeriodSwitchSupported(displayId)) {
+        const auto hwcId = *fromPhysicalDisplayId(displayId);
+        Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
+        auto error =
+                static_cast<hal::Error>(mComposer->getDisplayVsyncPeriod(hwcId, &vsyncPeriodNanos));
+        RETURN_IF_HWC_ERROR(error, displayId, 0);
+        return static_cast<nsecs_t>(vsyncPeriodNanos);
     }
 
-    RETURN_IF_HWC_ERROR(error, displayId, -1);
+    // Get the default vsync period
+    auto mode = getActiveMode(displayId);
 
-    if (index < 0) {
-        LOG_DISPLAY_ERROR(displayId, "Unknown config");
-        return -1;
+    if (!mode) {
+        // HWC has updated the display modes and hasn't notified us yet.
+        RETURN_IF_HWC_ERROR(hal::Error::BAD_CONFIG, displayId, 0);
     }
 
-    return index;
+    return mode->getVsyncPeriod();
 }
 
 std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
@@ -640,21 +673,21 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setActiveConfigWithConstraints(
-        PhysicalDisplayId displayId, size_t configId,
+status_t HWComposer::setActiveModeWithConstraints(
+        PhysicalDisplayId displayId, HwcConfigIndexType modeId,
         const hal::VsyncPeriodChangeConstraints& constraints,
         hal::VsyncPeriodChangeTimeline* outTimeline) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
     auto& displayData = mDisplayData[displayId];
-    if (configId >= displayData.configs.size()) {
-        LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str());
+    if (modeId.value() >= displayData.modes.size()) {
+        LOG_DISPLAY_ERROR(displayId, ("Invalid mode " + std::to_string(modeId.value())).c_str());
         return BAD_INDEX;
     }
 
-    auto error =
-            displayData.hwcDisplay->setActiveConfigWithConstraints(displayData.configs[configId],
-                                                                   constraints, outTimeline);
+    const auto hwcConfigId = displayData.modes[modeId.value()]->getHwcId();
+    auto error = displayData.hwcDisplay->setActiveConfigWithConstraints(hwcConfigId, constraints,
+                                                                        outTimeline);
     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
     return NO_ERROR;
 }