/*
 * Copyright 2017 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef CAMERA_INCLUDE_CROS_CAMERA_CAMERA_BUFFER_MANAGER_H_
#define CAMERA_INCLUDE_CROS_CAMERA_CAMERA_BUFFER_MANAGER_H_

#include <array>
#include <cstdint>
#include <memory>

#include <cutils/native_handle.h>
#include <sys/types.h>
#include <system/graphics.h>

#include "cros-camera/export.h"

// A V4L2 extension format which represents 32bit RGBX-8-8-8-8 format. This
// corresponds to DRM_FORMAT_XBGR8888 which is used as the underlying format for
// the HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINEND format on all CrOS boards.
#define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4')

// A private gralloc usage flag to force allocation of YUV420 buffer.  This
// usage flag is only valid when allocating HAL_PIXEL_FORMAT_YCbCr_420_888
// flexible YUV buffers.
const uint32_t GRALLOC_USAGE_FORCE_I420 = 0x10000000U;

namespace cros {

class GbmDevice;

// RAII class for handling the CPU memory mapping of a camera buffer.  All the
// planes of the camera buffer is mapped when the ScopedMapping is constructed,
// and the address and size of each mapped plane can be accessed through
// ScopedMapping::plane().
class CROS_CAMERA_EXPORT ScopedMapping {
 public:
  struct Plane {
    // The address pointing to the start of the plane.
    uint8_t* addr = nullptr;

    // The byte stride of the plane.
    size_t stride = 0;

    // The size of the mapped memory region of the plane.
    size_t size = 0;
  };

  explicit ScopedMapping(buffer_handle_t buffer);
  ~ScopedMapping();
  ScopedMapping(const ScopedMapping& other) = delete;
  ScopedMapping& operator=(const ScopedMapping& other) = delete;
  ScopedMapping(ScopedMapping&& other);
  ScopedMapping& operator=(ScopedMapping&& other);

  uint32_t width() const;
  uint32_t height() const;
  uint32_t drm_format() const;
  uint32_t v4l2_format() const;
  uint32_t hal_pixel_format() const;
  uint32_t num_planes() const;
  Plane plane(int plane) const;
  bool is_valid() const;

 private:
  static constexpr size_t kMaxPlanes = 4;
  void Invalidate();

  std::array<Plane, kMaxPlanes> planes_;
  buffer_handle_t buf_ = nullptr;
};

// Generic camera buffer manager.  The class is for a camera HAL to map and
// unmap the buffer handles received in camera3_stream_buffer_t.
//
// The class is thread-safe.
//
// Example usage:
//
//  #include <cros-camera/camera_buffer_manager.h>
//  CameraBufferManager* manager = CameraBufferManager::GetInstance();
//  if (!manager) {
//    /* Error handling */
//  }
//
//  /* Register and use a buffer received from IPC */
//
//  manager->Register(buffer_handle);
//  void* addr;
//  manager->Lock(buffer_handle, ..., &addr);
//  /* Access the buffer mapped to |addr| */
//  manager->Unlock(buffer_handle);
//  manager->Deregister(buffer_handle);
//
//  One can also allocate buffers directly from the camera buffer manager:
//
//  /* Allocate locally and use a buffer */
//
//  buffer_handle_t buffer_handle;
//  uint32_t stride;
//  manager->Allocate(..., &buffer_handle, &stride);
//  void* addr;
//  manager->Lock(buffer_handle, ..., &addr);
//  /* Access the buffer mapped to |addr| */
//  manager->Unlock(buffer_handle);
//  manager->Free(buffer_handle);

struct CROS_CAMERA_EXPORT BufferHandleDeleter {
  void operator()(buffer_handle_t* handle);
};

using ScopedBufferHandle =
    std::unique_ptr<buffer_handle_t, BufferHandleDeleter>;

class CROS_CAMERA_EXPORT CameraBufferManager {
 public:
  // Gets the singleton instance.  Returns nullptr if any error occurrs during
  // instance creation.
  static CameraBufferManager* GetInstance();

