/*
 * Copyright (C) 2010 The Android Open Source Project
 * Copyright (C)2012-2014, 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_UTILS_H
#define HWC_UTILS_H

#define DEBUG_MDPDOWNSCALE 0
#define HWC_REMOVE_DEPRECATED_VERSIONS 1

#include <fcntl.h>
#include <math.h>
#include <hardware/hwcomposer.h>
#include <gr.h>
#include <gralloc_priv.h>
#include <utils/String8.h>
#include "qdMetaData.h"
#include "mdp_version.h"
#include <overlayUtils.h>
#include <overlayRotator.h>
#include <EGL/egl.h>
#include <QService.h>


#define ALIGN_TO(x, align)     (((x) + ((align)-1)) & ~((align)-1))
#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
#define MAX_NUM_APP_LAYERS 32
#define MAX_NUM_BLEND_STAGES 16
#define MIN_DISPLAY_XRES 200
#define MIN_DISPLAY_YRES 200
#define HWC_WFDDISPSYNC_LOG 0
#define STR(f) #f;
// Max number of PTOR layers handled
#define MAX_PTOR_LAYERS 2

//Fwrd decls
struct hwc_context_t;

namespace ovutils = overlay::utils;

namespace overlay {
class Overlay;
class Rotator;
class RotMgr;
}

namespace qhwc {
//fwrd decl
class QueuedBufferStore;
class HDMIDisplay;
class VirtualDisplay;
class IFBUpdate;
class IVideoOverlay;
class MDPComp;
class CopyBit;
class HwcDebug;
class AssertiveDisplay;
class HWCVirtualVDS;


struct MDPInfo {
    int version;
    char panel;
    bool hasOverlay;
};

struct DisplayAttributes {
    uint32_t refreshRate;
    uint32_t dynRefreshRate;
    uint32_t vsync_period; //nanos
    uint32_t xres;
    uint32_t yres;
    uint32_t stride;
    float xdpi;
    float ydpi;
    bool secure;
    uint32_t fbformat;
    int fd;
    bool connected; //Applies only to pluggable disp.
    //Connected does not mean it ready to use.
    //It should be active also. (UNBLANKED)
    bool isActive;
    // In pause state, composition is bypassed
    // used for WFD displays and in QDCM calibration mode
    bool isPause;
    // To trigger padding round to clean up mdp
    // pipes
    bool isConfiguring;
    // Indicates whether external/virtual display is in MDP scaling mode
    bool mMDPScalingMode;
    // Ext dst Rect
    hwc_rect_t mDstRect;
    //Action safe attributes
    // Flag to indicate the presence of action safe dimensions for external
    bool mActionSafePresent;
    int mAsWidthRatio;
    int mAsHeightRatio;

    // This is the 3D mode to which the TV is set
    // The mode may be set via the appearance of a layer with 3D format
    // or by forcing the mode via binder.
    // If the mode is set via binder, the s3dModeForced flag is set, so that the
    // mode is not changed back when the 3D video layer drops out.
    // If the forced mode is different from the one in 3D video, the results
    // are unpredictable. The assumption is made here that the caller forcing
    // the mode via binder knows the right formats to use.
    // The s3dModeForced flag is also used to force 2D if the s3dMode is
    // HDMI_S3D_NONE
    int s3dMode;
    bool s3dModeForced;
    //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
    //following fields are used.
    //Also used when the actual panel's dimensions change and FB remains
    //constant
    bool fbScaling;
    uint32_t xresFB; //FB's width, by default from VSCREEN overridden by prop
    uint32_t yresFB; //FB's height, by default from VSCREEN overridden by prop
    float fbWidthScaleRatio; // Panel Width / FB Width
    float fbHeightScaleRatio; // Panel Height / FB Height
    //If configuration changed dynamically without subsequent GEOMETRY changes
    //we may still need to adjust destination params
    bool configSwitched;
};

struct ListStats {
    int numAppLayers; //Total - 1, excluding FB layer.
    int skipCount;
    int fbLayerIndex; //Always last for now. = numAppLayers
    //Video specific
    int yuvCount;
    int yuvIndices[MAX_NUM_APP_LAYERS];
    bool preMultipliedAlpha;
    int yuv4k2kIndices[MAX_NUM_APP_LAYERS];
    int yuv4k2kCount;
    // Notifies hwcomposer about the start and end of animation
    // This will be set to true during animation, otherwise false.
    bool isDisplayAnimating;
    bool secureUI; // Secure display layer
    bool isSecurePresent;
    hwc_rect_t lRoi;  //left ROI
    hwc_rect_t rRoi;  //right ROI. Unused in single DSI panels.
    //App Buffer Composition index
    int  renderBufIndexforABC;
    // Secure RGB specific
    int secureRGBCount;
    int secureRGBIndices[MAX_NUM_APP_LAYERS];
    //dyn refresh rate-Client requested refreshrate
    uint32_t refreshRateRequest;
    // Flag related to windowboxing feature
    bool mAIVVideoMode;
};

//PTOR Comp info
struct PtorInfo {
    int count;
    int layerIndex[MAX_PTOR_LAYERS];
    hwc_rect_t displayFrame[MAX_PTOR_LAYERS];
    bool isActive() { return (count>0); }
    int getPTORArrayIndex(int index) {
        int idx = -1;
        for(int i = 0; i < count; i++) {
            if(index == layerIndex[i])
                idx = i;
        }
        return idx;
    }
};

struct LayerProp {
    uint32_t mFlags; //qcom specific layer flags
    LayerProp():mFlags(0){};
};

struct VsyncState {
    bool enable;
    bool fakevsync;
    bool debug;
};

struct BwcPM {
    static void setBwc(const hwc_context_t *ctx, const int& dpy,
            const private_handle_t *hnd,
            const hwc_rect_t& crop, const hwc_rect_t& dst,
            const int& transform, const int& downscale,
            ovutils::eMdpFlags& mdpFlags);
};

// LayerProp::flag values
enum {
    HWC_MDPCOMP = 0x00000001,
    HWC_COPYBIT = 0x00000002,
};

// AIV specific flags
enum {
    HWC_AIV_VIDEO = 0x80000000,
    HWC_AIV_CC    = 0x40000000,
};

// HAL specific features
enum {
    HWC_COLOR_FILL = 0x00000008,
    HWC_FORMAT_RB_SWAP = 0x00000040,
};

/* External Display states */
enum {
    EXTERNAL_OFFLINE = 0,
    EXTERNAL_ONLINE,
    EXTERNAL_PAUSE,
    EXTERNAL_RESUME,
    EXTERNAL_MAXSTATES
};

