Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e4732c1 authored by John Reck's avatar John Reck
Browse files

Adjust IMapperMetadataTypes.h to match gralloc4 encoding

Specifically include the header encoding. Initially
omitted as it's a bit redundant, the value in having
bit-for-bit identical encoding between gralloc4 &
imapper5 seems worthwhile enough to keep it.

Test: impltests + VtsHalGraphicsMapperStableC
Change-Id: Iee37bb97acf40362c301a06f9118938b1a0c2cd9
parent 749f5af0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -61,6 +61,10 @@ cc_test {
    srcs: [
        "implutils/impltests.cpp",
    ],
    shared_libs: [
        "libgralloctypes",
        "libhidlbase",
    ],
    visibility: [":__subpackages__"],
    cpp_std: "experimental",
}
+290 −70
Original line number Diff line number Diff line
@@ -18,27 +18,61 @@

#include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
#include <android/hardware/graphics/mapper/utils/IMapperProvider.h>
#include <drm/drm_fourcc.h>
#include <gralloctypes/Gralloc4.h>
#include <span>
#include <vector>

using namespace ::android;
using namespace ::android::hardware::graphics::mapper;
using namespace ::aidl::android::hardware::graphics::common;
namespace gralloc4 = ::android::gralloc4;
using ::android::hardware::hidl_vec;

// These tests are primarily interested in hitting all the different *types* that can be
// serialized/deserialized than in exhaustively testing all the StandardMetadataTypes.
// Exhaustive testing of the actual metadata types is relegated for IMapper's VTS suite
// where meaning & correctness of values are more narrowly defined (eg, read-only values)

static constexpr auto HeaderSize = 69;

static std::span<uint8_t> SkipHeader(std::vector<uint8_t>& buffer) {
    return std::span<uint8_t>(buffer).subspan(HeaderSize);
}

static std::vector<PlaneLayout> fakePlaneLayouts() {
    PlaneLayout myPlaneLayout;
    myPlaneLayout.offsetInBytes = 10;
    myPlaneLayout.sampleIncrementInBits = 11;
    myPlaneLayout.strideInBytes = 12;
    myPlaneLayout.widthInSamples = 13;
    myPlaneLayout.heightInSamples = 14;
    myPlaneLayout.totalSizeInBytes = 15;
    myPlaneLayout.horizontalSubsampling = 16;
    myPlaneLayout.verticalSubsampling = 17;

    myPlaneLayout.components.resize(3);
    for (int i = 0; i < myPlaneLayout.components.size(); i++) {
        auto& it = myPlaneLayout.components[i];
        it.type = ExtendableType{"Plane ID", 40 + i};
        it.offsetInBits = 20 + i;
        it.sizeInBits = 30 + i;
    }

    return std::vector<PlaneLayout>{myPlaneLayout, PlaneLayout{}};
}

TEST(Metadata, setGetBufferId) {
    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;

    std::vector<char> buffer;
    buffer.resize(12, 0);
    *reinterpret_cast<int64_t*>(buffer.data()) = 42;
    std::vector<uint8_t> buffer(10000, 0);
    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
    *payload = 42;

    EXPECT_EQ(8, BufferId::encode(18, buffer.data(), 0));
    EXPECT_EQ(42, *reinterpret_cast<int64_t*>(buffer.data()));
    EXPECT_EQ(8, BufferId::encode(18, buffer.data(), buffer.size()));
    EXPECT_EQ(18, *reinterpret_cast<int64_t*>(buffer.data()));
    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), 0));
    EXPECT_EQ(42, *payload);
    EXPECT_EQ(8 + HeaderSize, BufferId::encode(18, buffer.data(), buffer.size()));
    EXPECT_EQ(18, *payload);
    EXPECT_FALSE(BufferId::decode(buffer.data(), 0));
    auto read = BufferId::decode(buffer.data(), buffer.size());
    EXPECT_TRUE(read.has_value());
