| /* |
| * 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; |
| |
| // 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; |
| }; |
| |
| 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); |
| |
| //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; |
| }; |
| |
| 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 |