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

Commit 1eb2bb18 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "gralloc: add reserved region"

parents b524bbb9 d36e1277
Loading
Loading
Loading
Loading
+40 −3
Original line number Original line Diff line number Diff line
@@ -56,6 +56,12 @@ interface IMapper {
         * BufferUsage.
         * BufferUsage.
         */
         */
        bitfield<BufferUsage> usage;
        bitfield<BufferUsage> usage;

        /**
         * The size in bytes of the reserved region associated with the buffer.
         * See getReservedRegion for more information.
         */
        uint64_t reservedSize;
    };
    };


    struct Rect {
    struct Rect {
@@ -71,9 +77,10 @@ interface IMapper {
     *
     *
     * Since the buffer descriptor fully describes a buffer, any device
     * Since the buffer descriptor fully describes a buffer, any device
     * dependent or device independent checks must be performed here whenever
     * dependent or device independent checks must be performed here whenever
     * possible. Specifically, when layered buffers are not supported, this
     * possible. When layered buffers are not supported, this function must
     * function must return `UNSUPPORTED` if `description.layers` is great than
     * return `UNSUPPORTED` if `description.layers` is great than 1. This
     * 1.
     * function may return `UNSUPPORTED` if `description.reservedSize` is
     * larger than a page.
     *
     *
     * @param description Attributes of the descriptor.
     * @param description Attributes of the descriptor.
     * @return error Error status of the call, which may be
     * @return error Error status of the call, which may be
@@ -560,5 +567,35 @@ interface IMapper {
     */
     */
    dumpBuffers()
    dumpBuffers()
            generates (Error error, vec<BufferDump> bufferDumps);
            generates (Error error, vec<BufferDump> bufferDumps);

    /**
     * Returns the region of shared memory associated with the buffer that is
     * reserved for client use.
     *
     * The shared memory may be allocated from any shared memory allocator.
     * The shared memory must be CPU-accessible and virtually contiguous. The
     * starting address must be word-aligned.
     *
     * This function may only be called after importBuffer() has been called by the
     * client. The reserved region must remain accessible until freeBuffer() has
     * been called. After freeBuffer() has been called, the client must not access
     * the reserved region.
     *
     * This reserved memory may be used in future versions of Android to
     * help clients implement backwards compatible features without requiring
     * IAllocator/IMapper updates.
     *
     * @param buffer Imported buffer handle.
     * @return error Error status of the call, which may be
     *     - `NONE` upon success.
     *     - `BAD_BUFFER` if the buffer is invalid.
     * @return reservedRegion CPU-accessible pointer to the reserved region
     * @return reservedSize the size of the reservedRegion that was requested
     *    in the BufferDescriptorInfo.
     */
    getReservedRegion(pointer buffer)
            generates (Error error,
                       pointer reservedRegion,
                       uint64_t reservedSize);
};
};
+13 −0
Original line number Original line Diff line number Diff line
@@ -310,6 +310,19 @@ Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo&
    return err;
    return err;
}
}


Error Gralloc::getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
                                 uint64_t* outReservedSize) {
    Error err;
    mMapper->getReservedRegion(
            const_cast<native_handle_t*>(bufferHandle),
            [&](const auto& tmpError, const auto& tmpReservedRegion, const auto& tmpReservedSize) {
                err = tmpError;
                *outReservedRegion = tmpReservedRegion;
                *outReservedSize = tmpReservedSize;
            });
    return err;
}

}  // namespace vts
}  // namespace vts
}  // namespace V4_0
}  // namespace V4_0
}  // namespace mapper
}  // namespace mapper
+3 −0
Original line number Original line Diff line number Diff line
@@ -90,6 +90,9 @@ class Gralloc {
                                      const IMapper::MetadataType& metadataType,
                                      const IMapper::MetadataType& metadataType,
                                      hidl_vec<uint8_t>* outVec);
                                      hidl_vec<uint8_t>* outVec);


    Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
                            uint64_t* outReservedSize);

  private:
  private:
    void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
    void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);


+120 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#define LOG_TAG "VtsHalGraphicsMapperV4_0TargetTest"
#define LOG_TAG "VtsHalGraphicsMapperV4_0TargetTest"


#include <unistd.h>
#include <chrono>
#include <chrono>
#include <thread>
#include <thread>
#include <vector>
#include <vector>
@@ -82,6 +83,7 @@ class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
        mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
        mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
        mDummyDescriptorInfo.usage =
        mDummyDescriptorInfo.usage =
                static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
                static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
        mDummyDescriptorInfo.reservedSize = 0;
    }
    }


    void TearDown() override {}
    void TearDown() override {}
