/*
 * Copyright (C) 2013-2018 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _CAMERA3_HAL_CAMERA_BUFFER_H_
#define _CAMERA3_HAL_CAMERA_BUFFER_H_

#include <memory>
#include <utils/Errors.h>
#include <hardware/camera3.h>
#include "base/macros.h"
#include <cros-camera/camera_buffer_manager.h>

namespace cros {
namespace intel {
class CameraStream;

/**
 * \class CameraBuffer
 *
 * This class is the buffer abstraction in the HAL. It can store buffers
 * provided by the framework or buffers allocated by the HAL.
 * Allocation in the HAL can be done via gralloc or malloc.
 */
class CameraBuffer {
public:
    enum BufferType {
        BUF_TYPE_HANDLE,
        BUF_TYPE_MALLOC,
    };

public:
    /**
     * default constructor
     * Used for buffers coming from the framework. The wrapper is initialized
     * using the method init
     */
    CameraBuffer();

    /**
     * constructor for the HAL-allocated buffer
     * These are used via the utility methods in the MemoryUtils namespace
     */
    CameraBuffer(int w, int h, int s, int v4l2fmt, void* usrPtr, int cameraId, int dataSizeOverride = 0);

    /**
     * no need to delete a buffer since it is RefBase'd. Buffer will be deleted
     * when no reference to it exist.
     */
    ~CameraBuffer();

    /**
     * initialization for the wrapper around the framework buffers
     */
    status_t init(const camera3_stream_buffer *aBuffer, int cameraId);

    /**
     * initialization for the fake framework buffer (allocated by the HAL)
     */
    status_t init(int width, int height, int format, buffer_handle_t buffer, int cameraId);

    /**
     * deinitialization for the wrapper around the framework buffers
     */
    status_t deinit();

    void* data() {return mDataPtr;}

    status_t lock();
    status_t unlock();

    bool isLocked() const {return mLocked;}
    buffer_handle_t * getBufferHandle() {return &mHandle;}
    status_t waitOnAcquireFence();

    void dumpImage(const int type, const char *name);
    CameraStream * getOwner() const {return mOwner;}
    int width() {return mWidth;}
    int height() {return mHeight;}
    int stride() {return mStride;}
    unsigned int size() {return mSize;}
    int format() {return mFormat;}
    int v4l2Fmt() {return mV4L2Fmt;}
    void setRequestId(int requestId) {mRequestID = requestId;}
    int requestId() {return mRequestID;}
    status_t getFence(camera3_stream_buffer* buf);
    int dmaBufFd() {return mType == BUF_TYPE_HANDLE ? mHandle->data[0] : mDmaBufFd;}
    int status() {return mUserBuffer.status;}

private:
    DISALLOW_COPY_AND_ASSIGN(CameraBuffer);

    status_t registerBuffer();
    status_t deregisterBuffer();
    status_t lock_();

private:
    camera3_stream_buffer_t mUserBuffer; /*!< Original structure passed by request */
    int             mWidth;
    int             mHeight;
    unsigned int    mSize;           /*!< size in bytes, this is filled when we
                                           lock the buffer */
    int             mFormat;         /*!<  HAL PIXEL fmt */
    int             mV4L2Fmt;        /*!< V4L2 fourcc format code */
    int             mStride;
    bool            mInit;           /*!< Boolean to check the integrity of the
                                          buffer when it is created*/
    bool            mLocked;         /*!< Use to track the lock status */
    bool            mRegistered;     /*!< Use to track the buffer register status */

    BufferType mType;
    cros::CameraBufferManager* mGbmBufferManager;
    buffer_handle_t mHandle;
    buffer_handle_t* mHandlePtr;
    CameraStream *mOwner;             /*!< Stream this buffer belongs to */
    void*         mDataPtr;           /*!< if locked, here is the vaddr */
    int           mRequestID;         /*!< this is filled by hw streams after
                                          calling putframe */
    int mCameraId;
    int mDmaBufFd;                    /*!< file descriptor for dmabuf */
};

namespace MemoryUtils {
std::shared_ptr<CameraBuffer>
allocateHeapBuffer(int w, int h, int s, int v4l2Fmt, int cameraId, int dataSizeOverride = 0);
std::shared_ptr<CameraBuffer>
allocateHandleBuffer(int w, int h, int gfxFmt, int usage, int cameraId);
};

} /* namespace intel */
} /* namespace cros */

#endif // _CAMERA3_HAL_CAMERA_BUFFER_H_
