/*
* 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"
#ifdef USES_POST_PROCESSING
#include "lib-postproc.h"
#endif

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 , FORMAT_NONE };

    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
     * true - A swap is needed to fix the priority.
     * false - Good, priority wise.
     */
    bool needsPrioritySwap(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);
    /* Logs pipe lifecycle events like set, unset, commit when enabled */
    static void debugPipeLifecycle(const bool& enable);
    /* Returns true if pipe life cycle logging is enabled */
    static bool isDebugPipeLifecycle();

private:
    /* Ctor setup */
    explicit Overlay();
    /*Validate index range, abort if invalid */
    void validate(int index);
    static void setDMAMultiplexingSupported();
    /* 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, const PipeSpecs& pipeSpecs);
    /* 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);
    utils::eDest getPipe_8994(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);

    /* Dynamically link ABL library */
    static void initPostProc();
    static void destroyPostProc();
    static int (*getFnPpParams())(const struct compute_params *,
                                 struct mdp_overlay_pp_params *);

    /* 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;
        /* Format for which this pipe is attached to the mixer*/
        int mFormatType;

        /* 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];
        static int pipeMinID[utils::OV_MDP_PIPE_ANY];
        static int pipeMaxID[utils::OV_MDP_PIPE_ANY];

        /* 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

    /* 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 *);
    /* Dynamically link ABL library */
    static void *sLibAblHandle;
    static int (*sFnppParams)(const struct compute_params *,
                            struct mdp_overlay_pp_params *);
    static bool sDebugPipeLifecycle;

    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 int (*Overlay::getFnPpParams())(const struct compute_params *,
                    struct mdp_overlay_pp_params *) {
    return sFnppParams;
}

inline void Overlay::debugPipeLifecycle(const bool& enable) {
    sDebugPipeLifecycle = enable;
}

inline bool Overlay::isDebugPipeLifecycle() {
    return sDebugPipeLifecycle;
}

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
