Merge "gralloc: add reserved region"

This commit is contained in:
TreeHugger Robot 2019-12-09 19:44:47 +00:00 committed by Android (Google) Code Review
commit 1eb2bb18eb
4 changed files with 176 additions and 3 deletions

View file

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

View file

@ -310,6 +310,19 @@ Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo&
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 V4_0
} // namespace mapper

View file

@ -90,6 +90,9 @@ class Gralloc {
const IMapper::MetadataType& metadataType,
hidl_vec<uint8_t>* outVec);
Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
uint64_t* outReservedSize);
private:
void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);

View file

@ -16,6 +16,7 @@
#define LOG_TAG "VtsHalGraphicsMapperV4_0TargetTest"
#include <unistd.h>
#include <chrono>
#include <thread>
#include <vector>
@ -82,6 +83,7 @@ class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
mDummyDescriptorInfo.usage =
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
mDummyDescriptorInfo.reservedSize = 0;
}
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 vts
} // namespace V4_0