class LayerRotMap {
public:
    LayerRotMap() { reset(); }
    void add(hwc_layer_1_t* layer, overlay::Rotator *rot);
    //Resets the mapping of layer to rotator
    void reset();
    //Clears mappings and existing rotator fences
    //Intended to be used during errors
    void clear();
    uint32_t getCount() const;
    hwc_layer_1_t* getLayer(uint32_t index) const;
    overlay::Rotator* getRot(uint32_t index) const;
    bool isRotCached(uint32_t index) const;
    void setReleaseFd(const int& fence);
private:
    hwc_layer_1_t* mLayer[overlay::RotMgr::MAX_ROT_SESS];
    overlay::Rotator* mRot[overlay::RotMgr::MAX_ROT_SESS];
    uint32_t mCount;
};

inline uint32_t LayerRotMap::getCount() const {
    return mCount;
}

inline hwc_layer_1_t* LayerRotMap::getLayer(uint32_t index) const {
    if(index >= mCount) return NULL;
    return mLayer[index];
}

inline overlay::Rotator* LayerRotMap::getRot(uint32_t index) const {
    if(index >= mCount) return NULL;
    return mRot[index];
}

inline hwc_rect_t integerizeSourceCrop(const hwc_frect_t& cropF) {
    hwc_rect_t cropI = {0,0,0,0};
    cropI.left = int(floorf(cropF.left));
    cropI.top = int(floorf(cropF.top));
    cropI.right = int(ceilf(cropF.right));
    cropI.bottom = int(ceilf(cropF.bottom));
    return cropI;
}

