/*
 * Copyright 2016 The Android Open Source Project
 *
 * 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 ANDROID_SERVERS_CAMERA3_BUFFER_MANAGER_H
#define ANDROID_SERVERS_CAMERA3_BUFFER_MANAGER_H

#include <list>
#include <algorithm>
#include <ui/GraphicBuffer.h>
#include <utils/RefBase.h>
#include <utils/KeyedVector.h>
#include "Camera3OutputStream.h"

namespace android {

namespace camera3 {

struct StreamInfo;
class Camera3OutputStream;

/**
 * A class managing the graphic buffers that is used by camera output streams. It allocates and
 * hands out Gralloc buffers to the clients (e.g., Camera3OutputStream) based on the requests.
 * When clients request a buffer, buffer manager will pick a buffer if there are some already
 * allocated buffer available, will allocate a buffer otherwise. When there are too many allocated
 * buffer maintained by the buffer manager, it will dynamically deallocate some buffers that are
 * solely owned by this buffer manager.
 * In doing so, it reduces the memory footprint unless it is already minimal without impacting
 * performance.
 *
 */
class Camera3BufferManager: public virtual RefBase {
public:
    Camera3BufferManager(const sp<IGraphicBufferAlloc>& allocator = NULL);

    virtual ~Camera3BufferManager();

    /**
     * This method registers an output stream to this buffer manager by using the provided stream
     * information.
     *
     * The stream info includes the necessary information such as stream size, format, buffer count,
     * usage flags, etc. for the buffer manager to allocate and hand out buffers for this stream.
     *
     * It's illegal to call this method if the stream is not CONFIGURED yet, as some critical
     * stream properties (e.g., combined usage flags) are only available in this state. It is also
     * illegal to call this method with an invalid stream set ID (CAMERA3_STREAM_SET_ID_INVALID),
     * as the invalid stream set ID indicates that this stream doesn't intend to use buffer manager.
     *
     *
     * Once a stream is successfully registered to this buffer manager, the buffer manager takes
     * over the buffer allocation role and provides buffers to this stream via getBufferForStream().
     * The returned buffer can be sent to the camera HAL for image output, and then queued to the
     * ANativeWindow (Surface) for downstream consumer to acquire. Once the image buffer is released
     * by the consumer end point, the BufferQueueProducer callback onBufferReleased will call
     * returnBufferForStream() to return the free buffer to this buffer manager. If the stream
     * uses buffer manager to manage the stream buffers, it should disable the BufferQueue
     * allocation via IGraphicBufferProducer::allowAllocation(false).
     *
     * Registering an already registered stream has no effect.
     *
     * Return values:
     *
     *  OK:                Registration of the new stream was successful.
     *  BAD_VALUE:         This stream is not at CONFIGURED state, or the stream ID or stream set
     *                     ID are invalid, or attempting to register the same stream to multiple
     *                     stream sets, or other stream properties are invalid.
     *  INVALID_OPERATION: This buffer manager doesn't support buffer sharing across this stream
     *                     and other streams that were already registered with the same stream set
     *                     ID.
     */
    status_t registerStream(wp<Camera3OutputStream>& stream, const StreamInfo &streamInfo);

    /**
     * This method unregisters a stream from this buffer manager.
     *
     * After a stream is unregistered, further getBufferForStream() calls will fail for this stream.
     * After all streams for a given stream set are unregistered, all the buffers solely owned (for
     * this stream set) by this buffer manager will be freed; all buffers subsequently returned to
     * this buffer manager for this stream set will be freed immediately.
     *
     * Return values:
     *
     *  OK:        Removal of the a stream from this buffer manager was successful.
     *  BAD_VALUE: stream ID or stream set ID are invalid, or stream ID and stream set ID
     *             combination doesn't match what was registered, or this stream wasn't registered
     *             to this buffer manager before.
     */
    status_t unregisterStream(int streamId, int streamSetId);

