/*
* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*    * Redistributions of source code must retain the above copyright
*      notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above
*      copyright notice, this list of conditions and the following
*      disclaimer in the documentation and/or other materials provided
*      with the distribution.
*    * Neither the name of The Linux Foundation. nor the names of its
*      contributors may be used to endorse or promote products derived
*      from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef OVERLAY_H
#define OVERLAY_H

#include "overlayUtils.h"
#include "mdp_version.h"
#include "utils/threads.h"

struct MetaData_t;

namespace overlay {
class GenericPipe;

class Overlay : utils::NoCopy {
public:
    enum { DMA_BLOCK_MODE, DMA_LINE_MODE };
    //Abstract Display types. Each backed by a LayerMixer,
    //represented by a fb node.
    //High res panels can be backed by 2 layer mixers and a single fb node.
    enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_WRITEBACK, DPY_UNUSED };
    enum { DPY_MAX = DPY_UNUSED };
    enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
    enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
    enum { MAX_FB_DEVICES = DPY_MAX };
    enum { FORMAT_YUV, FORMAT_RGB };

    struct PipeSpecs {
        PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
                dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT), numActiveDisplays(1) {}
        int formatClass;
        bool needsScaling;
        bool fb;
        int dpy;
        int mixer;
        int numActiveDisplays;
    };

    /* dtor close */
    ~Overlay();

    /* Marks the beginning of a drawing round, resets usage bits on pipes
     * Should be called when drawing begins before any pipe config is done.
     */
    void configBegin();

    /* Marks the end of config for this drawing round
     * Will do garbage collection of pipe objects and thus calling UNSETs,
     * closing FDs, removing rotator objects and memory, if allocated.
     * Should be called after all pipe configs are done.
     */
    void configDone();

    /* Get a pipe that supported the specified format class (yuv, rgb) and has
     * scaling capabilities.
     */
    utils::eDest getPipe(const PipeSpecs& pipeSpecs);
    /* Returns the eDest corresponding to an already allocated pipeid.
     * Useful for the reservation case, when libvpu reserves the pipe at its
     * end, and expect the overlay to allocate a given pipe for a layer.
     */
    utils::eDest reservePipe(int pipeid);
    /* getting dest for the given pipeid */
    utils::eDest getDest(int pipeid);
    /* getting overlay.pipeid for the given dest */
    int getPipeId(utils::eDest dest);

    void setSource(const utils::PipeArgs args, utils::eDest dest);
    void setCrop(const utils::Dim& d, utils::eDest dest);
    void setColor(const uint32_t color, utils::eDest dest);
    void setTransform(const int orientation, utils::eDest dest);
    void setPosition(const utils::Dim& dim, utils::eDest dest);
    void setVisualParams(const MetaData_t& data, utils::eDest dest);
    bool commit(utils::eDest dest);
    bool queueBuffer(int fd, uint32_t offset, utils::eDest dest);

    /* pipe reservation session is running */
    bool sessionInProgress(utils::eDest dest);
    /* pipe reservation session has ended*/
    bool isSessionEnded(utils::eDest dest);
    /* start session for the pipe reservation */
    void startSession(utils::eDest dest);
    /* end all started sesisons */
    void endAllSessions();
    /* Returns available ("unallocated") pipes for a display's mixer */
    int availablePipes(int dpy, int mixer);
    /* Returns available ("unallocated") pipes for a display */
    int availablePipes(int dpy);
    /* Returns available ("unallocated") pipe of given type for a display */
    int availablePipes(int dpy, utils::eMdpPipeType type);
    /* Returns if any of the requested pipe type is attached to any of the
     * displays
     */
    bool isPipeTypeAttached(utils::eMdpPipeType type);
    /* Compare pipe priorities and return
     * 1 if 1st pipe has a higher priority
     * 0 if both have the same priority
     *-1 if 2nd pipe has a higher priority
     */
    int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
    /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
     * to populate.
     */
    /* Returns if DMA pipe multiplexing is supported by the mdss driver */
    static bool isDMAMultiplexingSupported();
    /* Returns if UI scaling on external is supported on the targets */
    static bool isUIScalingOnExternalSupported();
    void getDump(char *buf, size_t len);
    /* Reset usage and allocation bits on all pipes for given display */
    void clear(int dpy);
    /* Validate the set of pipes for a display and set them in driver */
    bool validateAndSet(const int& dpy, const int& fbFd);

    /* Closes open pipes, called during startup */
    static int initOverlay();
    /* Returns the singleton instance of overlay */
    static Overlay* getInstance();
    static void setDMAMode(const int& mode);
    static int getDMAMode();
    /* Returns the framebuffer node backing up the display */
    static int getFbForDpy(const int& dpy);

    static bool displayCommit(const int& fd);
    /* Overloads display commit with ROI's of each halves.
     * Single interface panels will only update left ROI. */
    static bool displayCommit(const int& fd, const utils::Dim& lRoi,
                              const utils::Dim& rRoi);