inline bool isNonIntegralSourceCrop(const hwc_frect_t& cropF) {
    if(cropF.left - roundf(cropF.left)     ||
       cropF.top - roundf(cropF.top)       ||
       cropF.right - roundf(cropF.right)   ||
       cropF.bottom - roundf(cropF.bottom))
        return true;
    else
        return false;
}

// -----------------------------------------------------------------------------
// Utility functions - implemented in hwc_utils.cpp
void dumpLayer(hwc_layer_1_t const* l);
void setListStats(hwc_context_t *ctx, hwc_display_contents_1_t *list,
        int dpy);
int initContext(hwc_context_t *ctx);
void closeContext(hwc_context_t *ctx);
//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
                         const hwc_rect_t& scissor, int orient);
void getNonWormholeRegion(hwc_display_contents_1_t* list,
                              hwc_rect_t& nwr);
bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
bool isSecureModePolicy(int mdpVersion);
// Returns true, if the input layer format is supported by rotator
bool isRotatorSupportedFormat(private_handle_t *hnd);
//Returns true, if the layer is YUV or the layer has been rendered by CPU
bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd);
bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer);
bool isDownscaleRequired(hwc_layer_1_t const* layer);
bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
                           const int& dpy);
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
                        private_handle_t *hnd);
bool isAlphaPresent(hwc_layer_1_t const* layer);
bool isAlphaPresentinFB(hwc_context_t* ctx, int dpy);
int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable);
int getBlending(int blending);
bool isGLESOnlyComp(hwc_context_t *ctx, const int& dpy);
void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers);
bool isAbcInUse(hwc_context_t *ctx);

void dumpBuffer(private_handle_t *ohnd, char *bufferName);
void updateDisplayInfo(hwc_context_t* ctx, int dpy);
void resetDisplayInfo(hwc_context_t* ctx, int dpy);
void initCompositionResources(hwc_context_t* ctx, int dpy);
void destroyCompositionResources(hwc_context_t* ctx, int dpy);
void clearPipeResources(hwc_context_t* ctx, int dpy);

//Helper function to dump logs
void dumpsys_log(android::String8& buf, const char* fmt, ...);

int getExtOrientation(hwc_context_t* ctx);
bool isValidRect(const hwc_rect_t& rect);
hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2);
hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off);
hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
hwc_rect_t getUnion(const hwc_rect_t& rect1, const hwc_rect_t& rect2);
void optimizeLayerRects(const hwc_display_contents_1_t *list);
bool areLayersIntersecting(const hwc_layer_1_t* layer1,
        const hwc_layer_1_t* layer2);
bool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs);

// returns true if Action safe dimensions are set and target supports Actionsafe
bool isActionSafePresent(hwc_context_t *ctx, int dpy);

/* Calculates the destination position based on the action safe rectangle */
void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);

void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
                                hwc_rect_t& inRect, hwc_rect_t& outRect);

uint32_t roundOff(uint32_t refreshRate);

void setRefreshRate(hwc_context_t *ctx, int dpy, uint32_t refreshRate);

bool isPrimaryPortrait(hwc_context_t *ctx);

bool isOrientationPortrait(hwc_context_t *ctx);

void calcExtDisplayPosition(hwc_context_t *ctx,
                               private_handle_t *hnd,
                               int dpy,
                               hwc_rect_t& sourceCrop,
                               hwc_rect_t& displayFrame,
                               int& transform,
                               ovutils::eTransform& orient);

// Returns the orientation that needs to be set on external for
// BufferMirrirMode(Sidesync)
int getMirrorModeOrientation(hwc_context_t *ctx);

/* Get External State names */
const char* getExternalDisplayState(uint32_t external_state);

// Resets display ROI to full panel resoluion
void resetROI(hwc_context_t *ctx, const int dpy);

// Modifies ROI even from middle of the screen
hwc_rect expandROIFromMidPoint(hwc_rect roi, hwc_rect fullFrame);

// Aligns updating ROI to panel restrictions
hwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary);

// Handles wfd Pause and resume events
void handle_pause(hwc_context_t *ctx, int dpy);
void handle_resume(hwc_context_t *ctx, int dpy);

// Handle ONLINE/OFFLINE for HDMI display
void handle_online(hwc_context_t* ctx, int dpy);
void handle_offline(hwc_context_t* ctx, int dpy);