    /**
     * This method obtains a buffer for a stream from this buffer manager.
     *
     * This method returns the first free buffer from the free buffer list (associated with this
     * stream set) if there is any. Otherwise, it will allocate a buffer for this stream, return
     * it and increment its count of handed-out buffers. When the total number of allocated buffers
     * is too high, it may deallocate the unused buffers to save memory footprint of this stream
     * set.
     *
     * After this call, the client takes over the ownership of this buffer if it is not freed.
     *
     * Return values:
     *
     *  OK:        Getting buffer for this stream was successful.
     *  ALREADY_EXISTS: Enough free buffers are already attached to this output buffer queue,
     *             user should just dequeue from the buffer queue.
     *  BAD_VALUE: stream ID or streamSetId are invalid, or stream ID and stream set ID
     *             combination doesn't match what was registered, or this stream wasn't registered
     *             to this buffer manager before.
     *  NO_MEMORY: Unable to allocate a buffer for this stream at this time.
     */
    status_t getBufferForStream(int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd);

    /**
     * This method notifies the manager that a buffer has been released by the consumer.
     *
     * The buffer is not returned to the buffer manager, but is available for the stream the buffer
     * is attached to for dequeuing.
     *
     * The notification lets the manager know how many buffers are directly available to the stream.
     *
     * If onBufferReleased is called for a given released buffer,
     * returnBufferForStream may not be called for the same buffer, until the
     * buffer has been reused. The manager will call detachBuffer on the stream
     * if it needs the released buffer otherwise.
     *
     * Return values:
     *
     *  OK:        Buffer release was processed succesfully
     *  BAD_VALUE: stream ID or streamSetId are invalid, or stream ID and stream set ID
     *             combination doesn't match what was registered, or this stream wasn't registered
     *             to this buffer manager before.
     */
    status_t onBufferReleased(int streamId, int streamSetId);

    /**
     * This method returns a buffer for a stream to this buffer manager.
     *
     * When a buffer is returned, it is treated as a free buffer and may either be reused for future
     * getBufferForStream() calls, or freed if there total number of outstanding allocated buffers
     * is too large. The latter only applies to the case where the buffer are physically shared
     * between streams in the same stream set. A physically shared buffer is the buffer that has one
     * physical back store but multiple handles. Multiple stream can access the same physical memory
     * with their own handles. Physically shared buffer can only be supported by Gralloc HAL V1.
     * See hardware/libhardware/include/hardware/gralloc1.h for more details.
     *
     *
     * This call takes the ownership of the returned buffer if it was allocated by this buffer
     * manager; clients should not use this buffer after this call. Attempting to access this buffer
     * after this call will have undefined behavior. Holding a reference to this buffer after this
     * call may cause memory leakage. If a BufferQueue is used to track the buffers handed out by
     * this buffer queue, it is recommended to call detachNextBuffer() from the buffer queue after
     * BufferQueueProducer onBufferReleased callback is fired, and return it to this buffer manager.
     *
     *  OK:        Buffer return for this stream was successful.
     *  BAD_VALUE: stream ID or streamSetId are invalid, or stream ID and stream set ID combination
     *             doesn't match what was registered, or this stream wasn't registered to this
     *             buffer manager before.
     */
    status_t returnBufferForStream(int streamId, int streamSetId, const sp<GraphicBuffer>& buffer,
            int fenceFd);

    /**
     * Dump the buffer manager statistics.
     */
    void     dump(int fd, const Vector<String16> &args) const;

private:
    /**
     * Lock to synchronize the access to the methods of this class.
     */
    mutable Mutex mLock;

    static const size_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;

    /**
     * mAllocator is the connection to SurfaceFlinger that is used to allocate new GraphicBuffer
     * objects.
     */
    sp<IGraphicBufferAlloc> mAllocator;

    struct GraphicBufferEntry {
        sp<GraphicBuffer> graphicBuffer;
        int fenceFd;
        GraphicBufferEntry(const sp<GraphicBuffer>& gb = 0, int fd = -1) :
            graphicBuffer(gb),
            fenceFd(fd) {}
    };

    /**
     * A buffer entry (indexed by stream ID) represents a single physically allocated buffer. For
     * Gralloc V0, since each physical buffer is associated with one stream, this is
     * a single entry map. For Gralloc V1, one physical buffer can be shared between different
     * streams in one stream set, so this entry may include multiple entries, where the different
     * graphic buffers have the same common Gralloc backing store.
     */
    typedef int StreamId;
    typedef KeyedVector<StreamId, GraphicBufferEntry> BufferEntry;

    typedef std::list<BufferEntry> BufferList;

    /**
     * Stream info map (indexed by stream ID) tracks all the streams registered to a particular
     * stream set.
     */
    typedef KeyedVector<StreamId, StreamInfo> InfoMap;

