| /* | 
 |  * 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> | 
 |  | 
 |  | 
 | #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; | 
 |     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; | 
 |  | 
 |     //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES | 
 |     //following fields are used. | 
 |     bool customFBSize; | 
 |     uint32_t xres_new; | 
 |     uint32_t yres_new; | 
 |  | 
 | }; | 
 |  | 
 | 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); | 
 | void 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); | 
 | 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); | 
 |  | 
 | //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); | 
 |  | 
 | // 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 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; | 
 | }; | 
 |  | 
 | 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); | 
 | } | 
 |  | 
 | /* 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 |