/*
 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
 *
 * Not a Contribution, Apache license notifications and license are retained
 * for attribution purposes only.
 *
 * 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 HWC_MDP_COMP
#define HWC_MDP_COMP

#include <hwc_utils.h>
#include <idle_invalidator.h>
#include <cutils/properties.h>
#include <overlay.h>

namespace overlay {
class Rotator;
};

namespace qhwc {
namespace ovutils = overlay::utils;

class MDPComp {
public:
    explicit MDPComp(int);
    virtual ~MDPComp(){};
    /*sets up mdp comp for the current frame */
    int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* draw */
    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
    //Reset values
    void reset();
    /* dumpsys */
    void dump(android::String8& buf, hwc_context_t *ctx);
    bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); }
    bool isMDPComp() { return mModeOn; }
    int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    static MDPComp* getObject(hwc_context_t *ctx, const int& dpy);
    /* Handler to invoke frame redraw on Idle Timer expiry */
    static void timeout_handler(void *udata);
    /* Initialize MDP comp*/
    static bool init(hwc_context_t *ctx);
    static void resetIdleFallBack() { sIdleFallBack = false; }
    static bool isIdleFallback() { return sIdleFallBack; }
    static void dynamicDebug(bool enable){ sDebugLogs = enable; }
    static void setIdleTimeout(const uint32_t& timeout);
    static void setMaxPipesPerMixer(const uint32_t value);
    static int setPartialUpdatePref(hwc_context_t *ctx, bool enable);
    static bool getPartialUpdatePref(hwc_context_t *ctx);
    static void enablePartialUpdate(bool enable)
                                          { sIsPartialUpdateActive = enable; };
    void setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list);

