Camera: Add support for IMapper 3.0

Use IMapper 3.0 if available. Otherwise, fall back to IMapper 2.0.

Test: Update camera VTS test passes
Bug: 128013727
Change-Id: I9bb54bbc290f1b90ef593dee9796b22b0dd49671
This commit is contained in:
Shuzhen Wang
2019-05-10 12:07:14 -07:00
parent a12498abf8
commit 915115e381
11 changed files with 237 additions and 114 deletions

View File

@@ -20,6 +20,7 @@ cc_library_static {
"libhardware",
"libcamera_metadata",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"libexif",
],
include_dirs: ["system/media/private/camera/include"],

View File

@@ -25,7 +25,9 @@ namespace common {
namespace V1_0 {
namespace helper {
using MapperError = android::hardware::graphics::mapper::V2_0::Error;
using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
HandleImporter::HandleImporter() : mInitialized(false) {}
@@ -34,8 +36,14 @@ void HandleImporter::initializeLocked() {
return;
}
mMapper = IMapper::getService();
if (mMapper == nullptr) {
mMapperV3 = IMapperV3::getService();
if (mMapperV3 != nullptr) {
mInitialized = true;
return;
}
mMapperV2 = IMapper::getService();
if (mMapperV2 == nullptr) {
ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
return;
}
@@ -45,10 +53,90 @@ void HandleImporter::initializeLocked() {
}
void HandleImporter::cleanup() {
mMapper.clear();
mMapperV3.clear();
mMapperV2.clear();
mInitialized = false;
}
template<class M, class E>
bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
E error;
buffer_handle_t importedHandle;
auto ret = mapper->importBuffer(
hidl_handle(handle),
[&](const auto& tmpError, const auto& tmpBufferHandle) {
error = tmpError;
importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
});
if (!ret.isOk()) {
ALOGE("%s: mapper importBuffer failed: %s",
__FUNCTION__, ret.description().c_str());
return false;
}
if (error != E::NONE) {
return false;
}
handle = importedHandle;
return true;
}
template<class M, class E>
YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
hidl_handle acquireFenceHandle;
auto buffer = const_cast<native_handle_t*>(buf);
YCbCrLayout layout = {};
typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
accessRegion.width, accessRegion.height};
mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpLayout) {
if (tmpError == E::NONE) {
// Member by member copy from different versions of YCbCrLayout.
layout.y = tmpLayout.y;
layout.cb = tmpLayout.cb;
layout.cr = tmpLayout.cr;
layout.yStride = tmpLayout.yStride;
layout.cStride = tmpLayout.cStride;
layout.chromaStep = tmpLayout.chromaStep;
} else {
ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
}
});
return layout;
}
template<class M, class E>
int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
int releaseFence = -1;
auto buffer = const_cast<native_handle_t*>(buf);
mapper->unlock(
buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
if (tmpError == E::NONE) {
auto fenceHandle = tmpReleaseFence.getNativeHandle();
if (fenceHandle) {
if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
ALOGE("%s: bad release fence numInts %d numFds %d",
__FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
return;
}
releaseFence = dup(fenceHandle->data[0]);
if (releaseFence < 0) {
ALOGE("%s: bad release fence FD %d",
__FUNCTION__, releaseFence);
}
}
} else {
ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
}
});
return releaseFence;
}
// In IComposer, any buffer_handle_t is owned by the caller and we need to
// make a clone for hwcomposer2. We also need to translate empty handle
// to nullptr. This function does that, in-place.
@@ -63,33 +151,16 @@ bool HandleImporter::importBuffer(buffer_handle_t& handle) {
initializeLocked();
}
if (mMapper == nullptr) {
ALOGE("%s: mMapper is null!", __FUNCTION__);
return false;
if (mMapperV3 != nullptr) {
return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
}
MapperError error;
buffer_handle_t importedHandle;
auto ret = mMapper->importBuffer(
hidl_handle(handle),
[&](const auto& tmpError, const auto& tmpBufferHandle) {
error = tmpError;
importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
});
if (!ret.isOk()) {
ALOGE("%s: mapper importBuffer failed: %s",
__FUNCTION__, ret.description().c_str());
return false;
if (mMapperV2 != nullptr) {
return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
}
if (error != MapperError::NONE) {
return false;
}
handle = importedHandle;
return true;
ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
return false;
}
void HandleImporter::freeBuffer(buffer_handle_t handle) {
@@ -98,15 +169,23 @@ void HandleImporter::freeBuffer(buffer_handle_t handle) {
}
Mutex::Autolock lock(mLock);
if (mMapper == nullptr) {
ALOGE("%s: mMapper is null!", __FUNCTION__);
if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
return;
}
auto ret = mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
if (!ret.isOk()) {
ALOGE("%s: mapper freeBuffer failed: %s",
__FUNCTION__, ret.description().c_str());
if (mMapperV3 != nullptr) {
auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
if (!ret.isOk()) {
ALOGE("%s: mapper freeBuffer failed: %s",
__FUNCTION__, ret.description().c_str());
}
} else {
auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
if (!ret.isOk()) {
ALOGE("%s: mapper freeBuffer failed: %s",
__FUNCTION__, ret.description().c_str());
}
}
}
@@ -138,91 +217,82 @@ void* HandleImporter::lock(
buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
Mutex::Autolock lock(mLock);
void *ret = 0;
IMapper::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
if (!mInitialized) {
initializeLocked();
}
if (mMapper == nullptr) {
ALOGE("%s: mMapper is null!", __FUNCTION__);
if (mMapperV3 == nullptr && mMapperV2 == nullptr) {
ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
return ret;
}
hidl_handle acquireFenceHandle;
auto buffer = const_cast<native_handle_t*>(buf);
mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpPtr) {
if (tmpError == MapperError::NONE) {
ret = tmpPtr;
} else {
ALOGE("%s: failed to lock error %d!",
__FUNCTION__, tmpError);
}
});
if (mMapperV3 != nullptr) {
IMapperV3::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
// No need to use bytesPerPixel and bytesPerStride because we are using
// an 1-D buffer and accressRegion.
mMapperV3->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
const auto& /*bytesPerStride*/) {
if (tmpError == MapperErrorV3::NONE) {
ret = tmpPtr;
} else {
ALOGE("%s: failed to lock error %d!",
__FUNCTION__, tmpError);
}
});
} else {
IMapper::Rect accessRegion { 0, 0, static_cast<int>(size), 1 };
mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpPtr) {
if (tmpError == MapperErrorV2::NONE) {
ret = tmpPtr;
} else {
ALOGE("%s: failed to lock error %d!",
__FUNCTION__, tmpError);
}
});
}
ALOGV("%s: ptr %p size: %zu", __FUNCTION__, ret, size);
return ret;
}
YCbCrLayout HandleImporter::lockYCbCr(
buffer_handle_t& buf, uint64_t cpuUsage,
const IMapper::Rect& accessRegion) {
Mutex::Autolock lock(mLock);
YCbCrLayout layout = {};
if (!mInitialized) {
initializeLocked();
}
if (mMapper == nullptr) {
ALOGE("%s: mMapper is null!", __FUNCTION__);
return layout;
if (mMapperV3 != nullptr) {
return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
mMapperV3, buf, cpuUsage, accessRegion);
}
hidl_handle acquireFenceHandle;
auto buffer = const_cast<native_handle_t*>(buf);
mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpLayout) {
if (tmpError == MapperError::NONE) {
layout = tmpLayout;
} else {
ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
}
});
if (mMapperV2 != nullptr) {
return lockYCbCrInternal<IMapper, MapperErrorV2>(
mMapperV2, buf, cpuUsage, accessRegion);
}
ALOGV("%s: layout y %p cb %p cr %p y_str %d c_str %d c_step %d",
__FUNCTION__, layout.y, layout.cb, layout.cr,
layout.yStride, layout.cStride, layout.chromaStep);
return layout;
ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
return {};
}
int HandleImporter::unlock(buffer_handle_t& buf) {
int releaseFence = -1;
auto buffer = const_cast<native_handle_t*>(buf);
mMapper->unlock(
buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
if (tmpError == MapperError::NONE) {
auto fenceHandle = tmpReleaseFence.getNativeHandle();
if (fenceHandle) {
if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
ALOGE("%s: bad release fence numInts %d numFds %d",
__FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
return;
}
releaseFence = dup(fenceHandle->data[0]);
if (releaseFence <= 0) {
ALOGE("%s: bad release fence FD %d",
__FUNCTION__, releaseFence);
}
}
} else {
ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
}
});
if (mMapperV3 != nullptr) {
return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
}
if (mMapperV2 != nullptr) {
return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
}
return releaseFence;
ALOGE("%s: mMapperV3 and mMapperV2 are both null!", __FUNCTION__);
return -1;
}
} // namespace helper