//Close acquireFenceFds of all layers of incoming list
void closeAcquireFds(hwc_display_contents_1_t* list);

//Sync point impl.
int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
        int fd);

//Sets appropriate mdp flags for a layer.
void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
        ovutils::eMdpFlags &mdpFlags,
        int rotDownscale, int transform);

int configRotator(overlay::Rotator *rot, ovutils::Whf& whf,
        hwc_rect_t& crop, const ovutils::eMdpFlags& mdpFlags,
        const ovutils::eTransform& orient, const int& downscale);

int configMdp(overlay::Overlay *ov, const ovutils::PipeArgs& parg,
        const ovutils::eTransform& orient, const hwc_rect_t& crop,
        const hwc_rect_t& pos, const MetaData_t *metadata,
        const ovutils::eDest& dest);

int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
        const ovutils::eDest& dest);

void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
        hwc_rect_t& crop, overlay::Rotator *rot);

bool isZoomModeEnabled(hwc_rect_t crop);
void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy);
void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& dst, int dpy);
void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
                           hwc_rect_t& dst, int dpy);

//Routine to configure low resolution panels (<= 2048 width)
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
        const ovutils::eDest& dest,
        overlay::Rotator **rot);

//Routine to configure high resolution panels (> 2048 width)
int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
        const ovutils::eDest& lDest,
        const ovutils::eDest& rDest, overlay::Rotator **rot);

//Check if the current round needs 3D composition
bool needs3DComposition(hwc_context_t* ctx, int dpy);

//Routine to configure 3D video
int configure3DVideo(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
        const ovutils::eDest& lDest,
        const ovutils::eDest& rDest, overlay::Rotator **rot);

//Routine to split and configure high resolution YUV layer (> 2048 width)
int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy,
        ovutils::eMdpFlags& mdpFlags, ovutils::eZorder& z,
        const ovutils::eDest& lDest,
        const ovutils::eDest& rDest, overlay::Rotator **rot);

//On certain targets DMA pipes are used for rotation and they won't be available
//for line operations. On a per-target basis we can restrict certain use cases
//from using rotator, since we know before-hand that such scenarios can lead to
//extreme unavailability of pipes. This can also be done via hybrid calculations
//also involving many more variables like number of write-back interfaces etc,
//but the variety of scenarios is too high to warrant that.
bool canUseRotator(hwc_context_t *ctx, int dpy);

int getLeftSplit(hwc_context_t *ctx, const int& dpy);

bool isDisplaySplit(hwc_context_t* ctx, int dpy);

int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer);

// Set the GPU hint flag to high for MIXED/GPU composition only for
// first frame after MDP to GPU/MIXED mode transition.
// Set the GPU hint to default if the current composition type is GPU
// due to idle fallback or MDP composition.
void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list);

// Returns true if rect1 is peripheral to rect2, false otherwise.
bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2);

// Checks if boot animation has completed and applies default mode
void processBootAnimCompleted(hwc_context_t *ctx);

//The gralloc API and driver have different formats
//The format needs to be converted before passing to libhdmi
int convertS3DFormatToMode(int s3DFormat);

//Configure resources for 3D mode
void setup3DMode(hwc_context_t* ctx, int dpy, int s3dMode);

//Checks if this display supports 3D
bool displaySupports3D(hwc_context_t* ctx, int dpy);

// Inline utility functions
static inline bool isSkipLayer(const hwc_layer_1_t* l) {
    return (UNLIKELY(l && (l->flags & HWC_SKIP_LAYER)));
}

static inline bool isAIVVideoLayer(const hwc_layer_1_t* l) {
    return (UNLIKELY(l && (l->flags & HWC_AIV_VIDEO)));
}

static inline bool isAIVCCLayer(const hwc_layer_1_t* l) {
    return (UNLIKELY(l && (l->flags & HWC_AIV_CC)));
}

// Returns true if the buffer is yuv
static inline bool isYuvBuffer(const private_handle_t* hnd) {
    return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO));
}

// Returns true if the buffer is yuv and exceeds the mixer width
static inline bool isYUVSplitNeeded(const private_handle_t* hnd) {
    int maxPipeWidth = qdutils::MDPVersion::getInstance().getMaxPipeWidth();
    return (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) &&
            (hnd->width > maxPipeWidth));
}