private:
    /* Ctor setup */
    explicit Overlay();
    /*Validate index range, abort if invalid */
    void validate(int index);
    static void setDMAMultiplexingSupported();
    void dump() const;
    /* Returns an available pipe based on the type of pipe requested. When ANY
     * is requested, the first available VG or RGB is returned. If no pipe is
     * available for the display "dpy" then INV is returned. Note: If a pipe is
     * assigned to a certain display, then it cannot be assigned to another
     * display without being garbage-collected once. To add if a pipe is
     * asisgned to a mixer within a display it cannot be reused for another
     * mixer without being UNSET once*/
    utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
    /* Helpers that enfore target specific policies while returning pipes */
    utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
    utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
    utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs);

    /* Returns the handle to libscale.so's programScale function */
    static int (*getFnProgramScale())(struct mdp_overlay_list *);
    /* Creates a scalar object using libscale.so */
    static void initScalar();
    /* Destroys the scalar object using libscale.so */
    static void destroyScalar();
    /* Sets the pipe type RGB/VG/DMA*/
    void setPipeType(utils::eDest pipeIndex, const utils::eMdpPipeType pType);

    /* Just like a Facebook for pipes, but much less profile info */
    struct PipeBook {
        void init();
        void destroy();
        /* Check if pipe exists and return true, false otherwise */
        bool valid();

        /* Hardware pipe wrapper */
        GenericPipe *mPipe;
        /* Display using this pipe. Refer to enums above */
        int mDisplay;
        /* Mixer within a split display this pipe is attached to */
        int mMixer;

        /* operations on bitmap */
        static bool pipeUsageUnchanged();
        static void setUse(int index);
        static void resetUse(int index);
        static bool isUsed(int index);
        static bool isNotUsed(int index);
        static void save();

        static void setAllocation(int index);
        static void resetAllocation(int index);
        static bool isAllocated(int index);
        static bool isNotAllocated(int index);

        static utils::eMdpPipeType getPipeType(utils::eDest dest);
        static const char* getDestStr(utils::eDest dest);

        static int NUM_PIPES;
        static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX];
        /* Session for reserved pipes */
        enum Session {
            NONE,
            START,
            END
        };
        Session mSession;

    private:
        //usage tracks if a successful commit happened. So a pipe could be
        //allocated to a display, but it may not end up using it for various
        //reasons. If one display actually uses a pipe then it amy not be
        //used by another display, without an UNSET in between.
        static int sPipeUsageBitmap;
        static int sLastUsageBitmap;
        //Tracks which pipe objects are allocated. This does not imply that they
        //will actually be used. For example, a display might choose to acquire
        //3 pipe objects in one shot and proceed with config only if it gets all
        //3. The bitmap helps allocate different pipe objects on each request.
        static int sAllocatedBitmap;
    };

    PipeBook mPipeBook[utils::OV_INVALID]; //Used as max

    /* Dump string */
    char mDumpStr[1024];

    /* Singleton Instance*/
    static Overlay *sInstance;
    static int sDpyFbMap[DPY_MAX];
    static int sDMAMode;
    static bool sDMAMultiplexingSupported;
    static void *sLibScaleHandle;
    static int (*sFnProgramScale)(struct mdp_overlay_list *);

    friend class MdpCtrl;
};

inline void Overlay::validate(int index) {
    OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \
        "%s, Index out of bounds: %d", __FUNCTION__, index);
    OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s",
            PipeBook::getDestStr((utils::eDest)index));
}

inline int Overlay::availablePipes(int dpy, int mixer) {
    int avail = 0;
    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
        if( (mPipeBook[i].mDisplay == DPY_UNUSED ||
             mPipeBook[i].mDisplay == dpy) &&
            (mPipeBook[i].mMixer == MIXER_UNUSED ||
             mPipeBook[i].mMixer == mixer) &&
            PipeBook::isNotAllocated(i) &&
            !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE &&
              PipeBook::getPipeType((utils::eDest)i) ==
              utils::OV_MDP_PIPE_DMA)) {
            avail++;
        }
    }
    return avail;
}

