Loading graphics/mapper/4.0/IMapper.hal +40 −3 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading @@ -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 Loading Loading @@ -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); }; }; graphics/mapper/4.0/utils/vts/MapperVts.cpp +13 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -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); Loading graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp +120 −0 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 {} Loading Loading @@ -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 Loading Loading
graphics/mapper/4.0/IMapper.hal +40 −3 Original line number Original line Diff line number Diff line Loading @@ -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 { Loading @@ -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 Loading Loading @@ -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); }; };
graphics/mapper/4.0/utils/vts/MapperVts.cpp +13 −0 Original line number Original line Diff line number Diff line Loading @@ -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 Loading
graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -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); Loading
graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp +120 −0 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 {} Loading Loading @@ -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 Loading