[sf] Pass metadata to layer during composition
Adds the simple bits of code to grab a snapshot of the front-end Layer
generic metadata, storing a copy in LayerFECompositionState, and then
sending int to the HWC2::Layer along with other "geometry update"
settings.
As the metadata stored in the layers uses integer keys, they need to be
translated to name strings. For hard-coded mapping is defined, with a
TODO left to remove the hard-coded mapping.
A test is added to ensure that the metadata is written by OutputLayer
when present, and that it is not set as part of a "per-frame" update.
Bug: 139747351
Test: atest libcompositionengine_test
Change-Id: I63f2a34e1fb70e1aefc5aa7e97ce56b7c2579a29
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 963062f..1b5617c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -625,6 +625,8 @@
static constexpr ui::Dataspace kDataspace = static_cast<ui::Dataspace>(71);
static constexpr int kSupportedPerFrameMetadata = 101;
static constexpr int kExpectedHwcSlot = 0;
+ static constexpr bool kLayerGenericMetadata1Mandatory = true;
+ static constexpr bool kLayerGenericMetadata2Mandatory = true;
static const half4 kColor;
static const Rect kDisplayFrame;
@@ -635,6 +637,10 @@
static native_handle_t* kSidebandStreamHandle;
static const sp<GraphicBuffer> kBuffer;
static const sp<Fence> kFence;
+ static const std::string kLayerGenericMetadata1Key;
+ static const std::vector<uint8_t> kLayerGenericMetadata1Value;
+ static const std::string kLayerGenericMetadata2Key;
+ static const std::vector<uint8_t> kLayerGenericMetadata2Value;
OutputLayerWriteStateToHWCTest() {
auto& outputLayerState = mOutputLayer.editState();
@@ -669,6 +675,13 @@
// Some tests may need to simulate unsupported HWC calls
enum class SimulateUnsupported { None, ColorTransform };
+ void includeGenericLayerMetadataInState() {
+ mLayerFEState.metadata[kLayerGenericMetadata1Key] = {kLayerGenericMetadata1Mandatory,
+ kLayerGenericMetadata1Value};
+ mLayerFEState.metadata[kLayerGenericMetadata2Key] = {kLayerGenericMetadata2Mandatory,
+ kLayerGenericMetadata2Value};
+ }
+
void expectGeometryCommonCalls() {
EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
@@ -720,6 +733,18 @@
EXPECT_CALL(*mHwcLayer, setBuffer(kExpectedHwcSlot, kBuffer, kFence));
}
+ void expectGenericLayerMetadataCalls() {
+ // Note: Can be in any order.
+ EXPECT_CALL(*mHwcLayer,
+ setLayerGenericMetadata(kLayerGenericMetadata1Key,
+ kLayerGenericMetadata1Mandatory,
+ kLayerGenericMetadata1Value));
+ EXPECT_CALL(*mHwcLayer,
+ setLayerGenericMetadata(kLayerGenericMetadata2Key,
+ kLayerGenericMetadata2Mandatory,
+ kLayerGenericMetadata2Value));
+ }
+
std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
};
@@ -739,6 +764,13 @@
reinterpret_cast<native_handle_t*>(1031);
const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
+const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
+ "com.example.metadata.1";
+const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Value{{1, 2, 3}};
+const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Key =
+ "com.example.metadata.2";
+const std::vector<uint8_t> OutputLayerWriteStateToHWCTest::kLayerGenericMetadata2Value{
+ {4, 5, 6, 7}};
TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoFECompositionState) {
EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
@@ -862,6 +894,30 @@
mOutputLayer.writeStateToHWC(false);
}
+TEST_F(OutputLayerWriteStateToHWCTest, allStateIncludesMetadataIfPresent) {
+ mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
+ includeGenericLayerMetadataInState();
+
+ expectGeometryCommonCalls();
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls();
+ expectGenericLayerMetadataCalls();
+ expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
+
+ mOutputLayer.writeStateToHWC(true);
+}
+
+TEST_F(OutputLayerWriteStateToHWCTest, perFrameStateDoesNotIncludeMetadataIfPresent) {
+ mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
+ includeGenericLayerMetadataInState();
+
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls();
+ expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
+
+ mOutputLayer.writeStateToHWC(false);
+}
+
/*
* OutputLayer::writeCursorPositionToHWC()
*/