summaryrefslogtreecommitdiff
path: root/src/android/mm/cros_frame_buffer_allocator.cpp
diff options
context:
space:
mode:
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