// Returns true if the buffer is secure
static inline bool isSecureBuffer(const private_handle_t* hnd) {
    return (hnd && (private_handle_t::PRIV_FLAGS_SECURE_BUFFER & hnd->flags));
}

// Returns true if the buffer is protected
static inline bool isProtectedBuffer(const private_handle_t* hnd) {
    return (hnd && (private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER & hnd->flags));
}


static inline bool isTileRendered(const private_handle_t* hnd) {
    return (hnd && (private_handle_t::PRIV_FLAGS_TILE_RENDERED & hnd->flags));
}

//Return true if the buffer is intended for Secure Display
static inline bool isSecureDisplayBuffer(const private_handle_t* hnd) {
    return (hnd && (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY));
}

static inline uint32_t get3DFormat(const private_handle_t* hnd) {
    MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
    if(isYuvBuffer(hnd) && metadata && metadata->operation & S3D_FORMAT) {
        return metadata->s3dFormat;
    }
    return HAL_NO_3D;
}

static inline int getWidth(const private_handle_t* hnd) {
    MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
        return metadata->bufferDim.sliceWidth;
    }
    return hnd->width;
}

static inline int getHeight(const private_handle_t* hnd) {
    MetaData_t *metadata = reinterpret_cast<MetaData_t*>(hnd->base_metadata);
    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
        return metadata->bufferDim.sliceHeight;
    }
    return hnd->height;
}

template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }

// Initialize uevent thread
void init_uevent_thread(hwc_context_t* ctx);
// Initialize vsync thread
void init_vsync_thread(hwc_context_t* ctx);

inline void getLayerResolution(const hwc_layer_1_t* layer,
                               int& width, int& height) {
    hwc_rect_t displayFrame  = layer->displayFrame;
    width = displayFrame.right - displayFrame.left;
    height = displayFrame.bottom - displayFrame.top;
}

static inline int openFb(int dpy) {
    int fd = -1;
    const char *devtmpl = "/dev/graphics/fb%u";
    char name[64] = {0};
    snprintf(name, 64, devtmpl, dpy);
    fd = open(name, O_RDWR);
    return fd;
}

template <class T>
inline void swap(T& a, T& b) {
    T tmp = a;
    a = b;
    b = tmp;
}

}; //qhwc namespace

enum eAnimationState{
    ANIMATION_STOPPED,
    ANIMATION_STARTED,
};

enum eCompositionState {
    COMPOSITION_STATE_MDP = 0,        // Set if composition type is MDP
    COMPOSITION_STATE_GPU,            // Set if composition type is GPU or MIXED
    COMPOSITION_STATE_IDLE_FALLBACK,  // Set if it is idlefallback
};

// Structure holds the information about the GPU hint.
struct gpu_hint_info {
    // system level flag to enable gpu_perf_mode
    bool mGpuPerfModeEnable;
    // Stores the current GPU performance mode DEFAULT/HIGH
    bool mCurrGPUPerfMode;
    // Stores the compositon state GPU, MDP or IDLE_FALLBACK
    bool mCompositionState;
    // Stores the EGLContext of current process
    EGLContext mEGLContext;
    // Stores the EGLDisplay of current process
    EGLDisplay mEGLDisplay;
};

// -----------------------------------------------------------------------------
// HWC context
// This structure contains overall state
struct hwc_context_t {
    hwc_composer_device_1_t device;
    const hwc_procs_t* proc;

    //CopyBit objects
    qhwc::CopyBit *mCopyBit[HWC_NUM_DISPLAY_TYPES];

    //Overlay object - NULL for non overlay devices
    overlay::Overlay *mOverlay;
    //Holds a few rot objects
    overlay::RotMgr *mRotMgr;

