| /* | 
 |  * 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); } | 
 |     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); | 
 | 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; | 
 |  | 
 |         /* 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); | 
 |     }; | 
 |  | 
 |     /* 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 fbRect calculated against ROI generated */ | 
 |     virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) = 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); | 
 |  | 
 |     int mDpy; | 
 |     static bool sEnabled; | 
 |     static bool sEnableMixedMode; | 
 |     static int sSimulationFlags; | 
 |     static bool sDebugLogs; | 
 |     static bool sIdleFallBack; | 
 |     /* Handles the timeout event from kernel, if the value is set to true */ | 
 |     static bool sHandleTimeout; | 
 |     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 allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index); | 
 |     //Enable Partial Update for MDP3 targets | 
 |     static bool enablePartialUpdateForMDP3; | 
 | }; | 
 |  | 
 | 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 fbRect calculated against ROI generated */ | 
 |     virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect); | 
 | }; | 
 |  | 
 | 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); | 
 | 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); | 
 |     /* Trims fbRect calculated against ROI generated */ | 
 |     virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect); | 
 | }; | 
 |  | 
 | 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); | 
 | }; | 
 |  | 
 | }; //namespace | 
 | #endif |