From 5de271fe6c0f909006141ea26a7b94c1102be31d Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 28 Feb 2023 16:17:13 +0100 Subject: android: mm: generic: Use GraphicBufferAllocator instead of gralloc.h gralloc.h is a very old API that has been deprecated at least since Android P (9). Switch over to a higher level abstraction of gralloc from libui, which is compatible with Android 11 and up. Libui: * is provided in the VNDK (so it's available to vendors). * is also used in the camera vts test named VtsAidlHalCameraProvider_TargetTest. Notes: * GraphicsBufferAllocator being a Singleton, buffer lifecycle management is easier. * The imported headers from Android generate the -Wextra-semi warning. To avoid patching the files, a pragma has been added before inclusion. * libdl was used for dlclosing() the legacy hal, so the dep has been dropped Signed-off-by: Mattijs Korpershoek --- src/android/mm/generic_frame_buffer_allocator.cpp | 68 ++++++++--------------- src/android/mm/meson.build | 5 +- subprojects/packagefiles/vndk/meson.build | 21 +++++++ subprojects/vndk.wrap | 2 +- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/android/mm/generic_frame_buffer_allocator.cpp b/src/android/mm/generic_frame_buffer_allocator.cpp index 7ecef2c6..1f2fbe33 100644 --- a/src/android/mm/generic_frame_buffer_allocator.cpp +++ b/src/android/mm/generic_frame_buffer_allocator.cpp @@ -16,8 +16,11 @@ #include "libcamera/internal/framebuffer.h" #include -#include -#include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wextra-semi" +#include +#pragma GCC diagnostic pop +#include #include "../camera_device.h" #include "../frame_buffer_allocator.h" @@ -33,35 +36,26 @@ class GenericFrameBufferData : public FrameBuffer::Private LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) public: - GenericFrameBufferData(struct alloc_device_t *allocDevice, - buffer_handle_t handle, + GenericFrameBufferData(buffer_handle_t handle, const std::vector &planes) - : FrameBuffer::Private(planes), allocDevice_(allocDevice), - handle_(handle) + : FrameBuffer::Private(planes), handle_(handle) { - ASSERT(allocDevice_); ASSERT(handle_); } ~GenericFrameBufferData() override { /* - * allocDevice_ is used to destroy handle_. allocDevice_ is - * owned by PlatformFrameBufferAllocator::Private. - * GenericFrameBufferData must be destroyed before it is - * destroyed. - * - * \todo Consider managing alloc_device_t with std::shared_ptr - * if this is difficult to maintain. - * * \todo Thread safety against alloc_device_t is not documented. * Is it no problem to call alloc/free in parallel? */ - allocDevice_->free(allocDevice_, handle_); + auto &allocator = android::GraphicBufferAllocator::get(); + android::status_t status = allocator.free(handle_); + if (status != android::NO_ERROR) + LOG(HAL, Error) << "Error freeing framebuffer: " << status; } private: - struct alloc_device_t *allocDevice_; const buffer_handle_t handle_; }; } /* namespace */ @@ -72,51 +66,33 @@ class PlatformFrameBufferAllocator::Private : public Extensible::Private public: Private(CameraDevice *const cameraDevice) - : cameraDevice_(cameraDevice), - hardwareModule_(nullptr), - allocDevice_(nullptr) + : cameraDevice_(cameraDevice) { - hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hardwareModule_); - ASSERT(hardwareModule_); } - ~Private() override; + ~Private() = default; std::unique_ptr allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage); private: const CameraDevice *const cameraDevice_; - const struct hw_module_t *hardwareModule_; - struct alloc_device_t *allocDevice_; }; -PlatformFrameBufferAllocator::Private::~Private() -{ - if (allocDevice_) - gralloc_close(allocDevice_); - dlclose(hardwareModule_->dso); -} - std::unique_ptr PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage) { - if (!allocDevice_) { - int ret = gralloc_open(hardwareModule_, &allocDevice_); - if (ret) { - LOG(HAL, Fatal) << "gralloc_open() failed: " << ret; - return nullptr; - } - } - - int stride = 0; + uint32_t stride = 0; buffer_handle_t handle = nullptr; - int ret = allocDevice_->alloc(allocDevice_, size.width, size.height, - halPixelFormat, usage, &handle, &stride); - if (ret) { - LOG(HAL, Error) << "failed buffer allocation: " << ret; + + auto &allocator = android::GraphicBufferAllocator::get(); + android::status_t status = allocator.allocate(size.width, size.height, halPixelFormat, + 1 /*layerCount*/, usage, &handle, &stride, + "libcameraHAL"); + if (status != android::NO_ERROR) { + LOG(HAL, Error) << "failed buffer allocation: " << status; return nullptr; } if (!handle) { @@ -143,7 +119,7 @@ PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat, return std::make_unique( std::make_unique( - allocDevice_, handle, planes), + handle, planes), handle); } diff --git a/src/android/mm/meson.build b/src/android/mm/meson.build index 85f12f91..702f2ea6 100644 --- a/src/android/mm/meson.build +++ b/src/android/mm/meson.build @@ -4,10 +4,7 @@ platform = get_option('android_platform') if platform == 'generic' android_hal_sources += files(['generic_camera_buffer.cpp', 'generic_frame_buffer_allocator.cpp']) - android_deps += [ - libdl, - dependency('libhardware'), - ] + android_deps += [dependency('libui')] elif platform == 'cros' android_hal_sources += files(['cros_camera_buffer.cpp', 'cros_frame_buffer_allocator.cpp']) diff --git a/subprojects/packagefiles/vndk/meson.build b/subprojects/packagefiles/vndk/meson.build index b5999f16..dbc7eda6 100644 --- a/subprojects/packagefiles/vndk/meson.build +++ b/subprojects/packagefiles/vndk/meson.build @@ -21,3 +21,24 @@ libhardware_dep = declare_dependency( dependencies : cxx.find_library('hardware', dirs : prebuild_libraries), include_directories : include_directories(include_base / 'hardware/libhardware/')) meson.override_dependency('libhardware', libhardware_dep) + +liblog_dep = declare_dependency( + dependencies : cxx.find_library('log', dirs : prebuild_libraries), + include_directories : include_directories(include_base / 'system/logging/liblog/include_vndk')) +meson.override_dependency('liblog', liblog_dep) + +libutils_dep = declare_dependency( + dependencies : [ + cxx.find_library('utils', dirs : prebuild_libraries), + liblog_dep, + ], + include_directories : include_directories(include_base / 'system/core/libutils/include')) +meson.override_dependency('libutils', libutils_dep) + +libui_dep = declare_dependency( + dependencies : [ + cxx.find_library('ui', dirs : prebuild_libraries), + libutils_dep, + ], + include_directories : include_directories(include_base / 'frameworks/native/libs/ui/include_vndk')) +meson.override_dependency('libui', libui_dep) diff --git a/subprojects/vndk.wrap b/subprojects/vndk.wrap index 70002ddc..b7a0d3f0 100644 --- a/subprojects/vndk.wrap +++ b/subprojects/vndk.wrap @@ -9,4 +9,4 @@ depth = 1 patch_directory = vndk [provide] -dependency_names = libhardware +dependency_names = libhardware, libui -- cgit v1.2.1