    //Primary and external FB updater
    qhwc::IFBUpdate *mFBUpdate[HWC_NUM_DISPLAY_TYPES];
    // HDMI display related object. Used to configure/teardown
    // HDMI when it is connected as primary or external.
    qhwc::HDMIDisplay *mHDMIDisplay;
    qhwc::MDPInfo mMDP;
    qhwc::VsyncState vstate;
    qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
    qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES];
    qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES];
    qhwc::MDPComp *mMDPComp[HWC_NUM_DISPLAY_TYPES];
    qhwc::HwcDebug *mHwcDebug[HWC_NUM_DISPLAY_TYPES];
    hwc_rect_t mViewFrame[HWC_NUM_DISPLAY_TYPES];
    qhwc::AssertiveDisplay *mAD;
    eAnimationState mAnimationState[HWC_NUM_DISPLAY_TYPES];
    qhwc::HWCVirtualVDS *mHWCVirtual;

    // stores the #numHwLayers of the previous frame
    // for each display device
    int mPrevHwLayerCount[HWC_NUM_DISPLAY_TYPES];

    // stores the primary device orientation
    int deviceOrientation;
    //Securing in progress indicator
    bool mSecuring;
    //Display in secure mode indicator
    bool mSecureMode;
    //Lock to protect drawing data structures
    mutable Locker mDrawLock;
    //Drawing round when we use GPU
    bool isPaddingRound;
    // Used to mark composition cycle when DMA state change is required
    bool isDMAStateChanging;
    // External Orientation
    int mExtOrientation;
    //Flags the transition of a video session
    bool mVideoTransFlag;
    //Used for SideSync feature
    //which overrides the mExtOrientation
    bool mBufferMirrorMode;
    // Used to synchronize between WFD and Display modules
    mutable Locker mWfdSyncLock;

    qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
    // Panel reset flag will be set if BTA check fails
    bool mPanelResetStatus;
    // number of active Displays
    int numActiveDisplays;
    struct gpu_hint_info mGPUHintInfo;
    //App Buffer Composition
    bool enableABC;
    // PTOR Info
    qhwc::PtorInfo mPtorInfo;
    //Running in Thermal burst mode
    bool mThermalBurstMode;
    //Layers out of ROI
    bool copybitDrop[MAX_NUM_APP_LAYERS];
    // Flag related to windowboxing feature
    bool mWindowboxFeature;
    // This denotes the tolerance between video layer and external display
    // aspect ratio
    float mAspectRatioToleranceLevel;
    // Runtime switch for BWC for targets that support it
    bool mBWCEnabled;
    // Provides a way for OEM's to disable setting dynfps via metadata.
    bool mUseMetaDataRefreshRate;
    // Stores the hpd enabled status- avoids re-enabling HDP on suspend resume.
    bool mHPDEnabled;
    //Used to notify that boot has completed
    bool mBootAnimCompleted;
    // Display binder service
    qService::QService* mQService;
};

namespace qhwc {
static inline bool isSkipPresent (hwc_context_t *ctx, int dpy) {
    return  ctx->listStats[dpy].skipCount;
}

static inline bool isYuvPresent (hwc_context_t *ctx, int dpy) {
    return  ctx->listStats[dpy].yuvCount;
}

static inline bool has90Transform(hwc_layer_1_t const* layer) {
    return ((layer->transform & HWC_TRANSFORM_ROT_90) &&
            !(layer->flags & HWC_COLOR_FILL));
}

inline bool isSecurePresent(hwc_context_t *ctx, int dpy) {
    return ctx->listStats[dpy].isSecurePresent;
}

static inline bool isSecondaryConfiguring(hwc_context_t* ctx) {
    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring);
}

static inline bool isSecondaryConnected(hwc_context_t* ctx) {
    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ||
            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected);
}

static inline bool isSecondaryAnimating(hwc_context_t* ctx) {
    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected &&
            (!ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isPause) &&
            ctx->listStats[HWC_DISPLAY_EXTERNAL].isDisplayAnimating)
            ||
           (ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected &&
            (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) &&
            ctx->listStats[HWC_DISPLAY_VIRTUAL].isDisplayAnimating);
}

/* Return Virtual Display connection status */
static inline bool isVDConnected(hwc_context_t* ctx) {
    return ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;
}

inline uint32_t getLayerClock(const uint32_t& dstW, const uint32_t& dstH,
        const uint32_t& srcH) {
    return max(dstW, (srcH * dstW) / dstH);
}

};

#endif //HWC_UTILS_H