    /**
     * Stream set buffer count map (indexed by stream ID) tracks all buffer counts of the streams
     * registered to a particular stream set.
     */
    typedef KeyedVector<StreamId, size_t> BufferCountMap;

    /**
     * StreamSet keeps track of the stream info, free buffer list and hand-out buffer counts for
     * each stream set.
     */
    struct StreamSet {
        /**
         * Stream set buffer count water mark representing the max number of allocated buffers
         * (hand-out buffers + free buffers) count for each stream set. For a given stream set, when
         * getBufferForStream() is called on this buffer manager, if the total allocated buffer
         * count exceeds this water mark, the buffer manager will attempt to reduce it as follows:
         *
         * In getBufferForStream(), find a buffer associated with other streams (inside the same
         * stream set) on the free buffer list and free it. For Gralloc V1, can just free the top
         * of the free buffer list if the physical buffer sharing in this stream is supported.
         *
         * For a particular stream set, a larger allocatedBufferWaterMark increases the memory
         * footprint of the stream set, but reduces the chance that getBufferForStream() will have
         * to allocate a new buffer. We assume that the streams in one stream set are not streaming
         * simultaneously, the max allocated buffer count water mark for a stream set will the max
         * of all streams' total buffer counts. This will avoid new buffer allocation in steady
         * streaming state.
         *
         * This water mark can be dynamically changed, and will grow when the hand-out buffer count
         * of each stream increases, until it reaches the maxAllowedBufferCount.
         */
        size_t allocatedBufferWaterMark;

        /**
         * The max allowed buffer count for this stream set. It is the max of total number of
         * buffers for each stream. This is the upper bound of the allocatedBufferWaterMark.
         */
        size_t maxAllowedBufferCount;

        /**
         * The stream info for all streams in this set
         */
        InfoMap streamInfoMap;
        /**
         * The free buffer list for all the buffers belong to this set. The free buffers are
         * returned by the returnBufferForStream() call, and available for reuse.
         */
        BufferList freeBuffers;
        /**
         * The count of the buffers that were handed out to the streams of this set.
         */
        BufferCountMap handoutBufferCountMap;
        /**
         * The count of the buffers that are attached to the streams of this set.
         * An attached buffer may be free or handed out
         */
        BufferCountMap attachedBufferCountMap;

        StreamSet() {
            allocatedBufferWaterMark = 0;
            maxAllowedBufferCount = 0;
        }
    };

    /**
     * Stream set map managed by this buffer manager.
     */
    typedef int StreamSetId;
    KeyedVector<StreamSetId, StreamSet> mStreamSetMap;
    KeyedVector<StreamId, wp<Camera3OutputStream>> mStreamMap;

    // TODO: There is no easy way to query the Gralloc version in this code yet, we have different
    // code paths for different Gralloc versions, hardcode something here for now.
    const uint32_t mGrallocVersion = GRALLOC_DEVICE_API_VERSION_0_1;

    /**
     * Check if this stream was successfully registered already. This method needs to be called with
     * mLock held.
     */
    bool checkIfStreamRegisteredLocked(int streamId, int streamSetId) const;

    /**
     * Add a buffer entry to the BufferList. This method needs to be called with mLock held.
     */
    status_t addBufferToBufferListLocked(BufferList &bufList, const BufferEntry &buffer);

    /**
     * Remove all buffers from the BufferList.
     *
     * Note that this doesn't mean that the buffers are freed after this call. A buffer is freed
     * only if all other references to it are dropped.
     *
     * This method needs to be called with mLock held.
     */
    status_t removeBuffersFromBufferListLocked(BufferList &bufList, int streamId);

    /**
     * Get the first available buffer from the buffer list for this stream. The graphicBuffer inside
     * this entry will be NULL if there is no any GraphicBufferEntry found. After this call, the
     * GraphicBufferEntry will be removed from the BufferList if a GraphicBufferEntry is found.
     *
     * This method needs to be called with mLock held.
     *
     */
    GraphicBufferEntry getFirstBufferFromBufferListLocked(BufferList& buffers, int streamId);

    /**
     * Check if there is any buffer associated with this stream in the given buffer list.
     *
     * This method needs to be called with mLock held.
     *
     */
    bool inline hasBufferForStreamLocked(BufferList& buffers, int streamId);
};

} // namespace camera3
} // namespace android

#endif // ANDROID_SERVERS_CAMERA3_BUFFER_MANAGER_H