protected:
    enum ePipeType {
        MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
        MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
        MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
        MDPCOMP_OV_ANY,
    };

    //Simulation flags
    enum {
        MDPCOMP_AVOID_FULL_MDP = 0x001,
        MDPCOMP_AVOID_CACHE_MDP = 0x002,
        MDPCOMP_AVOID_LOAD_MDP = 0x004,
        MDPCOMP_AVOID_VIDEO_ONLY = 0x008,
        MDPCOMP_AVOID_MDP_ONLY_LAYERS = 0x010,
    };

    /* mdp pipe data */
    struct MdpPipeInfo {
        int zOrder;
        virtual ~MdpPipeInfo(){};
    };

    struct MdpYUVPipeInfo : public MdpPipeInfo{
        ovutils::eDest lIndex;
        ovutils::eDest rIndex;
        virtual ~MdpYUVPipeInfo(){};
    };

    /* per layer data */
    struct PipeLayerPair {
        MdpPipeInfo *pipeInfo;
        overlay::Rotator* rot;
        int listIndex;
    };

    /* per frame data */
    struct FrameInfo {
        /* maps layer list to mdp list */
        int layerCount;
        int layerToMDP[MAX_NUM_APP_LAYERS];

        /* maps mdp list to layer list */
        int mdpCount;
        struct PipeLayerPair mdpToLayer[MAX_NUM_BLEND_STAGES];

        /* layer composing on FB? */
        int fbCount;
        bool isFBComposed[MAX_NUM_APP_LAYERS];
        /* layers lying outside ROI. Will
         * be dropped off from the composition */
        int dropCount;
        bool drop[MAX_NUM_APP_LAYERS];

        bool needsRedraw;
        int fbZ;
        int hwCursorIndex;

        /* c'tor */
        FrameInfo();
        /* clear old frame data */
        void reset(const int& numLayers);
        void map();
    };

    /* cached data */
    struct LayerCache {
        int layerCount;
        buffer_handle_t hnd[MAX_NUM_APP_LAYERS];
        bool isFBComposed[MAX_NUM_APP_LAYERS];
        bool drop[MAX_NUM_APP_LAYERS];

        /* c'tor */
        LayerCache();
        /* clear caching info*/
        void reset();
        void cacheAll(hwc_display_contents_1_t* list);
        void updateCounts(const FrameInfo&);
        bool isSameFrame(const FrameInfo& curFrame,
                         hwc_display_contents_1_t* list);
        bool isSameFrame(hwc_context_t *ctx, int dpy,
                                        hwc_display_contents_1_t* list);
    };

    /* allocates pipe from pipe book */
    virtual bool allocLayerPipes(hwc_context_t *ctx,
                                 hwc_display_contents_1_t* list) = 0;
    /* configures MPD pipes */
    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                          PipeLayerPair& pipeLayerPair) = 0;
    /* Increments mdpCount if 4k2k yuv layer split is enabled.
     * updates framebuffer z order if fb lies above source-split layer */
    virtual void adjustForSourceSplit(hwc_context_t *ctx,
            hwc_display_contents_1_t* list) = 0;
    /* configures 4kx2k yuv layer*/
    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
            PipeLayerPair& PipeLayerPair) = 0;
    /* generates ROI based on the modified area of the frame */
    virtual void generateROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list) = 0;
    /* validates the ROI generated for fallback conditions */
    virtual bool validateAndApplyROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list) = 0;
    /* Trims layer coordinates against ROI generated */
    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
            hwc_rect& dst) = 0;
    /* set/reset flags for MDPComp */
    void setMDPCompLayerFlags(hwc_context_t *ctx,
                              hwc_display_contents_1_t* list);
    void setRedraw(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* checks for conditions where mdpcomp is not possible */
    bool isFrameDoable(hwc_context_t *ctx);
    /* checks for conditions where RGB layers cannot be bypassed */
    bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* checks if full MDP comp can be done */
    bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* Full MDP Composition with Peripheral Tiny Overlap Removal */
    bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list);
    /* check if we can use layer cache to do at least partial MDP comp */
    bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* Partial MDP comp that uses caching to save power as primary goal */
    bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* Partial MDP comp that balances the load between MDP and GPU such that
     * MDP is loaded to the max of its capacity. The lower z order layers are
     * fed to MDP, whereas the upper ones to GPU, because the upper ones have
     * lower number of pixels and can reduce GPU processing time */
    bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    /* Checks if its worth doing load based partial comp */
    bool isLoadBasedCompDoable(hwc_context_t *ctx);
    /* checks for conditions where only video can be bypassed */
    bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
            bool secureOnly);
    /* checks for conditions where only secure RGB and video can be bypassed */
    bool tryMDPOnlyLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    bool mdpOnlyLayersComp(hwc_context_t *ctx, hwc_display_contents_1_t* list,
            bool secureOnly);
    /* checks for conditions where YUV layers cannot be bypassed */
    bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
    /* checks for conditions where Secure RGB layers cannot be bypassed */
    bool isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
    /* checks if MDP/MDSS can process current list w.r.to HW limitations
     * All peculiar HW limitations should go here */
    bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
    /* Is debug enabled */
    static bool isDebug() { return sDebugLogs ? true : false; };
    /* Is feature enabled */
    static bool isEnabled() { return sEnabled; };
    /* checks for mdp comp dimension limitation */
    bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer);
    /* tracks non updating layers*/
    void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list,
                          FrameInfo& frame);
    /* optimize layers for mdp comp*/
    bool markLayersForCaching(hwc_context_t* ctx,
            hwc_display_contents_1_t* list);
    int getBatch(hwc_display_contents_1_t* list,
            int& maxBatchStart, int& maxBatchEnd,
            int& maxBatchCount);
    bool canPushBatchToTop(const hwc_display_contents_1_t* list,
            int fromIndex, int toIndex);
    bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
            int fromIndex, int toIndex, int targetLayerIndex);

    /* drop other non-AIV layers from external display list.*/
    void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list);

        /* updates cache map with YUV info */
    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
            bool secureOnly, FrameInfo& frame);
    /* updates cache map with secure RGB info */
    void updateSecureRGB(hwc_context_t* ctx,
            hwc_display_contents_1_t* list);
    /* Validates if the GPU/MDP layer split chosen by a strategy is supported
     * by MDP.
     * Sets up MDP comp data structures to reflect covnversion from layers to
     * overlay pipes.
     * Configures overlay.
     * Configures if GPU should redraw.
     */
    bool postHeuristicsHandling(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    void reset(hwc_context_t *ctx);
    bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer);
    bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
    hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* checks for conditions to enable partial udpate */
    bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    // Checks if only videocontent is updating
    bool onlyVideosUpdating(hwc_context_t *ctx, hwc_display_contents_1_t* list);
    static bool loadPerfLib();
    void setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list);

    int mDpy;
    static bool sEnabled;
    static bool sEnableMixedMode;
    static int sSimulationFlags;
    static bool sDebugLogs;
    static bool sIdleFallBack;
    static int sMaxPipesPerMixer;
    static bool sSrcSplitEnabled;
    static IdleInvalidator *sIdleInvalidator;
    static int sMaxSecLayers;
    static bool sIsPartialUpdateActive;
    struct FrameInfo mCurrentFrame;
    struct LayerCache mCachedFrame;
    //Enable 4kx2k yuv layer split
    static bool sEnableYUVsplit;
    bool mModeOn; // if prepare happened
    bool allocSplitVGPipes(hwc_context_t *ctx, int index);
    bool mPrevModeOn; //if previous prepare happened
    //Enable Partial Update for MDP3 targets
    static bool enablePartialUpdateForMDP3;
    static void *sLibPerfHint;
    static int sPerfLockHandle;
    static int (*sPerfLockAcquire)(int, int, int*, int);
    static int (*sPerfLockRelease)(int value);
    static int sPerfHintWindow;
    static float sDownscaleThreshold;

};

