////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camximagebufferinterface.h
///
/// @brief Camera image buffer and manager interface definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXIMAGEBUFFERINTERFACE_H
#define CAMXIMAGEBUFFERINTERFACE_H

#include "camxcsl.h"
#include "camxformats.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Forward Declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class  IImageBufferManager;
struct BufferManagerCreateData;
struct ImageFormat;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Type definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef VOID* MemPoolBufMgrHandle;  ///< Unique MemPoolBufMgr handle associated with each client Buffer Manager

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond SystemEventHandler @endcond
///
/// @brief Raise system event for a specific node.
///
/// @param[in] pNode          Node pointer
/// @param[in] errorCode      Node specific extended error code
/// @param[in] isDumpOnly     Node to decide on dump only or recovery path
/// @param[in] forceSigAbort  Flag to indicate if node wants to force a sigabort during fatal error
///
/// @return None
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef VOID (*SystemEventHandler)(
    VOID*         pNode,
    CamxResultExt errorCode,
    BOOL          isDumpOnly,
    BOOL          forceSigAbort);

/// @brief Bufferproperties structure that is initialized by looking at the corresponding XML structure
struct BufferProperties
{
    ImageFormat   imageFormat;                              ///< Buffer format info
    UINT32        numOfSupportedFormats;                    ///< Number of supported formats
    Format        supportedFormats[MaxNumSupportedFormats]; ///< Supported formats
    UINT          immediateAllocImageBuffers;               ///< Initial number of image buffers to be allocated
    UINT          maxImageBuffers;                          ///< Maximum number of image buffers can be allocated
    UINT32        memFlags;                                 ///< Memory flags
    CSLBufferHeap bufferHeap;                               ///< Buffer heap
    UINT64        producerFlags;                            ///< Buffer producer gralloc flags
    UINT64        consumerFlags;                            ///< Buffer consumer gralloc flags
    UINT32        grallocFormat;                            ///< Buffer gralloc format. This property
                                                            ///  is not needed if buffer will be allocated through CSL
};

/// @brief  Buffer manager types. This enum describes whether it is Camx internal or Chi buffer manager.
enum class BufferManagerType
{
    CamxBufferManager,  ///< Buffer manager that's created internally in camx driver
    ChiBufferManager,   ///< Buffer manager that's created in chi usecases through bufferManagerOps
};

/// @brief LinkBufferManagerProperties structure that is populated by looking at the pipeline information
struct LinkBufferManagerProperties
{
    VOID*   pNode;                          ///< Node to which the Buffer Manager belongs to
    BOOL    isFromIFENode;                  ///< Whether this link Buffer Manager is from IFE node
    BOOL    isPartOfRealTimePipeline;       ///< Whether this link Buffer Manager is part of a real time pipeline
    BOOL    isPartOfPreviewVideoPipeline;   ///< Whether this link Buffer Manager is part of a real time pipeline
    BOOL    isPartOfSnapshotPipeline;       ///< Whether this link Buffer Manager is part of a snapshot pipeline
};

