mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:23:37 +00:00
Merge changes I926887cc,I7def937e,I530f6d89,I393fc3c4 into rvc-dev am: ad17ebe23b am: 3a214d1126
Change-Id: Ide84bbba1ce7c75633378c778e45f6fbba49e224
This commit is contained in:
@@ -71,7 +71,8 @@ sp<IAllocator> Gralloc::getAllocator() const {
|
||||
return mAllocator;
|
||||
}
|
||||
|
||||
const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
|
||||
const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle,
|
||||
enum Tolerance /*tolerance*/) {
|
||||
const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
|
||||
EXPECT_NE(nullptr, bufferHandle);
|
||||
|
||||
@@ -84,42 +85,37 @@ const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
|
||||
|
||||
std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
|
||||
uint32_t count, bool import,
|
||||
bool allowFailure, uint32_t* outStride) {
|
||||
enum Tolerance tolerance,
|
||||
uint32_t* outStride) {
|
||||
std::vector<const native_handle_t*> bufferHandles;
|
||||
bufferHandles.reserve(count);
|
||||
mAllocator->allocate(
|
||||
descriptor, count,
|
||||
[&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
|
||||
if (allowFailure && tmpError == Error::UNSUPPORTED) {
|
||||
return;
|
||||
}
|
||||
ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
|
||||
ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
|
||||
mAllocator->allocate(descriptor, count,
|
||||
[&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
|
||||
if (canTolerate(tolerance, tmpError)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
if (import) {
|
||||
if (allowFailure) {
|
||||
bufferHandle = importBuffer(tmpBuffers[i]);
|
||||
} else {
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(tmpBuffers[i]));
|
||||
}
|
||||
} else {
|
||||
if (allowFailure) {
|
||||
bufferHandle = cloneBuffer(tmpBuffers[i]);
|
||||
} else {
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(tmpBuffers[i]));
|
||||
}
|
||||
}
|
||||
if (bufferHandle) {
|
||||
bufferHandles.push_back(bufferHandle);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
|
||||
ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
|
||||
|
||||
if (outStride) {
|
||||
*outStride = tmpStride;
|
||||
}
|
||||
});
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
if (import) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = importBuffer(tmpBuffers[i], tolerance));
|
||||
} else {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = cloneBuffer(tmpBuffers[i], tolerance));
|
||||
}
|
||||
if (bufferHandle) {
|
||||
bufferHandles.push_back(bufferHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (outStride) {
|
||||
*outStride = tmpStride;
|
||||
}
|
||||
});
|
||||
|
||||
if (::testing::Test::HasFatalFailure()) {
|
||||
bufferHandles.clear();
|
||||
@@ -129,13 +125,14 @@ std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& de
|
||||
}
|
||||
|
||||
const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import, bool allowFailure, uint32_t* outStride) {
|
||||
bool import, enum Tolerance tolerance,
|
||||
uint32_t* outStride) {
|
||||
BufferDescriptor descriptor = createDescriptor(descriptorInfo);
|
||||
if (::testing::Test::HasFatalFailure()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto buffers = allocate(descriptor, 1, import, allowFailure, outStride);
|
||||
auto buffers = allocate(descriptor, 1, import, tolerance, outStride);
|
||||
if (::testing::Test::HasFatalFailure()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -160,11 +157,14 @@ BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo&
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
|
||||
const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle,
|
||||
enum Tolerance tolerance) {
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
|
||||
ASSERT_EQ(Error::NONE, tmpError)
|
||||
<< "failed to import buffer %p" << rawHandle.getNativeHandle();
|
||||
if (!canTolerate(tolerance, tmpError)) {
|
||||
ASSERT_EQ(Error::NONE, tmpError)
|
||||
<< "failed to import buffer %p" << rawHandle.getNativeHandle();
|
||||
}
|
||||
bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
|
||||
});
|
||||
|
||||
|
||||
@@ -37,6 +37,16 @@ using android::hardware::graphics::allocator::V4_0::IAllocator;
|
||||
// A wrapper to IAllocator and IMapper.
|
||||
class Gralloc {
|
||||
public:
|
||||
enum class Tolerance : uint32_t {
|
||||
kToleranceStrict = 0x0U,
|
||||
kToleranceBadDescriptor = 0x1U << std::underlying_type_t<Error>(Error::BAD_DESCRIPTOR),
|
||||
kToleranceBadBuffer = 0x1U << std::underlying_type_t<Error>(Error::BAD_BUFFER),
|
||||
kToleranceBadValue = 0x1U << std::underlying_type_t<Error>(Error::BAD_VALUE),
|
||||
kToleranceNoResource = 0x1U << std::underlying_type_t<Error>(Error::NO_RESOURCES),
|
||||
kToleranceUnSupported = 0x1U << std::underlying_type_t<Error>(Error::UNSUPPORTED),
|
||||
kToleranceAllErrors = ~0x0U,
|
||||
};
|
||||
|
||||
Gralloc(const std::string& allocatorServiceName = "default",
|
||||
const std::string& mapperServiceName = "default", bool errOnFailure = true);
|
||||
~Gralloc();
|
||||
@@ -49,12 +59,27 @@ class Gralloc {
|
||||
// is true, the returned buffers are also imported into the mapper.
|
||||
//
|
||||
// Either case, the returned buffers must be freed with freeBuffer.
|
||||
std::vector<const native_handle_t*> allocate(const BufferDescriptor& descriptor, uint32_t count,
|
||||
bool import = true, bool allowFailure = false,
|
||||
uint32_t* outStride = nullptr);
|
||||
std::vector<const native_handle_t*> allocate(
|
||||
const BufferDescriptor& descriptor, uint32_t count, bool import = true,
|
||||
enum Tolerance tolerance = Tolerance::kToleranceStrict, uint32_t* outStride = nullptr);
|
||||
|
||||
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import = true, bool allowFailure = false,
|
||||
uint32_t* outStride = nullptr);
|
||||
bool import, enum Tolerance tolerance, uint32_t* outStride);
|
||||
|
||||
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import) {
|
||||
return allocate(descriptorInfo, import, Tolerance::kToleranceStrict);
|
||||
}
|
||||
|
||||
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import, enum Tolerance tolerance) {
|
||||
return allocate(descriptorInfo, import, tolerance, nullptr);
|
||||
}
|
||||
|
||||
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
|
||||
bool import, uint32_t* outStride) {
|
||||
return allocate(descriptorInfo, import, Tolerance::kToleranceStrict, outStride);
|
||||
}
|
||||
|
||||
// IMapper methods
|
||||
|
||||
@@ -62,7 +87,11 @@ class Gralloc {
|
||||
|
||||
BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo);
|
||||
|
||||
const native_handle_t* importBuffer(const hidl_handle& rawHandle);
|
||||
const native_handle_t* importBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance);
|
||||
const native_handle_t* importBuffer(const hidl_handle& rawHandle) {
|
||||
return importBuffer(rawHandle, Tolerance::kToleranceStrict);
|
||||
}
|
||||
|
||||
void freeBuffer(const native_handle_t* bufferHandle);
|
||||
|
||||
// We use fd instead of hidl_handle in these functions to pass fences
|
||||
@@ -96,11 +125,19 @@ class Gralloc {
|
||||
uint64_t* outReservedSize);
|
||||
|
||||
private:
|
||||
bool canTolerate(Tolerance tolerance, Error error) {
|
||||
return (std::underlying_type_t<Tolerance>(tolerance) &
|
||||
0x1U << std::underlying_type_t<Error>(error)) != 0;
|
||||
}
|
||||
|
||||
void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
|
||||
|
||||
// initialize without checking for failure to get service
|
||||
void initNoErr(const std::string& allocatorServiceName, const std::string& mapperServiceName);
|
||||
const native_handle_t* cloneBuffer(const hidl_handle& rawHandle);
|
||||
const native_handle_t* cloneBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance);
|
||||
const native_handle_t* cloneBuffer(const hidl_handle& rawHandle) {
|
||||
return cloneBuffer(rawHandle, Tolerance::kToleranceStrict);
|
||||
}
|
||||
|
||||
sp<IAllocator> mAllocator;
|
||||
sp<IMapper> mMapper;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <android/sync.h>
|
||||
#include <gralloctypes/Gralloc4.h>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -40,8 +41,10 @@ namespace V4_0 {
|
||||
namespace vts {
|
||||
namespace {
|
||||
|
||||
using ::android::base::unique_fd;
|
||||
using android::hardware::graphics::common::V1_2::BufferUsage;
|
||||
using android::hardware::graphics::common::V1_2::PixelFormat;
|
||||
using Tolerance = ::android::hardware::graphics::mapper::V4_0::vts::Gralloc::Tolerance;
|
||||
using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
|
||||
using aidl::android::hardware::graphics::common::BlendMode;
|
||||
using aidl::android::hardware::graphics::common::Cta861_3;
|
||||
@@ -276,7 +279,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) {
|
||||
hidl_vec<uint8_t> vec;
|
||||
ASSERT_EQ(Error::NONE,
|
||||
@@ -294,6 +297,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; }
|
||||
|
||||
std::unique_ptr<Gralloc> mGralloc;
|
||||
@@ -331,8 +377,9 @@ TEST_P(GraphicsMapperHidlTest, AllocatorAllocate) {
|
||||
for (uint32_t count = 0; count < 5; count++) {
|
||||
std::vector<const native_handle_t*> bufferHandles;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandles = mGralloc->allocate(descriptor, count, false, false, &stride));
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandles =
|
||||
mGralloc->allocate(descriptor, count, false,
|
||||
Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
if (count >= 1) {
|
||||
EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride";
|
||||
@@ -532,32 +579,30 @@ TEST_P(GraphicsMapperHidlTest, LockUnlockBasic) {
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
// lock buffer for writing
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
int fence = -1;
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
// RGBA_8888
|
||||
fillRGBA8888(data, info.height, stride * 4, info.width * 4);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
verifyRGBA8888(bufferHandle, data, info.height, stride * 4, info.width * 4));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
|
||||
if (fence >= 0) {
|
||||
close(fence);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
@@ -566,16 +611,21 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
|
||||
ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(
|
||||
info, true, Tolerance::kToleranceUnSupported, &stride));
|
||||
if (bufferHandle == nullptr) {
|
||||
GTEST_SUCCEED() << "YCRCB_420_SP format is unsupported";
|
||||
return;
|
||||
}
|
||||
|
||||
// lock buffer for writing
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
int fence = -1;
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
@@ -583,74 +633,122 @@ TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
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;
|
||||
ASSERT_EQ(crData + 1, cbData);
|
||||
ASSERT_EQ(2, chromaStep);
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
|
||||
|
||||
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);
|
||||
auto cbData = static_cast<uint8_t*>(yCbCr.cb);
|
||||
auto crData = static_cast<uint8_t*>(yCbCr.cr);
|
||||
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.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
|
||||
yData = static_cast<uint8_t*>(yCbCr.y);
|
||||
cbData = static_cast<uint8_t*>(yCbCr.cb);
|
||||
crData = static_cast<uint8_t*>(yCbCr.cr);
|
||||
verifyYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
|
||||
|
||||
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);
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
EXPECT_EQ(val, yData[yStride * y + x]);
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_YV12) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::YV12;
|
||||
|
||||
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);
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
EXPECT_EQ(subSampleVal, cbData[subSampleOffset]);
|
||||
EXPECT_EQ(subSampleVal + 1, crData[subSampleOffset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// lock buffer for writing
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
|
||||
if (fence >= 0) {
|
||||
close(fence);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
int64_t vSubsampling = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
|
||||
constexpr uint32_t kCbCrSubSampleFactor = 2;
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
|
||||
|
||||
auto cbData = static_cast<uint8_t*>(yCbCr.cb);
|
||||
auto crData = static_cast<uint8_t*>(yCbCr.cr);
|
||||
ASSERT_EQ(crData + yCbCr.cstride * info.height / vSubsampling, cbData);
|
||||
ASSERT_EQ(1, yCbCr.chroma_step);
|
||||
|
||||
fillYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
|
||||
verifyYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_420_888) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.format = PixelFormat::YCBCR_420_888;
|
||||
|
||||
const native_handle_t* bufferHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
// lock buffer for writing
|
||||
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
|
||||
static_cast<int32_t>(info.height)};
|
||||
unique_fd fence;
|
||||
uint8_t* data;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
android_ycbcr yCbCr;
|
||||
int64_t hSubsampling = 0;
|
||||
int64_t vSubsampling = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
|
||||
constexpr uint32_t kCbCrSubSampleFactor = 2;
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
|
||||
ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
|
||||
|
||||
fillYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
|
||||
// lock again for reading
|
||||
ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(
|
||||
mGralloc->lock(bufferHandle, info.usage, region, fence.get())));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
getAndroidYCbCr(bufferHandle, data, &yCbCr, &hSubsampling, &vSubsampling));
|
||||
|
||||
verifyYCbCr888Data(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,8 +839,8 @@ TEST_P(GraphicsMapperHidlTest, FlushRereadBasic) {
|
||||
|
||||
const native_handle_t* rawHandle;
|
||||
uint32_t stride;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false, false, &stride));
|
||||
ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false,
|
||||
Tolerance::kToleranceStrict, &stride));
|
||||
|
||||
const native_handle_t* writeBufferHandle;
|
||||
const native_handle_t* readBufferHandle;
|
||||
@@ -766,11 +864,10 @@ TEST_P(GraphicsMapperHidlTest, FlushRereadBasic) {
|
||||
|
||||
fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
|
||||
|
||||
int fence;
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->flushLockedBuffer(writeBufferHandle));
|
||||
unique_fd fence;
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->flushLockedBuffer(writeBufferHandle)));
|
||||
if (fence >= 0) {
|
||||
ASSERT_EQ(0, sync_wait(fence, 3500));
|
||||
close(fence);
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(mGralloc->rereadLockedBuffer(readBufferHandle));
|
||||
@@ -778,14 +875,9 @@ TEST_P(GraphicsMapperHidlTest, FlushRereadBasic) {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
verifyRGBA8888(readBufferHandle, readData, info.height, stride * 4, info.width * 4));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(readBufferHandle));
|
||||
if (fence >= 0) {
|
||||
close(fence);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(writeBufferHandle));
|
||||
if (fence >= 0) {
|
||||
close(fence);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(readBufferHandle)));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(writeBufferHandle)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -964,7 +1056,7 @@ TEST_P(GraphicsMapperHidlTest, GetProtectedContent) {
|
||||
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
|
||||
|
||||
const native_handle_t* bufferHandle = nullptr;
|
||||
bufferHandle = mGralloc->allocate(info, true, true);
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceAllErrors);
|
||||
if (!bufferHandle) {
|
||||
GTEST_SUCCEED() << "unable to allocate protected content";
|
||||
return;
|
||||
@@ -1267,7 +1359,7 @@ TEST_P(GraphicsMapperHidlTest, SetProtectedContent) {
|
||||
auto info = mDummyDescriptorInfo;
|
||||
info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
|
||||
|
||||
bufferHandle = mGralloc->allocate(info, true, true);
|
||||
bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceAllErrors);
|
||||
if (!bufferHandle) {
|
||||
GTEST_SUCCEED() << "unable to allocate protected content";
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user