class MDPCompNonSplit : public MDPComp {
public:
    explicit MDPCompNonSplit(int dpy):MDPComp(dpy){};
    virtual ~MDPCompNonSplit(){};
    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);

private:
    struct MdpPipeInfoNonSplit : public MdpPipeInfo {
        ovutils::eDest index;
        virtual ~MdpPipeInfoNonSplit() {};
    };

    /* configure's overlay pipes for the frame */
    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                          PipeLayerPair& pipeLayerPair);

    /* allocates pipes to selected candidates */
    virtual bool allocLayerPipes(hwc_context_t *ctx,
                                 hwc_display_contents_1_t* list);

    /* Increments mdpCount if 4k2k yuv layer split is enabled.
     * updates framebuffer z order if fb lies above source-split layer */
    virtual void adjustForSourceSplit(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);

    /* configures 4kx2k yuv layer to 2 VG pipes*/
    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
            PipeLayerPair& PipeLayerPair);
    /* generates ROI based on the modified area of the frame */
    virtual void generateROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* validates the ROI generated for fallback conditions */
    virtual bool validateAndApplyROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* Trims layer coordinates against ROI generated */
    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
            hwc_rect& dst);
};

class MDPCompSplit : public MDPComp {
public:
    explicit MDPCompSplit(int dpy):MDPComp(dpy){};
    virtual ~MDPCompSplit(){};
    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);

protected:
    struct MdpPipeInfoSplit : public MdpPipeInfo {
        ovutils::eDest lIndex;
        ovutils::eDest rIndex;
        virtual ~MdpPipeInfoSplit() {};
    };

    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
                         MdpPipeInfoSplit& pipe_info);

    /* configure's overlay pipes for the frame */
    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                          PipeLayerPair& pipeLayerPair);

    /* allocates pipes to selected candidates */
    virtual bool allocLayerPipes(hwc_context_t *ctx,
                                 hwc_display_contents_1_t* list);
    /* Trims layer coordinates against ROI generated */
    virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop,
            hwc_rect& dst);
private:
    /* Increments mdpCount if 4k2k yuv layer split is enabled.
     * updates framebuffer z order if fb lies above source-split layer */
    virtual void adjustForSourceSplit(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);

    /* configures 4kx2k yuv layer*/
    virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
            PipeLayerPair& PipeLayerPair);
    /* generates ROI based on the modified area of the frame */
    virtual void generateROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* validates the ROI generated for fallback conditions */
    virtual bool validateAndApplyROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
};

class MDPCompSrcSplit : public MDPCompSplit {
public:
    explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){};
    virtual ~MDPCompSrcSplit(){};
private:
    virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
            MdpPipeInfoSplit& pipe_info);

    virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
            PipeLayerPair& pipeLayerPair);
    /* generates ROI based on the modified area of the frame */
    virtual void generateROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
    /* validates the ROI generated for fallback conditions */
    virtual bool validateAndApplyROI(hwc_context_t *ctx,
            hwc_display_contents_1_t* list);
};

}; //namespace
#endif