@@ -48,13 +82,14 @@ TEST(Metadata, setGetBufferId) {
TEST(Metadata, setGetDataspace) {
    using DataspaceValue = StandardMetadata<StandardMetadataType::DATASPACE>::value;
    using intType = std::underlying_type_t<Dataspace>;
    std::vector<char> buffer;
    buffer.resize(12, 0);

    EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
    EXPECT_EQ(0, *reinterpret_cast<intType*>(buffer.data()));
    EXPECT_EQ(4, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
    EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(buffer.data()));
    std::vector<uint8_t> buffer(10000, 0);
    auto data = SkipHeader(buffer);

    EXPECT_EQ(4 + HeaderSize, DataspaceValue::encode(Dataspace::BT2020, buffer.data(), 0));
    EXPECT_EQ(0, *reinterpret_cast<intType*>(data.data()));
    EXPECT_EQ(4 + HeaderSize,
              DataspaceValue::encode(Dataspace::BT2020, buffer.data(), buffer.size()));
    EXPECT_EQ(static_cast<intType>(Dataspace::BT2020), *reinterpret_cast<intType*>(data.data()));
    EXPECT_FALSE(DataspaceValue::decode(buffer.data(), 0));
    auto read = DataspaceValue::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -64,14 +99,12 @@ TEST(Metadata, setGetDataspace) {
TEST(Metadata, setGetValidName) {
    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;

    std::vector<char> buffer;
    buffer.resize(100, 'a');
    buffer[buffer.size() - 1] = '\0';
    std::vector<uint8_t> buffer(10000, 'a');

    // len("Hello") + sizeof(int64)
    constexpr int expectedSize = 5 + sizeof(int64_t);
    constexpr int expectedSize = 5 + sizeof(int64_t) + HeaderSize;
    EXPECT_EQ(expectedSize, NameValue::encode("Hello", buffer.data(), buffer.size()));
    EXPECT_EQ(5, *reinterpret_cast<int64_t*>(buffer.data()));
    EXPECT_EQ(5, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
    // Verify didn't write past the end of the desired size
    EXPECT_EQ('a', buffer[expectedSize]);

@@ -84,18 +117,15 @@ TEST(Metadata, setGetValidName) {
TEST(Metadata, setGetInvalidName) {
    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;

    std::vector<char> buffer;
    buffer.resize(12, 'a');
    std::vector<uint8_t> buffer;
    buffer.resize(12 + HeaderSize, 'a');
    buffer[buffer.size() - 1] = '\0';

    // len("This is a long string") + sizeof(int64)
    constexpr int expectedSize = 21 + sizeof(int64_t);
    constexpr int expectedSize = 21 + sizeof(int64_t) + HeaderSize;
    EXPECT_EQ(expectedSize,
              NameValue::encode("This is a long string", buffer.data(), buffer.size()));
    EXPECT_EQ(21, *reinterpret_cast<int64_t*>(buffer.data()));
    // Verify didn't write the too-long string
    EXPECT_EQ('a', buffer[9]);
    EXPECT_EQ('\0', buffer[buffer.size() - 1]);
    EXPECT_EQ(21, *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));

    auto readValue = NameValue::decode(buffer.data(), buffer.size());
    EXPECT_FALSE(readValue.has_value());
@@ -105,7 +135,7 @@ TEST(Metadata, setGetInvalidName) {

TEST(Metadata, wouldOverflowName) {
    using NameValue = StandardMetadata<StandardMetadataType::NAME>::value;
    std::vector<char> buffer(100, 0);
    std::vector<uint8_t> buffer(10000, 0);

    // int_max + sizeof(int64) overflows int32
    std::string_view bad_string{"badbeef", std::numeric_limits<int32_t>::max()};
@@ -118,15 +148,31 @@ TEST(Metadata, wouldOverflowName) {
              NameValue::encode(bad_string, buffer.data(), buffer.size()));
}

TEST(Metadata, setGetMismatchedWidthHight) {
    // Validates that the header is properly validated on decode
    using WidthValue = StandardMetadata<StandardMetadataType::WIDTH>::value;
    using HeightValue = StandardMetadata<StandardMetadataType::HEIGHT>::value;
    std::vector<uint8_t> buffer(10000, 0);

    EXPECT_EQ(8 + HeaderSize, WidthValue::encode(100, buffer.data(), buffer.size()));
    EXPECT_EQ(100, *reinterpret_cast<uint64_t*>(SkipHeader(buffer).data()));
    auto read = WidthValue::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
    EXPECT_EQ(100, *read);
    read = HeightValue::decode(buffer.data(), buffer.size());
    EXPECT_FALSE(read.has_value());
}

TEST(Metadata, setGetCompression) {
    using CompressionValue = StandardMetadata<StandardMetadataType::COMPRESSION>::value;
    ExtendableType myCompression{"bestest_compression_ever", 42};
    std::vector<char> buffer(100, '\0');
    const int expectedSize = myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t);
    std::vector<uint8_t> buffer(10000, 0);
    const int expectedSize =
            myCompression.name.length() + sizeof(int64_t) + sizeof(int64_t) + HeaderSize;
    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), 0));
    EXPECT_EQ(0, buffer[0]);
    EXPECT_EQ(expectedSize, CompressionValue::encode(myCompression, buffer.data(), buffer.size()));
    EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(buffer.data()));
    EXPECT_EQ(myCompression.name.length(), *reinterpret_cast<int64_t*>(SkipHeader(buffer).data()));
    EXPECT_FALSE(CompressionValue::decode(buffer.data(), 0).has_value());
    auto read = CompressionValue::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -135,41 +181,25 @@ TEST(Metadata, setGetCompression) {

TEST(Metadata, setGetPlaneLayout) {
    using PlaneLayoutValue = StandardMetadata<StandardMetadataType::PLANE_LAYOUTS>::value;
    PlaneLayout myPlaneLayout;
    myPlaneLayout.offsetInBytes = 10;
    myPlaneLayout.sampleIncrementInBits = 11;
    myPlaneLayout.strideInBytes = 12;
    myPlaneLayout.widthInSamples = 13;
    myPlaneLayout.heightInSamples = 14;
    myPlaneLayout.totalSizeInBytes = 15;
    myPlaneLayout.horizontalSubsampling = 16;
    myPlaneLayout.verticalSubsampling = 17;

    myPlaneLayout.components.resize(3);
    for (int i = 0; i < myPlaneLayout.components.size(); i++) {
        auto& it = myPlaneLayout.components[i];
        it.type = ExtendableType{"Plane ID", 40 + i};
        it.offsetInBits = 20 + i;
        it.sizeInBits = 30 + i;
    }

    std::vector<PlaneLayout> layouts{myPlaneLayout, PlaneLayout{}};
    std::vector<PlaneLayout> layouts = fakePlaneLayouts();

    std::vector<char> buffer(5000, '\0');
    std::vector<uint8_t> buffer(10000, 0);
    constexpr int componentSize = 8 + (4 * sizeof(int64_t));
    constexpr int firstLayoutSize = (8 + 1) * sizeof(int64_t) + (3 * componentSize);
    constexpr int secondLayoutSize = (8 + 1) * sizeof(int64_t);
    constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t);
    constexpr int expectedSize = firstLayoutSize + secondLayoutSize + sizeof(int64_t) + HeaderSize;
    EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), 0));
    EXPECT_EQ(0, buffer[0]);
    EXPECT_EQ(expectedSize, PlaneLayoutValue::encode(layouts, buffer.data(), buffer.size()));
    EXPECT_EQ(3, reinterpret_cast<int64_t*>(buffer.data())[1]);
    EXPECT_EQ(8, reinterpret_cast<int64_t*>(buffer.data())[2]);
    EXPECT_EQ(40, reinterpret_cast<int64_t*>(buffer.data())[4]);
    EXPECT_EQ(31, reinterpret_cast<int64_t*>(buffer.data())[11]);
    EXPECT_EQ(22, reinterpret_cast<int64_t*>(buffer.data())[15]);
    EXPECT_EQ(10, reinterpret_cast<int64_t*>(buffer.data())[17]);
    EXPECT_EQ(11, reinterpret_cast<int64_t*>(buffer.data())[18]);
    int64_t* payload = reinterpret_cast<int64_t*>(SkipHeader(buffer).data());
    EXPECT_EQ(3, payload[1]);
    EXPECT_EQ(8, payload[2]);
    EXPECT_EQ(40, payload[4]);
    EXPECT_EQ(31, payload[11]);
    EXPECT_EQ(22, payload[15]);
    EXPECT_EQ(10, payload[17]);
    EXPECT_EQ(11, payload[18]);
    EXPECT_FALSE(PlaneLayoutValue::decode(buffer.data(), 0).has_value());
    auto read = PlaneLayoutValue::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -178,15 +208,15 @@ TEST(Metadata, setGetPlaneLayout) {

TEST(Metadata, setGetRects) {
    using RectsValue = StandardMetadata<StandardMetadataType::CROP>::value;
    std::vector<uint8_t> buffer(500, 0);
    std::vector<uint8_t> buffer(10000, 0);
    std::vector<Rect> cropRects{2};
    cropRects[0] = Rect{10, 11, 12, 13};
    cropRects[1] = Rect{20, 21, 22, 23};

    constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t));
    constexpr int expectedSize = sizeof(int64_t) + (8 * sizeof(int32_t)) + HeaderSize;
    EXPECT_EQ(expectedSize, RectsValue::encode(cropRects, buffer.data(), buffer.size()));
    EXPECT_EQ(2, reinterpret_cast<int64_t*>(buffer.data())[0]);
    EXPECT_EQ(10, reinterpret_cast<int32_t*>(buffer.data())[2]);
    EXPECT_EQ(2, reinterpret_cast<int64_t*>(SkipHeader(buffer).data())[0]);
    EXPECT_EQ(10, reinterpret_cast<int32_t*>(SkipHeader(buffer).data())[2]);
    auto read = RectsValue::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
    EXPECT_EQ(cropRects.size(), read->size());
@@ -203,8 +233,8 @@ TEST(Metadata, setGetSmpte2086) {
    source.primaryGreen = XyColor{.3f, .4f};
    source.primaryBlue = XyColor{.5f, .6f};

    constexpr int expectedSize = 10 * sizeof(float);
    std::vector<uint8_t> buffer(500, 0);
    constexpr int expectedSize = 10 * sizeof(float) + HeaderSize;
    std::vector<uint8_t> buffer(10000, 0);
    EXPECT_EQ(expectedSize, Smpte2086Value::encode(source, buffer.data(), buffer.size()));
    auto read = Smpte2086Value::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -223,8 +253,8 @@ TEST(Metadata, setGetCta861_3) {
    source.maxFrameAverageLightLevel = 244.55f;
    source.maxContentLightLevel = 202.202f;

    constexpr int expectedSize = 2 * sizeof(float);
    std::vector<uint8_t> buffer(500, 0);
    constexpr int expectedSize = 2 * sizeof(float) + HeaderSize;
    std::vector<uint8_t> buffer(10000, 0);
    EXPECT_EQ(expectedSize, Cta861_3Value::encode(source, buffer.data(), buffer.size()));
    auto read = Cta861_3Value::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -240,14 +270,14 @@ TEST(Metadata, setGetCta861_3) {
TEST(Metadata, setGetSmpte2094_10) {
    using SMPTE2094_10Value = StandardMetadata<StandardMetadataType::SMPTE2094_10>::value;

    std::vector<uint8_t> buffer(500, 0);
    std::vector<uint8_t> buffer(10000, 0);
    EXPECT_EQ(0, SMPTE2094_10Value::encode(std::nullopt, buffer.data(), buffer.size()));
    auto read = SMPTE2094_10Value::decode(buffer.data(), 0);
    ASSERT_TRUE(read.has_value());
    EXPECT_FALSE(read->has_value());

    const std::vector<uint8_t> emptyBuffer;
    EXPECT_EQ(sizeof(int64_t),
    EXPECT_EQ(sizeof(int64_t) + HeaderSize,
              SMPTE2094_10Value::encode(emptyBuffer, buffer.data(), buffer.size()));
    read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -255,7 +285,7 @@ TEST(Metadata, setGetSmpte2094_10) {
    EXPECT_EQ(0, read->value().size());

    const std::vector<uint8_t> simpleBuffer{0, 1, 2, 3, 4, 5};
    EXPECT_EQ(sizeof(int64_t) + 6,
    EXPECT_EQ(sizeof(int64_t) + 6 + HeaderSize,
              SMPTE2094_10Value::encode(simpleBuffer, buffer.data(), buffer.size()));
    read = SMPTE2094_10Value::decode(buffer.data(), buffer.size());
    ASSERT_TRUE(read.has_value());
@@ -266,7 +296,7 @@ TEST(Metadata, setGetSmpte2094_10) {

TEST(MetadataProvider, bufferId) {
    using BufferId = StandardMetadata<StandardMetadataType::BUFFER_ID>::value;
    std::vector<uint8_t> buffer(500, 0);
    std::vector<uint8_t> buffer(10000, 0);
    int result = provideStandardMetadata(StandardMetadataType::BUFFER_ID, buffer.data(),
                                         buffer.size(), []<StandardMetadataType T>(auto&& provide) {
                                             if constexpr (T == StandardMetadataType::BUFFER_ID) {
@@ -275,7 +305,7 @@ TEST(MetadataProvider, bufferId) {
                                             return 0;
                                         });

    EXPECT_EQ(8, result);
    EXPECT_EQ(8 + HeaderSize, result);
    auto read = BufferId::decode(buffer.data(), buffer.size());
    EXPECT_EQ(42, read.value_or(0));
}
@@ -312,3 +342,193 @@ TEST(MetadataProvider, outOfBounds) {
    EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, result)
            << "100 (out of range) should have resulted in UNSUPPORTED";
}

template <StandardMetadataType T>
std::vector<uint8_t> encode(const typename StandardMetadata<T>::value_type& value) {
    using Value = typename StandardMetadata<T>::value;

    int desiredSize = Value::encode(value, nullptr, 0);
    EXPECT_GE(desiredSize, 0);
    std::vector<uint8_t> buffer;
    buffer.resize(desiredSize);
    EXPECT_EQ(desiredSize, Value::encode(value, buffer.data(), buffer.size()));
    return buffer;
}

TEST(MetadataGralloc4Interop, BufferId) {
    auto mpbuf = encode<StandardMetadataType::BUFFER_ID>(42);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeBufferId(42, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Name) {
    auto mpbuf = encode<StandardMetadataType::NAME>("Hello, Interop!");
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeName("Hello, Interop!", &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Width) {
    auto mpbuf = encode<StandardMetadataType::WIDTH>(128);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeWidth(128, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Height) {
    auto mpbuf = encode<StandardMetadataType::HEIGHT>(64);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeHeight(64, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, LayerCount) {
    auto mpbuf = encode<StandardMetadataType::LAYER_COUNT>(3);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeLayerCount(3, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, PixelFormatRequested) {
    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(PixelFormat::RGBX_8888);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatRequested(
                                hardware::graphics::common::V1_2::PixelFormat::RGBX_8888, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, PixelFormatFourcc) {
    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_FOURCC>(DRM_FORMAT_ABGR8888);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(DRM_FORMAT_ABGR8888, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, PixelFormatModifier) {
    auto mpbuf = encode<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(123456);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(123456, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Usage) {
    auto mpbuf = encode<StandardMetadataType::USAGE>(BufferUsage::COMPOSER_OVERLAY);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR,
              gralloc4::encodeUsage(
                      static_cast<uint64_t>(
                              hardware::graphics::common::V1_2::BufferUsage::COMPOSER_OVERLAY),
                      &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, AllocationSize) {
    auto mpbuf = encode<StandardMetadataType::ALLOCATION_SIZE>(10200);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(10200, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, ProtectedContent) {
    auto mpbuf = encode<StandardMetadataType::PROTECTED_CONTENT>(1);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeProtectedContent(1, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Compression) {
    auto mpbuf = encode<StandardMetadataType::COMPRESSION>(
            gralloc4::Compression_DisplayStreamCompression);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR,
              gralloc4::encodeCompression(gralloc4::Compression_DisplayStreamCompression, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Interlaced) {
    auto mpbuf = encode<StandardMetadataType::INTERLACED>(gralloc4::Interlaced_TopBottom);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(gralloc4::Interlaced_TopBottom, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, ChromeSitting) {
    auto mpbuf =
            encode<StandardMetadataType::CHROMA_SITING>(gralloc4::ChromaSiting_SitedInterstitial);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR,
              gralloc4::encodeChromaSiting(gralloc4::ChromaSiting_SitedInterstitial, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, PlaneLayouts) {
    auto mpbuf = encode<StandardMetadataType::PLANE_LAYOUTS>(fakePlaneLayouts());
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodePlaneLayouts(fakePlaneLayouts(), &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Crop) {
    std::vector<Rect> cropRects{Rect{10, 11, 12, 13}, Rect{20, 21, 22, 23}};
    auto mpbuf = encode<StandardMetadataType::CROP>(cropRects);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeCrop(cropRects, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Dataspace) {
    auto mpbuf = encode<StandardMetadataType::DATASPACE>(Dataspace::DISPLAY_P3);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(Dataspace::DISPLAY_P3, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, BlendMode) {
    auto mpbuf = encode<StandardMetadataType::BLEND_MODE>(BlendMode::PREMULTIPLIED);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(BlendMode::PREMULTIPLIED, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Smpte2086) {
    Smpte2086 hdrdata{XyColor{.1f, .2f}, XyColor{.3f, .4f}, XyColor{.5f, .6f},
                      XyColor{.7f, .8f}, 452.889f,          12.335f};

    auto mpbuf = encode<StandardMetadataType::SMPTE2086>(hdrdata);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(hdrdata, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Cta861_3) {
    Cta861_3 hdrdata{302.202f, 244.55f};
    auto mpbuf = encode<StandardMetadataType::CTA861_3>(hdrdata);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(hdrdata, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Smpte2094_10) {
    auto mpbuf = encode<StandardMetadataType::SMPTE2094_10>(std::nullopt);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(std::nullopt, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);

    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
    mpbuf = encode<StandardMetadataType::SMPTE2094_10>(hdrdata);
    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_10(hdrdata, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}

TEST(MetadataGralloc4Interop, Smpte2094_40) {
    auto mpbuf = encode<StandardMetadataType::SMPTE2094_40>(std::nullopt);
    hidl_vec<uint8_t> g4buf;
    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(std::nullopt, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);

    std::vector<uint8_t> hdrdata{1, 2, 3, 4, 5, 6};
    mpbuf = encode<StandardMetadataType::SMPTE2094_40>(hdrdata);
    ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2094_40(hdrdata, &g4buf));
    EXPECT_EQ(mpbuf, g4buf);
}