@@ -1821,6 +1823,124 @@ TEST_F(GraphicsMapperHidlTest, DumpBuffers) {
    }
    }
}
}


/**
 * Test IMapper::getReservedRegion()
 */
TEST_F(GraphicsMapperHidlTest, GetReservedRegion) {
    const native_handle_t* bufferHandle = nullptr;
    auto info = mDummyDescriptorInfo;

    const int pageSize = getpagesize();
    ASSERT_GE(0, pageSize);
    std::vector<uint64_t> requestedReservedSizes{1, 10, 333, static_cast<uint64_t>(pageSize) / 2,
                                                 static_cast<uint64_t>(pageSize)};

    for (auto requestedReservedSize : requestedReservedSizes) {
        info.reservedSize = requestedReservedSize;

        ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));

        void* reservedRegion = nullptr;
        uint64_t reservedSize = 0;
        ASSERT_EQ(Error::NONE,
                  mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
        ASSERT_NE(nullptr, reservedRegion);
        ASSERT_EQ(requestedReservedSize, reservedSize);

        uint8_t testValue = 1;
        memset(reservedRegion, testValue, reservedSize);
        for (uint64_t i = 0; i < reservedSize; i++) {
            ASSERT_EQ(testValue, static_cast<uint8_t*>(reservedRegion)[i]);
        }
    }
}

/**
 * Test IMapper::getReservedRegion() request over a page
 */
TEST_F(GraphicsMapperHidlTest, GetLargeReservedRegion) {
    const native_handle_t* bufferHandle = nullptr;
    auto info = mDummyDescriptorInfo;

    const int pageSize = getpagesize();
    ASSERT_GE(0, pageSize);
    std::vector<uint64_t> requestedReservedSizes{static_cast<uint64_t>(pageSize) * 2,
                                                 static_cast<uint64_t>(pageSize) * 10,
                                                 static_cast<uint64_t>(pageSize) * 1000};

    for (auto requestedReservedSize : requestedReservedSizes) {
        info.reservedSize = requestedReservedSize;

        BufferDescriptor descriptor;
        ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(info));

        Error err;
        mGralloc->getAllocator()->allocate(
                descriptor, 1,
                [&](const auto& tmpError, const auto&, const auto&) { err = tmpError; });
        if (err == Error::UNSUPPORTED) {
            continue;
        }
        ASSERT_EQ(Error::NONE, err);

        void* reservedRegion = nullptr;
        uint64_t reservedSize = 0;
        err = mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize);

        ASSERT_EQ(Error::NONE, err);
        ASSERT_NE(nullptr, reservedRegion);
        ASSERT_EQ(requestedReservedSize, reservedSize);
    }
}

/**
 * Test IMapper::getReservedRegion() across multiple mappers
 */
TEST_F(GraphicsMapperHidlTest, GetReservedRegionMultiple) {
    const native_handle_t* bufferHandle = nullptr;
    auto info = mDummyDescriptorInfo;

    const int pageSize = getpagesize();
    ASSERT_GE(0, pageSize);
    info.reservedSize = pageSize;

    ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));

    void* reservedRegion1 = nullptr;
    uint64_t reservedSize1 = 0;
    ASSERT_EQ(Error::NONE,
              mGralloc->getReservedRegion(bufferHandle, &reservedRegion1, &reservedSize1));
    ASSERT_NE(nullptr, reservedRegion1);
    ASSERT_EQ(info.reservedSize, reservedSize1);

    std::unique_ptr<Gralloc> anotherGralloc;
    ASSERT_NO_FATAL_FAILURE(
            anotherGralloc = std::make_unique<Gralloc>(
                    GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
                    GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));

    void* reservedRegion2 = nullptr;
    uint64_t reservedSize2 = 0;
    ASSERT_EQ(Error::NONE,
              mGralloc->getReservedRegion(bufferHandle, &reservedRegion2, &reservedSize2));
    ASSERT_EQ(reservedRegion1, reservedRegion2);
    ASSERT_EQ(reservedSize1, reservedSize2);
}

/**
 * Test IMapper::getReservedRegion() with a bad buffer
 */
TEST_F(GraphicsMapperHidlTest, GetReservedRegionBadBuffer) {
    const native_handle_t* bufferHandle = nullptr;

    void* reservedRegion = nullptr;
    uint64_t reservedSize = 0;
    ASSERT_EQ(Error::BAD_BUFFER,
              mGralloc->getReservedRegion(bufferHandle, &reservedRegion, &reservedSize));
    ASSERT_EQ(nullptr, reservedRegion);
    ASSERT_EQ(0, reservedSize);
}

}  // namespace
}  // namespace
}  // namespace vts
}  // namespace vts
}  // namespace V4_0
}  // namespace V4_0