summaryrefslogtreecommitdiff
path: root/src/android/mm/cros_frame_buffer_allocator.cpp
diff options
context:
space:
mode:
authorHirokazu Honda <hiroh@chromium.org>2021-11-24 03:39:47 +0900
committerJacopo Mondi <jacopo@jmondi.org>2021-12-06 17:41:45 +0100
commitc58662c5770e4c2b4446318295055fcbc04c1824 (patch)
tree1cd386867a7f825cba50f95f4f52239ebd2b6638 /src/android/mm/cros_frame_buffer_allocator.cpp
parent99bb610fd1b270f126a6b35c0231843973d8f35b (diff)
android: Introduce PlatformFrameBufferAllocator
The existing FrameBufferAllocator is not allowed to allocate a new buffer while Camera is running. This introduces PlatformFrameBufferAllocator. It allocates FrameBuffer using cros::CameraBufferManager on ChromeOS and gralloc on non ChromeOS platform. The allocated FrameBuffer owns the underlying buffer but must be destroyed before PlatformFrameBufferAllocator is destroyed. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'src/android/mm/cros_frame_buffer_allocator.cpp')
-rw-r--r--src/android/mm/cros_frame_buffer_allocator.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/android/mm/cros_frame_buffer_allocator.cpp b/src/android/mm/cros_frame_buffer_allocator.cpp
new file mode 100644
index 00000000..52e8c180
--- /dev/null
+++ b/src/android/mm/cros_frame_buffer_allocator.cpp
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * cros_frame_buffer.cpp - Allocate FrameBuffer for Chromium OS using
+ * CameraBufferManager
+ */
+
+#include <memory>
+#include <vector>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/shared_fd.h>
+
+#include "libcamera/internal/framebuffer.h"
+
+#include "../camera_device.h"
+#include "../frame_buffer_allocator.h"
+#include "cros-camera/camera_buffer_manager.h"
+
+using namespace libcamera;
+
+LOG_DECLARE_CATEGORY(HAL)
+
+namespace {
+class CrosFrameBufferData : public FrameBuffer::Private
+{
+ LIBCAMERA_DECLARE_PUBLIC(FrameBuffer)
+
+public:
+ CrosFrameBufferData(cros::ScopedBufferHandle scopedHandle)
+ : FrameBuffer::Private(), scopedHandle_(std::move(scopedHandle))
+ {
+ }
+
+private:
+ cros::ScopedBufferHandle scopedHandle_;
+};
+} /* namespace */
+
+class PlatformFrameBufferAllocator::Private : public Extensible::Private
+{
+ LIBCAMERA_DECLARE_PUBLIC(PlatformFrameBufferAllocator)
+
+public:
+ Private([[maybe_unused]] CameraDevice *const cameraDevice)
+ {
+ }
+
+ std::unique_ptr<libcamera::FrameBuffer>
+ allocate(int halPixelFormat, const libcamera::Size &size, uint32_t usage);
+};
+
+std::unique_ptr<libcamera::FrameBuffer>
+PlatformFrameBufferAllocator::Private::allocate(int halPixelFormat,
+ const libcamera::Size &size,
+ uint32_t usage)
+{
+ cros::ScopedBufferHandle scopedHandle =
+ cros::CameraBufferManager::AllocateScopedBuffer(
+ size.width, size.height, halPixelFormat, usage);
+ if (!scopedHandle) {
+ LOG(HAL, Error) << "Failed to allocate buffer handle";
+ return nullptr;
+ }
+
+ buffer_handle_t handle = *scopedHandle;
+ SharedFD fd{ handle->data[0] };
+ if (!fd.isValid()) {
+ LOG(HAL, Fatal) << "Invalid fd";
+ return nullptr;
+ }
+
+ /* This code assumes all the planes are located in the same buffer. */
+ const size_t numPlanes = cros::CameraBufferManager::GetNumPlanes(handle);
+ std::vector<FrameBuffer::Plane> planes(numPlanes);
+ for (auto [i, plane] : utils::enumerate(planes)) {
+ plane.fd = fd;
+ plane.offset = cros::CameraBufferManager::GetPlaneOffset(handle, i);
+ plane.length = cros::CameraBufferManager::GetPlaneSize(handle, i);
+ }
+
+ return std::make_unique<FrameBuffer>(
+ std::make_unique<CrosFrameBufferData>(std::move(scopedHandle)),
+ planes);
+}
+
+PUBLIC_FRAME_BUFFER_ALLOCATOR_IMPLEMENTATION