  virtual ~CameraBufferManager() {}

  // Allocates a buffer for a frame.
  //
  // Args:
  //    |width|: The width of the frame.
  //    |height|: The height of the frame.
  //    |format|: The HAL pixel format of the frame.
  //    |usage|: The gralloc usage of the buffer.
  //    |out_buffer|: The handle to the allocated buffer.
  //    |out_stride|: The stride of the allocated buffer. |out_stride| is 0 for
  //                  YUV buffers.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Allocate(size_t width,
                       size_t height,
                       uint32_t format,
                       uint32_t usage,
                       buffer_handle_t* out_buffer,
                       uint32_t* out_stride) = 0;

  // Same as above, but returns a ScopedBufferHandle that deallocates the
  // allocated buffer automatically.
  //
  // Args:
  //    |width|: The width of the frame.
  //    |height|: The height of the frame.
  //    |format|: The HAL pixel format of the frame.
  //    |usage|: The gralloc usage of the buffer.
  //
  // Returns:
  //    A ScopedBufferHandle with valid buffer handle on success, or a
  //    ScopedBufferHandle with nullptr on error.
  static ScopedBufferHandle AllocateScopedBuffer(size_t width,
                                                 size_t height,
                                                 uint32_t format,
                                                 uint32_t usage);

  // Frees |buffer| allocated with CameraBufferManager::Allocate().
  //
  // Args:
  //    |buffer|: The buffer to free.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Free(buffer_handle_t buffer) = 0;

  // This method is analogous to the register() function in Android gralloc
  // module.  This method needs to be called for buffers that are not allocated
  // with Allocate() before |buffer| can be mapped.
  //
  // Args:
  //    |buffer|: The buffer handle to register.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Register(buffer_handle_t buffer) = 0;

  // This method is analogous to the unregister() function in Android gralloc
  // module.  After |buffer| is deregistered, calling Lock(), LockYCbCr(), or
  // Unlock() on |buffer| will fail.
  //
  // Args:
  //    |buffer|: The buffer handle to deregister.
  //
  // Returns:
  //    0 on success; corresponding error code on failure.
  virtual int Deregister(buffer_handle_t buffer) = 0;

  // This method is analogous to the lock() function in Android gralloc module.
  // Here the buffer handle is mapped with the given args.
  //
  // This method always maps the entire buffer and |x|, |y|, |width|, |height|
  // do not affect |out_addr|.
  //
  // Args:
  //    |buffer|: The buffer handle to map.
  //    |flags|:  Currently omitted and is reserved for future use.
  //    |x|: Unused and has no effect.
  //    |y|: Unused and has no effect.
  //    |width|: Unused and has no effect.
  //    |height|: Unused and has no effect.
  //    |out_addr|: The mapped address pointing to the start of the buffer.
  //
  // Returns:
  //    0 on success with |out_addr| set with the mapped address;
  //    -EINVAL on invalid buffer handle or invalid buffer format.
  virtual int Lock(buffer_handle_t buffer,
                   uint32_t flags,
                   uint32_t x,
                   uint32_t y,
                   uint32_t width,
                   uint32_t height,
                   void** out_addr) = 0;

  // This method is analogous to the lock_ycbcr() function in Android gralloc
  // module.  Here all the physical planes of the buffer handle are mapped with
  // the given args.
  //
  // This method always maps the entire buffer and |x|, |y|, |width|, |height|
  // do not affect |out_ycbcr|.
  //
  // Args:
  //    |buffer|: The buffer handle to map.
  //    |flags|:  Currently omitted and is reserved for future use.
  //    |x|: Unused and has no effect.
  //    |y|: Unused and has no effect.
  //    |width|: Unused and has no effect.
  //    |height|: Unused and has no effect.
  //    |out_ycbcr|: The mapped addresses, plane strides and chroma offset.
  //        - |out_ycbcr.y| stores the mapped address to the start of the
  //          Y-plane.
  //        - |out_ycbcr.cb| stores the mapped address to the start of the
  //          Cb-plane.
  //        - |out_ycbcr.cr| stores the mapped address to the start of the
  //          Cr-plane.
  //        - |out_ycbcr.ystride| stores the stride of the Y-plane.
  //        - |out_ycbcr.cstride| stores the stride of the chroma planes.
  //        - |out_ycbcr.chroma_step| stores the distance between two adjacent
  //          pixels on the chroma plane. The value is 1 for normal planar
  //          formats, and 2 for semi-planar formats.
  //
  // Returns:
  //    0 on success with |out_ycbcr.y| set with the mapped buffer info;
  //    -EINVAL on invalid buffer handle or invalid buffer format.
  virtual int LockYCbCr(buffer_handle_t buffer,
                        uint32_t flags,
                        uint32_t x,
                        uint32_t y,
                        uint32_t width,
                        uint32_t height,
                        struct android_ycbcr* out_ycbcr) = 0;

  // This method is analogous to the unlock() function in Android gralloc
  // module.  Here the buffer is simply unmapped.
  //
  // Args:
  //    |buffer|: The buffer handle to unmap.
  //
  // Returns:
  //    0 on success; -EINVAL on invalid buffer handle.
  virtual int Unlock(buffer_handle_t buffer) = 0;

  // Resolves the HAL pixel format |hal_format| to the actual DRM format, based
  // on the gralloc usage flags set in |usage|.
  //
  // Args:
  //    |hal_format|: The HAL pixel format to query.
  //    |usage|: The gralloc usage of the buffer.
  //
  // Returns:
  //    The corresponding DRM format; 0 if no DRM format could be resolved to.
  virtual uint32_t ResolveDrmFormat(uint32_t hal_format, uint32_t usage) = 0;

  // Checks if |buffer| is a valid camera buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to be verified.
  //
  // Returns:
  //    true if a buffer is valid, or false otherwise.
  static bool IsValidBuffer(buffer_handle_t buffer);

  // Get the width of the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The width; 0 if |buffer| is invalid.
  static uint32_t GetWidth(buffer_handle_t buffer);

  // Get the height of the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The height; 0 if |buffer| is invalid.
  static uint32_t GetHeight(buffer_handle_t buffer);

  // Get the number of physical planes associated with |buffer|.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    Number of planes on success; 0 if |buffer| is invalid or unrecognized
  //    pixel format.
  static uint32_t GetNumPlanes(buffer_handle_t buffer);

  // Gets the V4L2 pixel format for the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The V4L2 pixel format; 0 on error.
  static uint32_t GetV4L2PixelFormat(buffer_handle_t buffer);

  // Gets the stride of the specified plane.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //    |plane|: The plane to query.
  //
  // Returns:
  //    The stride of the specified plane; 0 on error.
  static size_t GetPlaneStride(buffer_handle_t buffer, size_t plane);

  // Gets the size of the specified plane.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //    |plane|: The plane to query.
  //
  // Returns:
  //    The size of the specified plane; 0 on error.
  static size_t GetPlaneSize(buffer_handle_t buffer, size_t plane);

  // Gets the offset of the specified plane.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //    |plane|: The plane to query.
  //
  // Returns:
  //    The offset of the specified plane; -1 on error.
  static off_t GetPlaneOffset(buffer_handle_t buffer, size_t plane);

  // Gets the plane fd of the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The plane fd; -1 on error.
  static int GetPlaneFd(buffer_handle_t buffer, size_t plane);

  // Gets the Android HAL pixel format of the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The HAL pixel format as defined in Android's system/graphics.h header;
  //    0 on error.
  static uint32_t GetHalPixelFormat(buffer_handle_t buffer);

  // Gets the DRM pixel format of the buffer handle.
  //
  // Args:
  //    |buffer|: The buffer handle to query.
  //
  // Returns:
  //    The DRM pixel format as defined in drm_fourcc.h header; 0 on error.
  static uint32_t GetDrmPixelFormat(buffer_handle_t buffer);
};

}  // namespace cros

#endif  // CAMERA_INCLUDE_CROS_CAMERA_CAMERA_BUFFER_MANAGER_H_