/// @brief Buffer manager create data.
struct BufferManagerCreateData
{
    BufferProperties            bufferProperties;                  ///< Buffer properties
    INT32                       deviceIndices[CamxMaxDeviceIndex]; ///< Pointer to array of device indices that may
                                                                   ///  access this buffer
    UINT                        deviceCount;                       ///< The number of valid entries in the pDeviceIndices array
    BOOL                        allocateBufferMemory;              ///< Boolean indicating whether buffer memory
                                                                   ///  should be allocated
    UINT                        numBatchedFrames;                  ///< Greater than 1 for a link that has batch mode enabled,
                                                                   ///  otherwise it MUST be set to 1
    UINT                        immediateAllocBufferCount;         ///< Number of buffers to be allocated immediately
    UINT                        maxBufferCount;                    ///< Maximum number of buffers to be allocated
    BOOL                        bNeedDedicatedBuffers;             ///< Whether this Buffer Manager needs dedicated buffers
    BOOL                        bEnableLateBinding;                ///< Whether to enable late binding of backing buffers to
                                                                   ///  ImageBuffer holder. Used only when allocateBufferMemory
                                                                   ///  is TRUE
    BOOL                        bDisableSelfShrinking;             ///< Whether to explicitly disable self shrinking for the
                                                                   ///  buffers allocated for this ImageBufferManager
    BOOL                        bObeyImmediateCount;               ///< Whether to obey immediate count coming in BufferManager
                                                                   ///  create data. If true, self tune wont happen for this
    BufferManagerType           bufferManagerType;                 ///< The type indicating whether it is camx or chi
                                                                   ///  buffer manager
    SystemEventHandler          systemEventHandler;                ///< System event handler
    LinkBufferManagerProperties linkProperties;                    ///< Link properties
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Base Class that needs to be derived by ImageBuffer
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class IImageBuffer
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Initialize
    ///
    /// @brief  Function for initializing IImageBuffer object
    ///
    /// @param  pBufferMgrName          Pointer to client Buffer Manager name. ImageBuffer class saves this pointer for future
    ///                                 and expects this memory to be valid over the lifetime of this Buffer Manager
    /// @param  pCreateData             Pointer to client Buffer Manager create data. ImageBuffer class saves this pointer
    ///                                 for future reference and expects this memory to be valid over the lifetime of this
    ///                                 Buffer Manager and is not changed.
    /// @param  pCurrentFormat          Current Image Format for this ImageBuffer. This is used to import csl buffer info
    /// @param  pImageBufferManagerIntf Buffer manager that allocated the buffer (optional parameter which should be set
    ///                                 to NULL if no buffer manager is required to be specified)
    /// @param  hMemPoolBufMgrHandle    Memory Pool Buffer Manager handle using which this ImageBuffer can get a buffer
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Initialize(
        const CHAR*                     pBufferMgrName,
        const BufferManagerCreateData*  pCreateData,
        const ImageFormat*              pCurrentFormat,
        IImageBufferManager*            pImageBufferManagerIntf,
        MemPoolBufMgrHandle             hMemPoolBufMgrHandle) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetFormat
    ///
    /// @brief  Get the format of the buffer
    ///
    /// @param  internalFormat BOOL flag to switch using ubwcp alternate format for calc
    ///
    /// @return The image format. Will return NULL if the image buffer is not populated.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // NOWHINE CP021: used default arguments for non-virtual and private methods
    virtual const ImageFormat* GetFormat(
        BOOL internalFormat = FALSE) const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetCSLBufferInfo
    ///
    /// @brief  Retrieve the gralloc buffer handle
    ///
    /// @return Return the gralloc buffer handle
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual const CSLBufferInfo* GetCSLBufferInfo() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetFileDescriptor
    ///
    /// @brief  Get the fileDescriptor for the image.
    ///
    /// @return File Descriptor.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual INT GetFileDescriptor() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetPlaneVirtualAddr
    ///
    /// @brief  Get the virtual address of a plane in the image buffer.
    ///
    /// @param  batchFrameIndex  If the imagebuffer is batched, then we set this to the frame index within the batch
    /// @param  planeIndex       The plane to get.
    /// @param  isInternalFormat BOOL flag to switch using ubwcp alternate format for calc
    ///
    /// @return The virtual address for the plane. Will return NULL if the image buffer is not populated or the buffer is not
    ///         mapped into the UMD.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // NOWHINE CP021: used default arguments for non-virtual and private methods
    virtual BYTE* GetPlaneVirtualAddr(
        UINT batchFrameIndex,
        UINT planeIndex,
        BOOL isInternalFormat = FALSE
        ) const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetNumberOfPlanes
    ///
    /// @brief  Get the number of planes for the buffer
    ///
    /// @param  internalFormat BOOL flag to switch using ubwcp alternate format for calc
    ///
    /// @return The number of planes.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // NOWHINE CP021: used default arguments for non-virtual and private methods
    virtual UINT GetNumberOfPlanes(
        BOOL internalFormat = FALSE) const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetNumFramesInBatch
    ///
    /// @brief  Retrieve the total frame numbers in one batch
    ///
    /// @return Return the number of frames in one batch
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT GetNumFramesInBatch() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetPlaneCSLMemHandle
    ///
    /// @brief  Get the CSL Buffer information for a plane in the image buffer.
    ///
    /// @param  batchFrameIndex If the imagebuffer is batched, then we set this to the frame index within the batch
    /// @param  planeIndex      The plane to get.
    /// @param  phMemHandle     CSL memory handle out parameter.
    /// @param  pOffset         Output parameter. Offset of plane within the memory referred to by phMemHandle.
    /// @param  pMetadataSize   Output parameter. Metadatasize of the plane. For linear format Meta Size would be 0.
    /// @param  isInternalFmt   Flag indicating use of alternate ubwcp Format
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // NOWHINE CP021: used default arguments for non-virtual and private methods
    virtual CamxResult GetPlaneCSLMemHandle(
        UINT            batchFrameIndex,
        UINT            planeIndex,
        CSLMemHandle*   phMemHandle,
        SIZE_T*         pOffset,
        SIZE_T*         pMetadataSize,
        BOOL            isInternalFmt = FALSE
        ) const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetCPUAddress
    ///
    /// @brief  Retrieve the base virtual address for the image buffer
    ///
    /// @return Const byte pointer
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual const BYTE* GetCPUAddress() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsBatchImageFormat
    ///
    /// @brief  If the image is batch format, which can hold multiple frames
    ///
    /// @return Return TRUE if the image is batch format
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual BOOL IsBatchImageFormat() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ReleaseBufferManagerImageReference
    ///
    /// @brief  Release a reference to this image buffer via ImageBufferManager.
    ///
    /// @return The updated reference count.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT ReleaseBufferManagerImageReference() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// HasBackingBuffer
    ///
    /// @brief  Check whether the Image buffer is valid, having been backed by memory.
    ///
    /// @return TRUE if the ImageBuffer is valid and backed by memory, FALSE otherwise.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual BOOL HasBackingBuffer() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Release
    ///
    /// @brief  Release any allocated memory for this device and all references to underlying memory.
    ///
    /// @param  isForced               force to release the image buffer
    /// @param  isMPMImmediateRelease  immediately release mempool buffer acquired by image buffer
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // NOWHINE CP021: Default arguments added
    virtual VOID Release(
        BOOL isForced,
        BOOL isMPMImmediateRelease = FALSE) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetPlaneSize
    ///
    /// @brief  Get the size of a plane in the buffer in bytes.
    ///
    /// @param  planeIndex     The plane to get.
    /// @param  internalFormat BOOL flag to switch using ubwcp alternate format for calc
    ///
    /// @return The number of bytes in the plane. Will return 0 if the image buffer is not populated.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // NOWHINE CP021: used default arguments for non-virtual and private methods
    virtual SIZE_T GetPlaneSize(
        UINT planeIndex,
        BOOL internalFormat = FALSE) const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpImageBuffers
    ///
    /// @brief  Helper method to dump image buffers
    ///
    /// @param  pPipelineName         Pipeline name
    /// @param  pNodeName             Node name
    /// @param  instanceID            Instance id
    /// @param  requestId             Request id
    /// @param  batchId               Batch Id
    /// @param  portId                port id of the image buffer
    /// @param  pDescriptionString    port id of the image buffer
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID DumpImageBuffers(
        const CHAR*     pPipelineName,
        const CHAR*     pNodeName,
        UINT32          instanceID,
        UINT64          requestId,
        UINT            batchId,
        UINT            portId,
        const CHAR*     pDescriptionString) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsCSLBuffer
    ///
    /// @brief  Check if the image buffer is allocated through CSL
    ///
    /// @return Return true if it's CSL buffer
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual BOOL IsCSLBuffer() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsGrallocBuffer
    ///
    /// @brief  Check if the image buffer is allocated through gralloc
    ///
    /// @return Return true if it's gralloc buffer
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual BOOL IsGrallocBuffer() const = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetGrallocBufferHandle
    ///
    /// @brief  Retrieve the gralloc buffer handle
    ///
    /// @return Return the gralloc buffer handle
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual BufferHandle* GetGrallocBufferHandle() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CacheOps
    ///
    /// @brief  Clean and/or invalidate the cache for all memory associated with this image buffer.
    ///
    /// @param  invalidate  Invalidate the cache.
    /// @param  clean       Clean the cache.
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult CacheOps(
        BOOL invalidate,
        BOOL clean) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetReferenceCount
    ///
    /// @brief  Get the current reference count.
    ///
    /// @return The reference count.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT GetReferenceCount() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ReleaseImageReference
    ///
    /// @brief  Release a reference to this image buffer. Only ImageBufferManager should call this API
    ///         as buffers are all managed through buffer manager.
    ///
    /// @return The updated reference count.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT ReleaseImageReference() = 0;

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IImageBuffer
    ///
    /// @brief  Default Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    IImageBuffer() = default;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~IImageBuffer
    ///
    /// @brief  Virtual Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IImageBuffer() = default;

private:
    IImageBuffer(const IImageBuffer& rOther)            = delete; ///< Removed copy constructor
    IImageBuffer& operator=(const IImageBuffer& rOther) = delete; ///< Removed operator=
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief The IImageBufferManager manages a pool of homogeneous frame buffers
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CAMX_VISIBILITY_PUBLIC IImageBufferManager
{
public:

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Activate
    ///
    /// @brief  Activate this buffer manager. This gives a hint to manager underlying Image Buffer allocations
    ///
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Activate() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetImageBuffer
    ///
    /// @brief  Retrieve an available buffer from the buffer pool. Buffers are retrieved in FIFO order.
    ///
    /// @return Pointer to an ImageBuffer. If buffers are not allocated, not available, or some other error, NULL is returned.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual IImageBuffer* GetImageBuffer() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Deactivate
    ///
    /// @brief  Deactivate this Buffer Manager. This releases all or some buffers allocated by the buffer manager.
    ///
    /// @param  isPartialRelease   If TRUE, release buffers until m_immediateAllocBufferCount is reached; else release all
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Deactivate(
        BOOL isPartialRelease) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Destroy
    ///
    /// @brief  Destroy this image buffer manager.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID Destroy() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetMaxImageBufferCount
    ///
    /// @brief  Retrieve the maximum number of buffers to be allocated passed in the create data.
    ///
    /// @return the maximum number of buffers allowed to be created.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT GetMaxImageBufferCount() = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// DumpState
    ///
    /// @brief  Dumps snapshot of current state to a file
    ///
    /// @param  textLogFd   file descriptor for textual logging.
    /// @param  binaryLogFd file descriptor for binary logging.
    /// @param  indent      indent spaces.
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID DumpState(
        INT     textLogFd,
        UINT64  binaryLogFd,
        UINT32  indent) = 0;

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IImageBufferManager
    ///
    /// @brief  Default constuctor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    IImageBufferManager() = default;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~IImageBufferManager
    ///
    /// @brief  Virtual Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IImageBufferManager() = default;

private:
    IImageBufferManager(const IImageBufferManager& rOther)            = delete; ///< Removed copy constructor
    IImageBufferManager& operator=(const IImageBufferManager& rOther) = delete; ///< Removed operator=
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CreateImageBufferManager
///
/// @brief  This C Function will help to allocate Image Buf Mgr class.
///         This is mainly to decouple the dependency for the IImageBufferManager interface.
///
///
/// @param  pBufferManagerName       Name of the image buffer manager
/// @param  pCreateData              Buffer manager create data
/// @param  ppImageBufferManager     Pointer to Image Buffer Manager instance
///
/// @return None
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CAMX_VISIBILITY_PUBLIC CamxResult CreateImageBufferManager(
    const CHAR*              pBufferManagerName,
    BufferManagerCreateData* pCreateData,
    IImageBufferManager**    ppImageBufferManager);

CAMX_NAMESPACE_END

#endif // CAMXIMAGEBUFFERINTERFACE_H
