Add controls for ALLM and Content Types to composer hal
Also extending the passthrough interface with setLowLatencyMode
and setContentType.
Bug:132731049
Test: make -j$(nproc)
Test: vts-tradefed run vts-hal --skip-device-info -m
VtsHalGraphicsComposerV2_4Target
Change-Id: I14dd61a3d9c60fdb06f9028ccd6f49797267e9f4
diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index f23536c..06b4c5e 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -48,6 +48,12 @@
* with protected buffers.
*/
PROTECTED_CONTENTS = 4,
+
+ /**
+ * Indicates that both the composer HAL implementation and the given display
+ * support a low latency mode, such as HDMI 2.1 Auto Low Latency Mode.
+ */
+ AUTO_LOW_LATENCY_MODE = 5,
};
/**
@@ -64,6 +70,18 @@
EXTERNAL = 1,
};
+ enum ContentType : uint32_t {
+ NONE = 0,
+
+ /**
+ * These modes correspond to those found in the HDMI 1.4 specification.
+ */
+ GRAPHICS = 1,
+ PHOTO = 2,
+ CINEMA = 3,
+ GAME = 4,
+ };
+
/**
* Constraints for changing vsync period.
*/
@@ -172,4 +190,60 @@
setActiveConfigWithConstraints(Display display, Config config,
VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints)
generates (Error error, VsyncPeriodChangeTimeline timeline);
+
+ /**
+ * Requests the display to enable/disable its low latency mode.
+ *
+ * If the display is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If
+ * the display is internally connected and a custom low latency mode is available, that should
+ * be triggered.
+ *
+ * This function should only be called if the display reports support for
+ * DisplayCapability::AUTO_LOW_LATENCY_MODE from getDisplayCapabilities_2_4.
+ *
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * UNSUPPORTED when AUTO_LOW_LATENCY_MODE is not supported by the composer
+ * implementation or the given display
+ */
+ setAutoLowLatencyMode(Display display, bool on)
+ generates (Error error);
+
+ /**
+ * Provides a list of all the content types supported by this display (any of
+ * ContentType::{GRAPHICS, PHOTO, CINEMA, GAME}). This list must not change after
+ * initialization.
+ *
+ * Content types are introduced in HDMI 1.4 and supporting them is optional. The
+ * ContentType::NONE is always supported and will not be returned by this method..
+ *
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * @return supportedContentTypes is a list of supported content types.
+ */
+ getSupportedContentTypes(Display display)
+ generates(Error error, vec<ContentType> supportedContentTypes);
+
+ /**
+ * Instructs the connected display that the content being shown is of the given type - one of
+ * GRAPHICS, PHOTO, CINEMA, GAME.
+ *
+ * Content types are introduced in HDMI 1.4 and supporting them is optional. If they are
+ * supported, this signal should switch the display to a mode that is optimal for the given
+ * type of content. See HDMI 1.4 specification for more information.
+ *
+ * If the display is internally connected (not through HDMI), and such modes are available,
+ * this method should trigger them.
+ *
+ * This function should only be called if the display reports support for the corresponding
+ * content type (ContentType::{GRAPHICS, PHOTO, CINEMA, GAME}) from getSupportedContentTypes.
+ * ContentType::NONE is supported by default and can always be set.
+ *
+ * @return error is NONE upon success. Otherwise,
+ * BAD_DISPLAY when an invalid display handle was passed in.
+ * UNSUPPORTED when the given content type is not supported by the composer
+ * implementation or the given display
+ */
+ setContentType(Display display, ContentType type)
+ generates (Error error);
};
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index 4160ed9..dcd959d 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -139,6 +139,24 @@
return Void();
}
+ Return<Error> setAutoLowLatencyMode(Display display, bool on) override {
+ return mHal->setAutoLowLatencyMode(display, on);
+ }
+
+ Return<void> getSupportedContentTypes(
+ Display display, IComposerClient::getSupportedContentTypes_cb hidl_cb) override {
+ std::vector<IComposerClient::ContentType> supportedContentTypes;
+ Error error = mHal->getSupportedContentTypes(display, &supportedContentTypes);
+
+ hidl_cb(error, supportedContentTypes);
+ return Void();
+ }
+
+ Return<Error> setContentType(Display display,
+ IComposerClient::ContentType contentType) override {
+ return mHal->setContentType(display, contentType);
+ }
+
static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
auto client = std::make_unique<ComposerClientImpl>(hal);
return client->init() ? std::move(client) : nullptr;
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index 89dbe66..a1e56ae 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -67,6 +67,11 @@
Display display, Config config,
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
VsyncPeriodChangeTimeline* timeline) = 0;
+ virtual Error setAutoLowLatencyMode(Display display, bool on) = 0;
+ virtual Error getSupportedContentTypes(
+ Display display,
+ std::vector<IComposerClient::ContentType>* outSupportedContentTypes) = 0;
+ virtual Error setContentType(Display display, IComposerClient::ContentType contentType) = 0;
};
} // namespace hal
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index d59d0d5..a27582a 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -167,6 +167,57 @@
return Error::NONE;
}
+ Error setAutoLowLatencyMode(Display display, bool on) override {
+ if (!mDispatch.setAutoLowLatencyMode) {
+ return Error::UNSUPPORTED;
+ }
+
+ int32_t error = mDispatch.setAutoLowLatencyMode(mDevice, display, on);
+ if (error != HWC2_ERROR_NONE) {
+ return static_cast<Error>(error);
+ }
+ return Error::NONE;
+ }
+
+ Error getSupportedContentTypes(
+ Display display,
+ std::vector<IComposerClient::ContentType>* outSupportedContentTypes) override {
+ if (!mDispatch.getSupportedContentTypes) {
+ return Error::UNSUPPORTED;
+ }
+
+ uint32_t count = 0;
+ int32_t error = mDispatch.getSupportedContentTypes(mDevice, display, &count, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ return static_cast<Error>(error);
+ }
+
+ outSupportedContentTypes->resize(count);
+
+ error = mDispatch.getSupportedContentTypes(
+ mDevice, display, &count,
+ reinterpret_cast<std::underlying_type<IComposerClient::ContentType>::type*>(
+ outSupportedContentTypes->data()));
+ if (error != HWC2_ERROR_NONE) {
+ *outSupportedContentTypes = std::vector<IComposerClient::ContentType>();
+ return static_cast<Error>(error);
+ }
+ return Error::NONE;
+ }
+
+ Error setContentType(Display display, IComposerClient::ContentType contentType) override {
+ if (!mDispatch.setContentType) {
+ return Error::UNSUPPORTED;
+ }
+
+ int32_t error =
+ mDispatch.setContentType(mDevice, display, static_cast<int32_t>(contentType));
+ if (error != HWC2_ERROR_NONE) {
+ return static_cast<Error>(error);
+ }
+ return Error::NONE;
+ }
+
protected:
bool initDispatch() override {
if (!BaseType2_3::initDispatch()) {
@@ -179,6 +230,11 @@
&mDispatch.getDisplayVsyncPeriod);
this->initOptionalDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,
&mDispatch.setActiveConfigWithConstraints);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,
+ &mDispatch.setAutoLowLatencyMode);
+ this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,
+ &mDispatch.getSupportedContentTypes);
+ this->initOptionalDispatch(HWC2_FUNCTION_SET_CONTENT_TYPE, &mDispatch.setContentType);
return true;
}
@@ -222,6 +278,9 @@
HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType;
HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod;
HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints;
+ HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE setAutoLowLatencyMode;
+ HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES getSupportedContentTypes;
+ HWC2_PFN_SET_CONTENT_TYPE setContentType;
} mDispatch = {};
hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr;
diff --git a/graphics/composer/2.4/utils/vts/ComposerVts.cpp b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
index 35ac23f..5b06d6d 100644
--- a/graphics/composer/2.4/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.4/utils/vts/ComposerVts.cpp
@@ -106,6 +106,25 @@
return error;
}
+Error ComposerClient::setAutoLowLatencyMode(Display display, bool on) {
+ return mClient->setAutoLowLatencyMode(display, on);
+}
+
+Error ComposerClient::getSupportedContentTypes(
+ Display display, std::vector<IComposerClient::ContentType>* outSupportedContentTypes) {
+ Error error = Error::NONE;
+ mClient->getSupportedContentTypes(
+ display, [&](const auto& tmpError, const auto& tmpSupportedContentTypes) {
+ error = tmpError;
+ *outSupportedContentTypes = tmpSupportedContentTypes;
+ });
+ return error;
+}
+
+Error ComposerClient::setContentType(Display display, IComposerClient::ContentType contentType) {
+ return mClient->setContentType(display, contentType);
+}
+
} // namespace vts
} // namespace V2_4
} // namespace composer
diff --git a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
index 83e74ed..b094bc8 100644
--- a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
+++ b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
@@ -84,6 +84,13 @@
const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
VsyncPeriodChangeTimeline* timeline);
+ Error setAutoLowLatencyMode(Display display, bool on);
+
+ Error getSupportedContentTypes(
+ Display display, std::vector<IComposerClient::ContentType>* outSupportedContentTypes);
+
+ Error setContentType(Display display, IComposerClient::ContentType contentType);
+
private:
const sp<IComposerClient> mClient;
};
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index f038f55..6b6f2a5 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -47,6 +47,9 @@
using mapper::V2_0::IMapper;
using mapper::V2_0::vts::Gralloc;
+using ContentType = IComposerClient::ContentType;
+using DisplayCapability = IComposerClient::DisplayCapability;
+
class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
protected:
void SetUp() override {
@@ -117,6 +120,11 @@
void Test_setActiveConfigWithConstraints(
const IComposerClient::VsyncPeriodChangeConstraints& constraints);
+ void Test_setContentType(const ContentType& contentType, const char* contentTypeStr);
+ void Test_setContentTypeForDisplay(const Display& display,
+ const std::vector<ContentType>& capabilities,
+ const ContentType& contentType, const char* contentTypeStr);
+
std::unique_ptr<Composer> mComposer;
std::unique_ptr<ComposerClient> mComposerClient;
sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
@@ -377,6 +385,117 @@
Test_setActiveConfigWithConstraints(constraints);
}
+TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) {
+ EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true));
+ EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false));
+}
+
+TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
+ for (Display display : mComposerCallback->getDisplays()) {
+ std::vector<DisplayCapability> capabilities;
+ const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities);
+ EXPECT_EQ(Error::NONE, error);
+
+ const bool allmSupport =
+ std::find(capabilities.begin(), capabilities.end(),
+ DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
+
+ if (!allmSupport) {
+ EXPECT_EQ(Error::UNSUPPORTED,
+ mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
+ EXPECT_EQ(Error::UNSUPPORTED,
+ mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
+ GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
+ << to_string(display) << ", skipping test";
+ return;
+ }
+
+ EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
+ EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, getSupportedContentTypesBadDisplay) {
+ std::vector<ContentType> supportedContentTypes;
+ const auto error =
+ mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes);
+ EXPECT_EQ(Error::BAD_DISPLAY, error);
+}
+
+TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
+ std::vector<ContentType> supportedContentTypes;
+ for (Display display : mComposerCallback->getDisplays()) {
+ supportedContentTypes.clear();
+ const auto error =
+ mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
+ const bool noneSupported =
+ std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
+ ContentType::NONE) != supportedContentTypes.end();
+ EXPECT_EQ(Error::NONE, error);
+ EXPECT_FALSE(noneSupported);
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) {
+ for (Display display : mComposerCallback->getDisplays()) {
+ const auto error = mComposerClient->setContentType(display, ContentType::NONE);
+ EXPECT_NE(Error::UNSUPPORTED, error);
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setContentTypeBadDisplay) {
+ const auto types = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
+ ContentType::CINEMA, ContentType::GAME};
+ for (auto type : types) {
+ EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setContentType(mInvalidDisplayId, type));
+ }
+}
+
+void GraphicsComposerHidlTest::Test_setContentTypeForDisplay(
+ const Display& display, const std::vector<ContentType>& capabilities,
+ const ContentType& contentType, const char* contentTypeStr) {
+ const bool contentTypeSupport =
+ std::find(capabilities.begin(), capabilities.end(), contentType) != capabilities.end();
+
+ if (!contentTypeSupport) {
+ EXPECT_EQ(Error::UNSUPPORTED, mComposerClient->setContentType(display, contentType));
+ GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
+ << to_string(display) << ", skipping test";
+ return;
+ }
+
+ EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, contentType));
+ EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, ContentType::NONE));
+}
+
+void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType,
+ const char* contentTypeStr) {
+ for (Display display : mComposerCallback->getDisplays()) {
+ std::vector<ContentType> supportedContentTypes;
+ const auto error =
+ mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
+ EXPECT_EQ(Error::NONE, error);
+
+ Test_setContentTypeForDisplay(display, supportedContentTypes, contentType, contentTypeStr);
+ }
+}
+
+TEST_P(GraphicsComposerHidlTest, setGraphicsContentType) {
+ Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
+}
+
+TEST_P(GraphicsComposerHidlTest, setPhotoContentType) {
+ Test_setContentType(ContentType::PHOTO, "PHOTO");
+}
+
+TEST_P(GraphicsComposerHidlTest, setCinemaContentType) {
+ Test_setContentType(ContentType::CINEMA, "CINEMA");
+}
+
+TEST_P(GraphicsComposerHidlTest, setGameContentType) {
+ Test_setContentType(ContentType::GAME, "GAME");
+}
+
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),