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

Commit f4d374a7 authored by Yichi Chen's avatar Yichi Chen
Browse files

gralloc4-vts: Extract YCbCr888 data operation from Lock_YCRCB_420_SP

The patch extracts the common operation on YCbCr888 data to allow a
better reuse in tests with other YCbCr color formats

Bug: 150461327
Bug: 152510209
Test: VtsHalGraphicsMapperV4_0Target

Change-Id: I530f6d895c338fb041f7705aa9a4fd36931a1588
parent c6394fff
Loading
Loading
Loading
Loading
+50 −49
Original line number Original line Diff line number Diff line
@@ -277,7 +277,7 @@ class GraphicsMapperHidlTest
        }
        }
    }
    }


    void verifyRGBA8888(const native_handle_t* bufferHandle, uint8_t* data, uint32_t height,
    void verifyRGBA8888(const native_handle_t* bufferHandle, const uint8_t* data, uint32_t height,
                        size_t strideInBytes, size_t widthInBytes, uint32_t seed = 0) {
                        size_t strideInBytes, size_t widthInBytes, uint32_t seed = 0) {
        hidl_vec<uint8_t> vec;
        hidl_vec<uint8_t> vec;
        ASSERT_EQ(Error::NONE,
        ASSERT_EQ(Error::NONE,
@@ -295,6 +295,49 @@ class GraphicsMapperHidlTest
        }
        }
    }
    }


    void traverseYCbCr888Data(const android_ycbcr& yCbCr, int32_t width, int32_t height,
                              int64_t hSubsampling, int64_t vSubsampling,
                              std::function<void(uint8_t*, uint8_t)> traverseFuncion) {
        auto yData = static_cast<uint8_t*>(yCbCr.y);
        auto cbData = static_cast<uint8_t*>(yCbCr.cb);
        auto crData = static_cast<uint8_t*>(yCbCr.cr);
        auto yStride = yCbCr.ystride;
        auto cStride = yCbCr.cstride;
        auto chromaStep = yCbCr.chroma_step;

        for (uint32_t y = 0; y < height; y++) {
            for (uint32_t x = 0; x < width; x++) {
                auto val = static_cast<uint8_t>(height * y + x);

                traverseFuncion(yData + yStride * y + x, val);

                if (y % vSubsampling == 0 && x % hSubsampling == 0) {
                    uint32_t subSampleX = x / hSubsampling;
                    uint32_t subSampleY = y / vSubsampling;
                    const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
                    const auto subSampleVal =
                            static_cast<uint8_t>(height * subSampleY + subSampleX);

                    traverseFuncion(cbData + subSampleOffset, subSampleVal);
                    traverseFuncion(crData + subSampleOffset, subSampleVal + 1);
                }
            }
        }
    }

    void fillYCbCr888Data(const android_ycbcr& yCbCr, int32_t width, int32_t height,
                          int64_t hSubsampling, int64_t vSubsampling) {
        traverseYCbCr888Data(yCbCr, width, height, hSubsampling, vSubsampling,
                             [](auto address, auto fillingData) { *address = fillingData; });
    }

    void verifyYCbCr888Data(const android_ycbcr& yCbCr, int32_t width, int32_t height,
                            int64_t hSubsampling, int64_t vSubsampling) {
        traverseYCbCr888Data(
                yCbCr, width, height, hSubsampling, vSubsampling,
                [](auto address, auto expectedData) { EXPECT_EQ(*address, expectedData); });
    }

    bool isEqual(float a, float b) { return abs(a - b) < 0.0001; }
    bool isEqual(float a, float b) { return abs(a - b) < 0.0001; }


    std::unique_ptr<Gralloc> mGralloc;
    std::unique_ptr<Gralloc> mGralloc;
@@ -591,37 +634,16 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
    ASSERT_NO_FATAL_FAILURE(
    ASSERT_NO_FATAL_FAILURE(
            getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
            getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));


    auto yData = static_cast<uint8_t*>(yCbCr.y);
    auto cbData = static_cast<uint8_t*>(yCbCr.cb);
    auto crData = static_cast<uint8_t*>(yCbCr.cr);
    auto yStride = yCbCr.ystride;
    auto cStride = yCbCr.cstride;
    auto chromaStep = yCbCr.chroma_step;

    constexpr uint32_t kCbCrSubSampleFactor = 2;
    constexpr uint32_t kCbCrSubSampleFactor = 2;
    ASSERT_EQ(crData + 1, cbData);
    ASSERT_EQ(2, chromaStep);
    ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
    ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
    ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
    ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);


    for (uint32_t y = 0; y < info.height; y++) {
    auto cbData = static_cast<uint8_t*>(yCbCr.cb);
        for (uint32_t x = 0; x < info.width; x++) {
    auto crData = static_cast<uint8_t*>(yCbCr.cr);
            auto val = static_cast<uint8_t>(info.height * y + x);
    ASSERT_EQ(crData + 1, cbData);
    ASSERT_EQ(2, yCbCr.chroma_step);


            yData[yStride * y + x] = val;
    fillYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);

            if (y % vSubsampling == 0 && x % hSubsampling == 0) {
                uint32_t subSampleX = x / hSubsampling;
                uint32_t subSampleY = y / vSubsampling;
                const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
                const auto subSampleVal =
                        static_cast<uint8_t>(info.height * subSampleY + subSampleX);

                cbData[subSampleOffset] = subSampleVal;
                crData[subSampleOffset] = subSampleVal + 1;
            }
        }
    }


    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));


@@ -632,28 +654,7 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
    ASSERT_NO_FATAL_FAILURE(
    ASSERT_NO_FATAL_FAILURE(
            getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
            getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));


    yData = static_cast<uint8_t*>(yCbCr.y);
    verifyYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
    cbData = static_cast<uint8_t*>(yCbCr.cb);
    crData = static_cast<uint8_t*>(yCbCr.cr);

    for (uint32_t y = 0; y < info.height; y++) {
        for (uint32_t x = 0; x < info.width; x++) {
            auto val = static_cast<uint8_t>(info.height * y + x);

            EXPECT_EQ(val, yData[yStride * y + x]);

            if (y % vSubsampling == 0 && x % hSubsampling == 0) {
                uint32_t subSampleX = x / hSubsampling;
                uint32_t subSampleY = y / vSubsampling;
                const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
                const auto subSampleVal =
                        static_cast<uint8_t>(info.height * subSampleY + subSampleX);

                EXPECT_EQ(subSampleVal, cbData[subSampleOffset]);
                EXPECT_EQ(subSampleVal + 1, crData[subSampleOffset]);
            }
        }
    }


    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
    if (fence >= 0) {
    if (fence >= 0) {