View File

@@ -19,6 +19,7 @@
#include <utils/Mutex.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <cutils/native_handle.h>
using android::hardware::graphics::mapper::V2_0::IMapper;
@@ -57,10 +58,18 @@ private:
void initializeLocked();
void cleanup();
template<class M, class E>
bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
template<class M, class E>
YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
const IMapper::Rect& accessRegion);
template<class M, class E>
int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
Mutex mLock;
bool mInitialized;
sp<IMapper> mMapper;
sp<IMapper> mMapperV2;
sp<graphics::mapper::V3_0::IMapper> mMapperV3;
};
} // namespace helper

View File

@@ -15,6 +15,7 @@ cc_library_shared {
"android.hardware.camera.common@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.common@1.0",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",

View File

@@ -13,6 +13,7 @@ cc_library_shared {
"android.hardware.camera.device@3.2",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",

View File

@@ -15,6 +15,7 @@ cc_library_shared {
"android.hardware.camera.device@3.3",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",

View File

@@ -48,6 +48,7 @@ cc_library_shared {
"android.hardware.camera.device@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",
@@ -84,6 +85,7 @@ cc_library_shared {
"android.hardware.camera.device@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",

View File

@@ -49,6 +49,7 @@ cc_library_shared {
"android.hardware.camera.device@3.5",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",
@@ -82,6 +83,7 @@ cc_library_shared {
"android.hardware.camera.device@3.5",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"liblog",
"libhardware",
"libcamera_metadata",

View File

@@ -12,6 +12,7 @@ cc_library_shared {
"android.hardware.camera.device@3.5",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"camera.device@1.0-impl",
@@ -50,6 +51,7 @@ cc_library_shared {
"android.hardware.camera.device@3.5",
"android.hardware.camera.provider@2.4",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"camera.device@3.3-impl",

View File

@@ -42,8 +42,10 @@ cc_test {
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",

View File

@@ -54,8 +54,10 @@
#include <ui/GraphicBuffer.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
@@ -6104,36 +6106,66 @@ void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint
sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
android::hardware::graphics::allocator::V2_0::IAllocator::getService();
ASSERT_NE(nullptr, allocator.get());
sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
android::hardware::graphics::allocator::V3_0::IAllocator::getService();
sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
android::hardware::graphics::mapper::V3_0::IMapper::getService();
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
ASSERT_NE(mapper.get(), nullptr);
android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
descriptorInfo.width = width;
descriptorInfo.height = height;
descriptorInfo.layerCount = 1;
descriptorInfo.format = format;
descriptorInfo.usage = usage;
::android::hardware::hidl_vec<uint32_t> descriptor;
auto ret = mapper->createDescriptor(
descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
::android::hardware::hidl_vec<uint32_t> desc) {
ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
descriptor = desc;
});
ASSERT_TRUE(ret.isOk());
if (mapperV3 != nullptr && allocatorV3 != nullptr) {
android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
descriptorInfo.width = width;
descriptorInfo.height = height;
descriptorInfo.layerCount = 1;
descriptorInfo.format =
static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
descriptorInfo.usage = usage;
ret = allocator->allocate(descriptor, 1u,
[&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
ASSERT_EQ(buffers.size(), 1u);
*buffer_handle = buffers[0];
});
ASSERT_TRUE(ret.isOk());
auto ret = mapperV3->createDescriptor(
descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
::android::hardware::hidl_vec<uint32_t> desc) {
ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
descriptor = desc;
});
ASSERT_TRUE(ret.isOk());
ret = allocatorV3->allocate(descriptor, 1u,
[&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
ASSERT_EQ(buffers.size(), 1u);
*buffer_handle = buffers[0];
});
ASSERT_TRUE(ret.isOk());
} else {
ASSERT_NE(mapper.get(), nullptr);
ASSERT_NE(allocator.get(), nullptr);
android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
descriptorInfo.width = width;
descriptorInfo.height = height;
descriptorInfo.layerCount = 1;
descriptorInfo.format = format;
descriptorInfo.usage = usage;
auto ret = mapper->createDescriptor(
descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
::android::hardware::hidl_vec<uint32_t> desc) {
ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
descriptor = desc;
});
ASSERT_TRUE(ret.isOk());
ret = allocator->allocate(descriptor, 1u,
[&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
ASSERT_EQ(buffers.size(), 1u);
*buffer_handle = buffers[0];
});
ASSERT_TRUE(ret.isOk());
}
}
void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {