Loading sensors/1.0/vts/functional/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalSensorsTargetTestUtils", ], Loading sensors/2.0/vts/functional/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "android.hardware.sensors@2.0", "libfmq", Loading sensors/common/vts/utils/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -31,7 +31,10 @@ cc_library_static { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalHidlTargetTestBase", ], Loading sensors/common/vts/utils/GrallocWrapper.cpp +209 −153 Original line number Diff line number Diff line Loading @@ -16,206 +16,262 @@ #include "GrallocWrapper.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.1/IMapper.h> #include <android/hardware/graphics/mapper/3.0/IMapper.h> #include <utils/Log.h> #include <cinttypes> #include <type_traits> using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator; using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator; using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper; using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper; using Error2 = ::android::hardware::graphics::mapper::V2_0::Error; using Error3 = ::android::hardware::graphics::mapper::V3_0::Error; using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::PixelFormat; // This is a typedef to the same underlying type across v2.0 and v3.0 using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; namespace android { GrallocWrapper::GrallocWrapper() { init(); } // Since we use the same APIs across allocator/mapper HALs but they have major // version differences (meaning they are not related through inheritance), we // create a common interface abstraction for the IAllocator + IMapper combination // (major versions need to match in the current HALs, e.g. IAllocator 3.0 needs to // be paired with IMapper 3.0, so these are tied together) class IGrallocHalWrapper { public: virtual ~IGrallocHalWrapper() = default; void GrallocWrapper::init() { mAllocator = allocator2::IAllocator::getService(); if (mAllocator == nullptr) { ALOGE("Failed to get allocator service"); } // IAllocator virtual std::string dumpDebugInfo() = 0; virtual native_handle_t* allocate(uint32_t size) = 0; virtual void freeBuffer(native_handle_t* bufferHandle) = 0; mMapper = mapper2::IMapper::getService(); if (mMapper == nullptr) { ALOGE("Failed to get mapper service"); } else if (mMapper->isRemote()) { ALOGE("Mapper is not in passthrough mode"); } } // IMapper virtual void* lock(native_handle_t* bufferHandle) = 0; virtual void unlock(native_handle_t* bufferHandle) = 0; }; GrallocWrapper::~GrallocWrapper() { for (auto bufferHandle : mClonedBuffers) { auto buffer = const_cast<native_handle_t*>(bufferHandle); native_handle_close(buffer); native_handle_delete(buffer); } mClonedBuffers.clear(); namespace { for (auto bufferHandle : mImportedBuffers) { auto buffer = const_cast<native_handle_t*>(bufferHandle); if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) { ALOGE("Failed to free buffer %p", buffer); } bool failed(Error2 error) { return (error != Error2::NONE); } mImportedBuffers.clear(); bool failed(Error3 error) { return (error != Error3::NONE); } sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const { return mAllocator; // Since all the type and function names are the same for the things we use across the major HAL // versions, we use template magic to avoid repeating ourselves. template <typename AllocatorT, typename MapperT> class GrallocHalWrapper : public IGrallocHalWrapper { public: GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper) : mAllocator(allocator), mMapper(mapper) { if (mapper->isRemote()) { ALOGE("Mapper is in passthrough mode"); } } std::string GrallocWrapper::dumpDebugInfo() { std::string debugInfo; mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); virtual std::string dumpDebugInfo() override; virtual native_handle_t* allocate(uint32_t size) override; virtual void freeBuffer(native_handle_t* bufferHandle) override; virtual void* lock(native_handle_t* bufferHandle) override; virtual void unlock(native_handle_t* bufferHandle) override; private: static constexpr uint64_t kBufferUsage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN); sp<AllocatorT> mAllocator; sp<MapperT> mMapper; BufferDescriptor getDescriptor(uint32_t size); native_handle_t* importBuffer(const hidl_handle& rawHandle); }; template <typename AllocatorT, typename MapperT> std::string GrallocHalWrapper<AllocatorT, MapperT>::dumpDebugInfo() { std::string debugInfo; mAllocator->dumpDebugInfo([&](const hidl_string& tmpDebugInfo) { debugInfo = tmpDebugInfo; }); return debugInfo; } const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) { const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); template <typename AllocatorT, typename MapperT> native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) { constexpr uint32_t kBufferCount = 1; BufferDescriptor descriptor = getDescriptor(size); native_handle_t* bufferHandle = nullptr; if (bufferHandle) { mClonedBuffers.insert(bufferHandle); auto callback = [&](auto error, uint32_t /*stride*/, const hidl_vec<hidl_handle>& buffers) { if (failed(error)) { ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error)); } else if (buffers.size() != kBufferCount) { ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", buffers.size(), kBufferCount); } else { bufferHandle = importBuffer(buffers[0]); } }; mAllocator->allocate(descriptor, kBufferCount, callback); return bufferHandle; } std::vector<const native_handle_t*> GrallocWrapper::allocate( const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, 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 (mapper2::Error::NONE != tmpError) { ALOGE("Failed to allocate buffers"); template <typename AllocatorT, typename MapperT> void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) { auto error = mMapper->freeBuffer(bufferHandle); if (!error.isOk() || failed(error)) { ALOGE("Failed to free buffer %p", bufferHandle); } if (count != tmpBuffers.size()) { ALOGE("Invalid buffer array"); } for (uint32_t i = 0; i < count; i++) { if (import) { bufferHandles.push_back(importBuffer(tmpBuffers[i])); template <typename AllocatorT, typename MapperT> BufferDescriptor GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) { typename MapperT::BufferDescriptorInfo descriptorInfo = { .width = size, .height = 1, .layerCount = 1, .usage = kBufferUsage, .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB), }; BufferDescriptor descriptor; auto callback = [&](auto error, const BufferDescriptor& tmpDescriptor) { if (failed(error)) { ALOGE("Failed to create descriptor: %" PRId32, static_cast<int32_t>(error)); } else { bufferHandles.push_back(cloneBuffer(tmpBuffers[i])); } descriptor = tmpDescriptor; } }; if (outStride) { *outStride = tmpStride; mMapper->createDescriptor(descriptorInfo, callback); return descriptor; } }); return bufferHandles; } template <typename AllocatorT, typename MapperT> native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer( const hidl_handle& rawHandle) { native_handle_t* bufferHandle = nullptr; const native_handle_t* GrallocWrapper::allocate( const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import, uint32_t* outStride) { mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo); auto buffers = allocate(descriptor, 1, import, outStride); return buffers[0]; mMapper->importBuffer(rawHandle, [&](auto error, void* tmpBuffer) { if (failed(error)) { ALOGE("Failed to import buffer %p: %" PRId32, rawHandle.getNativeHandle(), static_cast<int32_t>(error)); } else { bufferHandle = static_cast<native_handle_t*>(tmpBuffer); } }); sp<mapper2::IMapper> GrallocWrapper::getMapper() const { return mMapper; return bufferHandle; } mapper2::BufferDescriptor GrallocWrapper::createDescriptor( const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) { mapper2::BufferDescriptor descriptor; mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to create descriptor"); template <typename AllocatorT, typename MapperT> void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) { // Per the HAL, all-zeros Rect means the entire buffer typename MapperT::Rect accessRegion = {}; hidl_handle acquireFenceHandle; // No fence needed, already safe to lock void* data = nullptr; mMapper->lock(bufferHandle, kBufferUsage, accessRegion, acquireFenceHandle, [&](auto error, void* tmpData, ...) { // V3_0 passes extra args we don't use if (failed(error)) { ALOGE("Failed to lock buffer %p: %" PRId32, bufferHandle, static_cast<int32_t>(error)); } else { data = tmpData; } descriptor = tmpDescriptor; }); return descriptor; return data; } const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) { const native_handle_t* bufferHandle = nullptr; mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle()); template <typename AllocatorT, typename MapperT> void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) { mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) { if (failed(error)) { ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle, static_cast<int32_t>(error)); } bufferHandle = static_cast<const native_handle_t*>(tmpBuffer); }); if (bufferHandle) { mImportedBuffers.insert(bufferHandle); } return bufferHandle; } } // anonymous namespace void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) { auto buffer = const_cast<native_handle_t*>(bufferHandle); GrallocWrapper::GrallocWrapper() { sp<IAllocator3> allocator3 = IAllocator3::getService(); sp<IMapper3> mapper3 = IMapper3::getService(); if (mImportedBuffers.erase(bufferHandle)) { mapper2::Error error = mMapper->freeBuffer(buffer); if (error != mapper2::Error::NONE) { ALOGE("Failed to free %p", buffer); } if (allocator3 != nullptr && mapper3 != nullptr) { mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( new GrallocHalWrapper<IAllocator3, IMapper3>(allocator3, mapper3)); } else { mClonedBuffers.erase(bufferHandle); native_handle_close(buffer); native_handle_delete(buffer); } } void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, const mapper2::IMapper::Rect& accessRegion, int acquireFence) { auto buffer = const_cast<native_handle_t*>(bufferHandle); ALOGD("Graphics HALs 3.0 not found (allocator %d mapper %d), falling back to 2.x", (allocator3 != nullptr), (mapper3 != nullptr)); NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); hardware::hidl_handle acquireFenceHandle; if (acquireFence >= 0) { auto h = native_handle_init(acquireFenceStorage, 1, 0); h->data[0] = acquireFence; acquireFenceHandle = h; sp<IAllocator2> allocator2 = IAllocator2::getService(); sp<IMapper2> mapper2 = IMapper2_1::getService(); if (mapper2 == nullptr) { mapper2 = IMapper2::getService(); } void* data = nullptr; mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to lock buffer %p", buffer); if (allocator2 != nullptr && mapper2 != nullptr) { mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( new GrallocHalWrapper<IAllocator2, IMapper2>(allocator2, mapper2)); } else { ALOGE("Couldn't open 2.x/3.0 graphics HALs (2.x allocator %d mapper %d)", (allocator2 != nullptr), (mapper2 != nullptr)); } data = tmpData; }); if (acquireFence >= 0) { close(acquireFence); } return data; } int GrallocWrapper::unlock(const native_handle_t* bufferHandle) { auto buffer = const_cast<native_handle_t*>(bufferHandle); int releaseFence = -1; mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to unlock buffer %p", buffer); GrallocWrapper::~GrallocWrapper() { for (auto bufferHandle : mAllocatedBuffers) { mGrallocHal->unlock(bufferHandle); mGrallocHal->freeBuffer(bufferHandle); } auto fenceHandle = tmpReleaseFence.getNativeHandle(); if (fenceHandle) { if (fenceHandle->numInts != 0) { ALOGE("Invalid fence handle %p", fenceHandle); mAllocatedBuffers.clear(); } if (fenceHandle->numFds == 1) { releaseFence = dup(fenceHandle->data[0]); if (releaseFence < 0) { ALOGE("Failed to dup fence fd"); std::string GrallocWrapper::dumpDebugInfo() { return mGrallocHal->dumpDebugInfo(); } std::pair<native_handle_t*, void*> GrallocWrapper::allocate(uint32_t size) { native_handle_t* bufferHandle = mGrallocHal->allocate(size); void* buffer = nullptr; if (bufferHandle) { buffer = mGrallocHal->lock(bufferHandle); if (buffer) { mAllocatedBuffers.insert(bufferHandle); } else { if (fenceHandle->numFds != 0) { ALOGE("Invalid fence handle %p", fenceHandle); mGrallocHal->freeBuffer(bufferHandle); bufferHandle = nullptr; } } return std::make_pair<>(bufferHandle, buffer); } }); return releaseFence; void GrallocWrapper::freeBuffer(native_handle_t* bufferHandle) { if (mAllocatedBuffers.erase(bufferHandle)) { mGrallocHal->unlock(bufferHandle); mGrallocHal->freeBuffer(bufferHandle); } } } // namespace android sensors/common/vts/utils/SensorsTestSharedMemory.cpp +5 −26 Original line number Diff line number Diff line Loading @@ -119,32 +119,13 @@ SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size } case SharedMemType::GRALLOC: { mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); if (mGrallocWrapper->getAllocator() == nullptr || mGrallocWrapper->getMapper() == nullptr) { if (!mGrallocWrapper->isInitialized()) { break; } using android::hardware::graphics::common::V1_0::BufferUsage; using android::hardware::graphics::common::V1_0::PixelFormat; mapper2::IMapper::BufferDescriptorInfo buf_desc_info = { .width = static_cast<uint32_t>(size), .height = 1, .layerCount = 1, .usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN), .format = PixelFormat::BLOB}; handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info)); if (handle != nullptr) { mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width), static_cast<int32_t>(buf_desc_info.height)}; buffer = static_cast<char*>( mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1)); if (buffer != nullptr) { break; } mGrallocWrapper->freeBuffer(handle); handle = nullptr; } std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); handle = buf.first; buffer = static_cast<char*>(buf.second); break; } default: Loading Loading @@ -175,9 +156,7 @@ SensorsTestSharedMemory::~SensorsTestSharedMemory() { } case SharedMemType::GRALLOC: { if (mSize != 0) { mGrallocWrapper->unlock(mNativeHandle); mGrallocWrapper->freeBuffer(mNativeHandle); mNativeHandle = nullptr; mSize = 0; } Loading Loading
sensors/1.0/vts/functional/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalSensorsTargetTestUtils", ], Loading
sensors/2.0/vts/functional/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -24,7 +24,10 @@ cc_test { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "android.hardware.sensors@2.0", "libfmq", Loading
sensors/common/vts/utils/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -31,7 +31,10 @@ cc_library_static { ], static_libs: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.1", "android.hardware.graphics.mapper@3.0", "android.hardware.sensors@1.0", "VtsHalHidlTargetTestBase", ], Loading
sensors/common/vts/utils/GrallocWrapper.cpp +209 −153 Original line number Diff line number Diff line Loading @@ -16,206 +16,262 @@ #include "GrallocWrapper.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.1/IMapper.h> #include <android/hardware/graphics/mapper/3.0/IMapper.h> #include <utils/Log.h> #include <cinttypes> #include <type_traits> using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator; using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator; using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper; using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper; using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper; using Error2 = ::android::hardware::graphics::mapper::V2_0::Error; using Error3 = ::android::hardware::graphics::mapper::V3_0::Error; using ::android::hardware::graphics::common::V1_0::BufferUsage; using ::android::hardware::graphics::common::V1_0::PixelFormat; // This is a typedef to the same underlying type across v2.0 and v3.0 using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; namespace android { GrallocWrapper::GrallocWrapper() { init(); } // Since we use the same APIs across allocator/mapper HALs but they have major // version differences (meaning they are not related through inheritance), we // create a common interface abstraction for the IAllocator + IMapper combination // (major versions need to match in the current HALs, e.g. IAllocator 3.0 needs to // be paired with IMapper 3.0, so these are tied together) class IGrallocHalWrapper { public: virtual ~IGrallocHalWrapper() = default; void GrallocWrapper::init() { mAllocator = allocator2::IAllocator::getService(); if (mAllocator == nullptr) { ALOGE("Failed to get allocator service"); } // IAllocator virtual std::string dumpDebugInfo() = 0; virtual native_handle_t* allocate(uint32_t size) = 0; virtual void freeBuffer(native_handle_t* bufferHandle) = 0; mMapper = mapper2::IMapper::getService(); if (mMapper == nullptr) { ALOGE("Failed to get mapper service"); } else if (mMapper->isRemote()) { ALOGE("Mapper is not in passthrough mode"); } } // IMapper virtual void* lock(native_handle_t* bufferHandle) = 0; virtual void unlock(native_handle_t* bufferHandle) = 0; }; GrallocWrapper::~GrallocWrapper() { for (auto bufferHandle : mClonedBuffers) { auto buffer = const_cast<native_handle_t*>(bufferHandle); native_handle_close(buffer); native_handle_delete(buffer); } mClonedBuffers.clear(); namespace { for (auto bufferHandle : mImportedBuffers) { auto buffer = const_cast<native_handle_t*>(bufferHandle); if (mMapper->freeBuffer(buffer) != mapper2::Error::NONE) { ALOGE("Failed to free buffer %p", buffer); } bool failed(Error2 error) { return (error != Error2::NONE); } mImportedBuffers.clear(); bool failed(Error3 error) { return (error != Error3::NONE); } sp<allocator2::IAllocator> GrallocWrapper::getAllocator() const { return mAllocator; // Since all the type and function names are the same for the things we use across the major HAL // versions, we use template magic to avoid repeating ourselves. template <typename AllocatorT, typename MapperT> class GrallocHalWrapper : public IGrallocHalWrapper { public: GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper) : mAllocator(allocator), mMapper(mapper) { if (mapper->isRemote()) { ALOGE("Mapper is in passthrough mode"); } } std::string GrallocWrapper::dumpDebugInfo() { std::string debugInfo; mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); }); virtual std::string dumpDebugInfo() override; virtual native_handle_t* allocate(uint32_t size) override; virtual void freeBuffer(native_handle_t* bufferHandle) override; virtual void* lock(native_handle_t* bufferHandle) override; virtual void unlock(native_handle_t* bufferHandle) override; private: static constexpr uint64_t kBufferUsage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN); sp<AllocatorT> mAllocator; sp<MapperT> mMapper; BufferDescriptor getDescriptor(uint32_t size); native_handle_t* importBuffer(const hidl_handle& rawHandle); }; template <typename AllocatorT, typename MapperT> std::string GrallocHalWrapper<AllocatorT, MapperT>::dumpDebugInfo() { std::string debugInfo; mAllocator->dumpDebugInfo([&](const hidl_string& tmpDebugInfo) { debugInfo = tmpDebugInfo; }); return debugInfo; } const native_handle_t* GrallocWrapper::cloneBuffer(const hardware::hidl_handle& rawHandle) { const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle()); template <typename AllocatorT, typename MapperT> native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) { constexpr uint32_t kBufferCount = 1; BufferDescriptor descriptor = getDescriptor(size); native_handle_t* bufferHandle = nullptr; if (bufferHandle) { mClonedBuffers.insert(bufferHandle); auto callback = [&](auto error, uint32_t /*stride*/, const hidl_vec<hidl_handle>& buffers) { if (failed(error)) { ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error)); } else if (buffers.size() != kBufferCount) { ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", buffers.size(), kBufferCount); } else { bufferHandle = importBuffer(buffers[0]); } }; mAllocator->allocate(descriptor, kBufferCount, callback); return bufferHandle; } std::vector<const native_handle_t*> GrallocWrapper::allocate( const mapper2::BufferDescriptor& descriptor, uint32_t count, bool import, 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 (mapper2::Error::NONE != tmpError) { ALOGE("Failed to allocate buffers"); template <typename AllocatorT, typename MapperT> void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) { auto error = mMapper->freeBuffer(bufferHandle); if (!error.isOk() || failed(error)) { ALOGE("Failed to free buffer %p", bufferHandle); } if (count != tmpBuffers.size()) { ALOGE("Invalid buffer array"); } for (uint32_t i = 0; i < count; i++) { if (import) { bufferHandles.push_back(importBuffer(tmpBuffers[i])); template <typename AllocatorT, typename MapperT> BufferDescriptor GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) { typename MapperT::BufferDescriptorInfo descriptorInfo = { .width = size, .height = 1, .layerCount = 1, .usage = kBufferUsage, .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB), }; BufferDescriptor descriptor; auto callback = [&](auto error, const BufferDescriptor& tmpDescriptor) { if (failed(error)) { ALOGE("Failed to create descriptor: %" PRId32, static_cast<int32_t>(error)); } else { bufferHandles.push_back(cloneBuffer(tmpBuffers[i])); } descriptor = tmpDescriptor; } }; if (outStride) { *outStride = tmpStride; mMapper->createDescriptor(descriptorInfo, callback); return descriptor; } }); return bufferHandles; } template <typename AllocatorT, typename MapperT> native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer( const hidl_handle& rawHandle) { native_handle_t* bufferHandle = nullptr; const native_handle_t* GrallocWrapper::allocate( const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo, bool import, uint32_t* outStride) { mapper2::BufferDescriptor descriptor = createDescriptor(descriptorInfo); auto buffers = allocate(descriptor, 1, import, outStride); return buffers[0]; mMapper->importBuffer(rawHandle, [&](auto error, void* tmpBuffer) { if (failed(error)) { ALOGE("Failed to import buffer %p: %" PRId32, rawHandle.getNativeHandle(), static_cast<int32_t>(error)); } else { bufferHandle = static_cast<native_handle_t*>(tmpBuffer); } }); sp<mapper2::IMapper> GrallocWrapper::getMapper() const { return mMapper; return bufferHandle; } mapper2::BufferDescriptor GrallocWrapper::createDescriptor( const mapper2::IMapper::BufferDescriptorInfo& descriptorInfo) { mapper2::BufferDescriptor descriptor; mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to create descriptor"); template <typename AllocatorT, typename MapperT> void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) { // Per the HAL, all-zeros Rect means the entire buffer typename MapperT::Rect accessRegion = {}; hidl_handle acquireFenceHandle; // No fence needed, already safe to lock void* data = nullptr; mMapper->lock(bufferHandle, kBufferUsage, accessRegion, acquireFenceHandle, [&](auto error, void* tmpData, ...) { // V3_0 passes extra args we don't use if (failed(error)) { ALOGE("Failed to lock buffer %p: %" PRId32, bufferHandle, static_cast<int32_t>(error)); } else { data = tmpData; } descriptor = tmpDescriptor; }); return descriptor; return data; } const native_handle_t* GrallocWrapper::importBuffer(const hardware::hidl_handle& rawHandle) { const native_handle_t* bufferHandle = nullptr; mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to import buffer %p", rawHandle.getNativeHandle()); template <typename AllocatorT, typename MapperT> void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) { mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) { if (failed(error)) { ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle, static_cast<int32_t>(error)); } bufferHandle = static_cast<const native_handle_t*>(tmpBuffer); }); if (bufferHandle) { mImportedBuffers.insert(bufferHandle); } return bufferHandle; } } // anonymous namespace void GrallocWrapper::freeBuffer(const native_handle_t* bufferHandle) { auto buffer = const_cast<native_handle_t*>(bufferHandle); GrallocWrapper::GrallocWrapper() { sp<IAllocator3> allocator3 = IAllocator3::getService(); sp<IMapper3> mapper3 = IMapper3::getService(); if (mImportedBuffers.erase(bufferHandle)) { mapper2::Error error = mMapper->freeBuffer(buffer); if (error != mapper2::Error::NONE) { ALOGE("Failed to free %p", buffer); } if (allocator3 != nullptr && mapper3 != nullptr) { mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( new GrallocHalWrapper<IAllocator3, IMapper3>(allocator3, mapper3)); } else { mClonedBuffers.erase(bufferHandle); native_handle_close(buffer); native_handle_delete(buffer); } } void* GrallocWrapper::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, const mapper2::IMapper::Rect& accessRegion, int acquireFence) { auto buffer = const_cast<native_handle_t*>(bufferHandle); ALOGD("Graphics HALs 3.0 not found (allocator %d mapper %d), falling back to 2.x", (allocator3 != nullptr), (mapper3 != nullptr)); NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); hardware::hidl_handle acquireFenceHandle; if (acquireFence >= 0) { auto h = native_handle_init(acquireFenceStorage, 1, 0); h->data[0] = acquireFence; acquireFenceHandle = h; sp<IAllocator2> allocator2 = IAllocator2::getService(); sp<IMapper2> mapper2 = IMapper2_1::getService(); if (mapper2 == nullptr) { mapper2 = IMapper2::getService(); } void* data = nullptr; mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to lock buffer %p", buffer); if (allocator2 != nullptr && mapper2 != nullptr) { mGrallocHal = std::unique_ptr<IGrallocHalWrapper>( new GrallocHalWrapper<IAllocator2, IMapper2>(allocator2, mapper2)); } else { ALOGE("Couldn't open 2.x/3.0 graphics HALs (2.x allocator %d mapper %d)", (allocator2 != nullptr), (mapper2 != nullptr)); } data = tmpData; }); if (acquireFence >= 0) { close(acquireFence); } return data; } int GrallocWrapper::unlock(const native_handle_t* bufferHandle) { auto buffer = const_cast<native_handle_t*>(bufferHandle); int releaseFence = -1; mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) { if (tmpError != mapper2::Error::NONE) { ALOGE("Failed to unlock buffer %p", buffer); GrallocWrapper::~GrallocWrapper() { for (auto bufferHandle : mAllocatedBuffers) { mGrallocHal->unlock(bufferHandle); mGrallocHal->freeBuffer(bufferHandle); } auto fenceHandle = tmpReleaseFence.getNativeHandle(); if (fenceHandle) { if (fenceHandle->numInts != 0) { ALOGE("Invalid fence handle %p", fenceHandle); mAllocatedBuffers.clear(); } if (fenceHandle->numFds == 1) { releaseFence = dup(fenceHandle->data[0]); if (releaseFence < 0) { ALOGE("Failed to dup fence fd"); std::string GrallocWrapper::dumpDebugInfo() { return mGrallocHal->dumpDebugInfo(); } std::pair<native_handle_t*, void*> GrallocWrapper::allocate(uint32_t size) { native_handle_t* bufferHandle = mGrallocHal->allocate(size); void* buffer = nullptr; if (bufferHandle) { buffer = mGrallocHal->lock(bufferHandle); if (buffer) { mAllocatedBuffers.insert(bufferHandle); } else { if (fenceHandle->numFds != 0) { ALOGE("Invalid fence handle %p", fenceHandle); mGrallocHal->freeBuffer(bufferHandle); bufferHandle = nullptr; } } return std::make_pair<>(bufferHandle, buffer); } }); return releaseFence; void GrallocWrapper::freeBuffer(native_handle_t* bufferHandle) { if (mAllocatedBuffers.erase(bufferHandle)) { mGrallocHal->unlock(bufferHandle); mGrallocHal->freeBuffer(bufferHandle); } } } // namespace android
sensors/common/vts/utils/SensorsTestSharedMemory.cpp +5 −26 Original line number Diff line number Diff line Loading @@ -119,32 +119,13 @@ SensorsTestSharedMemory::SensorsTestSharedMemory(SharedMemType type, size_t size } case SharedMemType::GRALLOC: { mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); if (mGrallocWrapper->getAllocator() == nullptr || mGrallocWrapper->getMapper() == nullptr) { if (!mGrallocWrapper->isInitialized()) { break; } using android::hardware::graphics::common::V1_0::BufferUsage; using android::hardware::graphics::common::V1_0::PixelFormat; mapper2::IMapper::BufferDescriptorInfo buf_desc_info = { .width = static_cast<uint32_t>(size), .height = 1, .layerCount = 1, .usage = static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN), .format = PixelFormat::BLOB}; handle = const_cast<native_handle_t*>(mGrallocWrapper->allocate(buf_desc_info)); if (handle != nullptr) { mapper2::IMapper::Rect region{0, 0, static_cast<int32_t>(buf_desc_info.width), static_cast<int32_t>(buf_desc_info.height)}; buffer = static_cast<char*>( mGrallocWrapper->lock(handle, buf_desc_info.usage, region, /*fence=*/-1)); if (buffer != nullptr) { break; } mGrallocWrapper->freeBuffer(handle); handle = nullptr; } std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); handle = buf.first; buffer = static_cast<char*>(buf.second); break; } default: Loading Loading @@ -175,9 +156,7 @@ SensorsTestSharedMemory::~SensorsTestSharedMemory() { } case SharedMemType::GRALLOC: { if (mSize != 0) { mGrallocWrapper->unlock(mNativeHandle); mGrallocWrapper->freeBuffer(mNativeHandle); mNativeHandle = nullptr; mSize = 0; } Loading