inline int Overlay::availablePipes(int dpy) {
    int avail = 0;
    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
        if( (mPipeBook[i].mDisplay == DPY_UNUSED ||
             mPipeBook[i].mDisplay == dpy) &&
            PipeBook::isNotAllocated(i) &&
            !(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE &&
              PipeBook::getPipeType((utils::eDest)i) ==
              utils::OV_MDP_PIPE_DMA)) {
            avail++;
        }
    }
    return avail;
}

inline int Overlay::availablePipes(int dpy, utils::eMdpPipeType type) {
    int avail = 0;
    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
        if((mPipeBook[i].mDisplay == DPY_UNUSED ||
            mPipeBook[i].mDisplay == dpy) &&
            PipeBook::isNotAllocated(i) &&
            type == PipeBook::getPipeType((utils::eDest)i)) {
            avail++;
        }
    }
    return avail;
}

inline void Overlay::setDMAMode(const int& mode) {
    if(mode == DMA_LINE_MODE || mode == DMA_BLOCK_MODE)
        sDMAMode = mode;
}

inline void Overlay::setDMAMultiplexingSupported() {
    sDMAMultiplexingSupported = false;
    if(qdutils::MDPVersion::getInstance().is8x26())
        sDMAMultiplexingSupported = true;
}

inline bool Overlay::isDMAMultiplexingSupported() {
    return sDMAMultiplexingSupported;
}

inline bool Overlay::isUIScalingOnExternalSupported() {
    if(qdutils::MDPVersion::getInstance().is8x26() or
       qdutils::MDPVersion::getInstance().is8x16() or
       qdutils::MDPVersion::getInstance().is8x39()) {
        return false;
    }
    return true;
}

inline int Overlay::getDMAMode() {
    return sDMAMode;
}

inline int Overlay::getFbForDpy(const int& dpy) {
    OVASSERT(dpy >= 0 && dpy < DPY_MAX, "Invalid dpy %d", dpy);
    return sDpyFbMap[dpy];
}

inline int (*Overlay::getFnProgramScale())(struct mdp_overlay_list *) {
    return sFnProgramScale;
}

inline bool Overlay::PipeBook::valid() {
    return (mPipe != NULL);
}

inline bool Overlay::PipeBook::pipeUsageUnchanged() {
    return (sPipeUsageBitmap == sLastUsageBitmap);
}

inline void Overlay::PipeBook::setUse(int index) {
    sPipeUsageBitmap |= (1 << index);
}

inline void Overlay::PipeBook::resetUse(int index) {
    sPipeUsageBitmap &= ~(1 << index);
}

inline bool Overlay::PipeBook::isUsed(int index) {
    return sPipeUsageBitmap & (1 << index);
}

inline bool Overlay::PipeBook::isNotUsed(int index) {
    return !isUsed(index);
}

inline void Overlay::PipeBook::save() {
    sLastUsageBitmap = sPipeUsageBitmap;
}

inline void Overlay::PipeBook::setAllocation(int index) {
    sAllocatedBitmap |= (1 << index);
}

inline void Overlay::PipeBook::resetAllocation(int index) {
    sAllocatedBitmap &= ~(1 << index);
}

inline bool Overlay::PipeBook::isAllocated(int index) {
    return sAllocatedBitmap & (1 << index);
}

inline bool Overlay::PipeBook::isNotAllocated(int index) {
    return !isAllocated(index);
}

inline utils::eMdpPipeType Overlay::PipeBook::getPipeType(utils::eDest dest) {
    return pipeTypeLUT[(int)dest];
}

inline void Overlay::startSession(utils::eDest dest) {
    mPipeBook[(int)dest].mSession = PipeBook::START;
}

inline bool Overlay::sessionInProgress(utils::eDest dest) {
    return (mPipeBook[(int)dest].mSession == PipeBook::START);
}

inline bool Overlay::isSessionEnded(utils::eDest dest) {
    return (mPipeBook[(int)dest].mSession == PipeBook::END);
}

inline const char* Overlay::PipeBook::getDestStr(utils::eDest dest) {
    switch(getPipeType(dest)) {
        case utils::OV_MDP_PIPE_RGB: return "RGB";
        case utils::OV_MDP_PIPE_VG: return "VG";
        case utils::OV_MDP_PIPE_DMA: return "DMA";
        default: return "Invalid";
    }
    return "Invalid";
}

}; // overlay

#endif // OVERLAY_H
