SF: Initialize DisplayDevice with the active config index
This is a port of aosp/580542, with added unit test changes now that the
correct config is being set in the DisplayDevice.
Bug: 69807179
Test: atest libsurfaceflinger_unittest
Change-Id: I51c13678bc28c715fa116ad127478d4afa3d0349
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 3947318..61758b6 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -30,8 +30,9 @@
#include <android/configuration.h>
-#include <algorithm>
#include <inttypes.h>
+#include <algorithm>
+#include <iterator>
#include <set>
using android::Fence;
@@ -338,6 +339,31 @@
return Error::None;
}
+Error Display::getActiveConfigIndex(int* outIndex) const {
+ ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId);
+ hwc2_config_t configId = 0;
+ auto intError = mComposer.getActiveConfig(mId, &configId);
+ auto error = static_cast<Error>(intError);
+
+ if (error != Error::None) {
+ ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
+ *outIndex = -1;
+ return error;
+ }
+
+ auto pos = mConfigs.find(configId);
+ if (pos != mConfigs.end()) {
+ *outIndex = std::distance(mConfigs.begin(), pos);
+ } else {
+ ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId);
+ // Return no error, but the caller needs to check for a negative index
+ // to detect this case
+ *outIndex = -1;
+ }
+
+ return Error::None;
+}
+
Error Display::getChangedCompositionTypes(
std::unordered_map<Layer*, Composition>* outTypes)
{
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 3ac06ec..29d7a47 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -36,7 +36,6 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
-#include <map>
namespace android {
class Fence;
@@ -207,6 +206,7 @@
[[clang::warn_unused_result]] Error destroyLayer(Layer* layer);
[[clang::warn_unused_result]] Error getActiveConfig(
std::shared_ptr<const Config>* outConfig) const;
+ [[clang::warn_unused_result]] Error getActiveConfigIndex(int* outIndex) const;
[[clang::warn_unused_result]] Error getChangedCompositionTypes(
std::unordered_map<Layer*, Composition>* outTypes);
[[clang::warn_unused_result]] Error getColorModes(
@@ -288,9 +288,7 @@
bool mIsConnected;
DisplayType mType;
std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
- // The ordering in this map matters, for getConfigs(), when it is
- // converted to a vector
- std::map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
+ std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
};
// Convenience C++ class to access hwc2_device_t Layer functions directly.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 96d691c..f5f7a82 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -318,6 +318,28 @@
return config;
}
+int HWComposer::getActiveConfigIndex(int32_t displayId) const {
+ if (!isValidDisplay(displayId)) {
+ ALOGV("getActiveConfigIndex: Attempted to access invalid display %d", displayId);
+ return -1;
+ }
+ int index;
+ auto error = mDisplayData[displayId].hwcDisplay->getActiveConfigIndex(&index);
+ if (error == HWC2::Error::BadConfig) {
+ ALOGE("getActiveConfigIndex: No config active, returning -1");
+ return -1;
+ } else if (error != HWC2::Error::None) {
+ ALOGE("getActiveConfigIndex failed for display %d: %s (%d)", displayId,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ return -1;
+ } else if (index < 0) {
+ ALOGE("getActiveConfigIndex returned an unknown config for display %d", displayId);
+ return -1;
+ }
+
+ return index;
+}
+
std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index d7f3b08..f968948 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -164,6 +164,7 @@
std::shared_ptr<const HWC2::Display::Config>
getActiveConfig(int32_t displayId) const;
+ int getActiveConfigIndex(int32_t displayId) const;
std::vector<ui::ColorMode> getColorModes(int32_t displayId) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b35b58c..9117207 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2414,6 +2414,9 @@
}
setActiveColorModeInternal(hw, defaultColorMode, defaultDataSpace,
RenderIntent::COLORIMETRIC);
+ if (state.type < DisplayDevice::DISPLAY_VIRTUAL) {
+ hw->setActiveConfig(getHwComposer().getActiveConfigIndex(state.type));
+ }
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation, state.viewport, state.frame);
hw->setDisplayName(state.displayName);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index d1bbb5b..cd69128 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -306,11 +306,7 @@
static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
// The HWC active configuration id
- // TODO(b/69807179): SurfaceFlinger does not correctly get the active
- // config. Once it does, change this to non-zero so that it is properly
- // covered.
- // static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
- static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
+ static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
static void injectPendingHotplugEvent(DisplayTransactionTest* test,
HWC2::Connection connection) {
@@ -362,13 +358,11 @@
// Called by tests to set up HWC call expectations
static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
+ .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
}
};
struct NonHwcDisplayVariant {
- static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
-
static void injectHwcDisplay(DisplayTransactionTest*) {}
static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
@@ -1033,10 +1027,7 @@
// Various native window calls will be made.
Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
-
- // TODO(b/69807179): SurfaceFlinger does not correctly get the active config.
- // Case::Display::setupHwcGetActiveConfigCallExpectations(this)
-
+ Case::Display::setupHwcGetActiveConfigCallExpectations(this);
Case::WideColorSupport::setupComposerCallExpectations(this);
Case::HdrSupport::setupComposerCallExpectations(this);
Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
@@ -1060,7 +1051,10 @@
EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
- EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveConfig());
+ // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
+ // remapped, and the test only ever sets up one config. If there were an error
+ // looking up the remapped index, device->getActiveConfig() would be -1 instead.
+ EXPECT_EQ(0, device->getActiveConfig());
EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
device->getSupportedPerFrameMetadata());
}