1 /* 2 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved. 3 * 4 * Not a Contribution, Apache license notifications and license are retained 5 * for attribution purposes only. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 #ifndef HWC_MDP_COMP 21 #define HWC_MDP_COMP 22 23 #include <hwc_utils.h> 24 #include <idle_invalidator.h> 25 #include <cutils/properties.h> 26 #include <overlay.h> 27 28 namespace overlay { 29 class Rotator; 30 }; 31 32 namespace qhwc { 33 namespace ovutils = overlay::utils; 34 35 class MDPComp { 36 public: 37 explicit MDPComp(int); ~MDPComp()38 virtual ~MDPComp(){}; 39 /*sets up mdp comp for the current frame */ 40 int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list); 41 /* draw */ 42 virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0; 43 //Reset values 44 void reset(); 45 /* dumpsys */ 46 void dump(android::String8& buf, hwc_context_t *ctx); isGLESOnlyComp()47 bool isGLESOnlyComp() { return (mCurrentFrame.mdpCount == 0); } 48 int drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list); 49 static MDPComp* getObject(hwc_context_t *ctx, const int& dpy); 50 /* Handler to invoke frame redraw on Idle Timer expiry */ 51 static void timeout_handler(void *udata); 52 /* Initialize MDP comp*/ 53 static bool init(hwc_context_t *ctx); resetIdleFallBack()54 static void resetIdleFallBack() { sIdleFallBack = false; } isIdleFallback()55 static bool isIdleFallback() { return sIdleFallBack; } dynamicDebug(bool enable)56 static void dynamicDebug(bool enable){ sDebugLogs = enable; } 57 static void setIdleTimeout(const uint32_t& timeout); 58 static void setMaxPipesPerMixer(const uint32_t value); 59 static int setPartialUpdatePref(hwc_context_t *ctx, bool enable); 60 static bool getPartialUpdatePref(hwc_context_t *ctx); 61 void setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list); setSingleFullScreenUpdate()62 static void setSingleFullScreenUpdate() { sIsSingleFullScreenUpdate = true; } 63 64 protected: 65 enum ePipeType { 66 MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB, 67 MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG, 68 MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA, 69 MDPCOMP_OV_ANY, 70 }; 71 72 //Simulation flags 73 enum { 74 MDPCOMP_AVOID_FULL_MDP = 0x001, 75 MDPCOMP_AVOID_CACHE_MDP = 0x002, 76 MDPCOMP_AVOID_LOAD_MDP = 0x004, 77 MDPCOMP_AVOID_VIDEO_ONLY = 0x008, 78 MDPCOMP_AVOID_MDP_ONLY_LAYERS = 0x010, 79 }; 80 81 /* mdp pipe data */ 82 struct MdpPipeInfo { 83 int zOrder; ~MdpPipeInfoMdpPipeInfo84 virtual ~MdpPipeInfo(){}; 85 }; 86 87 struct MdpYUVPipeInfo : public MdpPipeInfo{ 88 ovutils::eDest lIndex; 89 ovutils::eDest rIndex; ~MdpYUVPipeInfoMdpYUVPipeInfo90 virtual ~MdpYUVPipeInfo(){}; 91 }; 92 93 /* per layer data */ 94 struct PipeLayerPair { 95 MdpPipeInfo *pipeInfo; 96 overlay::Rotator* rot; 97 int listIndex; 98 }; 99 100 /* per frame data */ 101 struct FrameInfo { 102 /* maps layer list to mdp list */ 103 int layerCount; 104 int layerToMDP[MAX_NUM_APP_LAYERS]; 105 106 /* maps mdp list to layer list */ 107 int mdpCount; 108 struct PipeLayerPair mdpToLayer[MAX_NUM_BLEND_STAGES]; 109 110 /* layer composing on FB? */ 111 int fbCount; 112 bool isFBComposed[MAX_NUM_APP_LAYERS]; 113 /* layers lying outside ROI. Will 114 * be dropped off from the composition */ 115 int dropCount; 116 bool drop[MAX_NUM_APP_LAYERS]; 117 118 bool needsRedraw; 119 int fbZ; 120 121 /* c'tor */ 122 FrameInfo(); 123 /* clear old frame data */ 124 void reset(const int& numLayers); 125 void map(); 126 }; 127 128 /* cached data */ 129 struct LayerCache { 130 int layerCount; 131 bool isFBComposed[MAX_NUM_APP_LAYERS]; 132 bool drop[MAX_NUM_APP_LAYERS]; 133 134 /* c'tor */ 135 LayerCache(); 136 /* clear caching info*/ 137 void reset(); 138 void updateCounts(const FrameInfo&); 139 bool isSameFrame(const FrameInfo& curFrame, 140 hwc_display_contents_1_t* list); 141 }; 142 143 /* allocates pipe from pipe book */ 144 virtual bool allocLayerPipes(hwc_context_t *ctx, 145 hwc_display_contents_1_t* list) = 0; 146 /* configures MPD pipes */ 147 virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 148 PipeLayerPair& pipeLayerPair) = 0; 149 /* Increments mdpCount if 4k2k yuv layer split is enabled. 150 * updates framebuffer z order if fb lies above source-split layer */ 151 virtual void adjustForSourceSplit(hwc_context_t *ctx, 152 hwc_display_contents_1_t* list) = 0; 153 /* configures 4kx2k yuv layer*/ 154 virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer, 155 PipeLayerPair& PipeLayerPair) = 0; 156 /* generates ROI based on the modified area of the frame */ 157 virtual void generateROI(hwc_context_t *ctx, 158 hwc_display_contents_1_t* list) = 0; 159 /* Calculates the dirtyRegion for the given layer */ 160 hwc_rect_t calculateDirtyRect(const hwc_layer_1_t* layer, 161 hwc_rect_t& scissor); 162 /* validates the ROI generated for fallback conditions */ 163 virtual bool validateAndApplyROI(hwc_context_t *ctx, 164 hwc_display_contents_1_t* list) = 0; 165 /* Trims layer coordinates against ROI generated */ 166 virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop, 167 hwc_rect& dst) = 0; 168 /* set/reset flags for MDPComp */ 169 void setMDPCompLayerFlags(hwc_context_t *ctx, 170 hwc_display_contents_1_t* list); 171 void setRedraw(hwc_context_t *ctx, 172 hwc_display_contents_1_t* list); 173 /* checks for conditions where mdpcomp is not possible */ 174 bool isFrameDoable(hwc_context_t *ctx); 175 /* checks for conditions where RGB layers cannot be bypassed */ 176 bool tryFullFrame(hwc_context_t *ctx, hwc_display_contents_1_t* list); 177 /* checks if full MDP comp can be done */ 178 bool fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list); 179 /* Full MDP Composition with Peripheral Tiny Overlap Removal */ 180 bool fullMDPCompWithPTOR(hwc_context_t *ctx,hwc_display_contents_1_t* list); 181 /* check if we can use layer cache to do at least partial MDP comp */ 182 bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list); 183 /* Partial MDP comp that uses caching to save power as primary goal */ 184 bool cacheBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list); 185 /* Partial MDP comp that balances the load between MDP and GPU such that 186 * MDP is loaded to the max of its capacity. The lower z order layers are 187 * fed to MDP, whereas the upper ones to GPU, because the upper ones have 188 * lower number of pixels and can reduce GPU processing time */ 189 bool loadBasedComp(hwc_context_t *ctx, hwc_display_contents_1_t* list); 190 /* Checks if its worth doing load based partial comp */ 191 bool isLoadBasedCompDoable(hwc_context_t *ctx); 192 /* checks for conditions where only video can be bypassed */ 193 bool tryVideoOnly(hwc_context_t *ctx, hwc_display_contents_1_t* list); 194 bool videoOnlyComp(hwc_context_t *ctx, hwc_display_contents_1_t* list, 195 bool secureOnly); 196 /* checks for conditions where only secure RGB and video can be bypassed */ 197 bool tryMDPOnlyLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list); 198 bool mdpOnlyLayersComp(hwc_context_t *ctx, hwc_display_contents_1_t* list, 199 bool secureOnly); 200 /* checks for conditions where YUV layers cannot be bypassed */ 201 bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer); 202 /* checks for conditions where Secure RGB layers cannot be bypassed */ 203 bool isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer); 204 /* checks if MDP/MDSS can process current list w.r.to HW limitations 205 * All peculiar HW limitations should go here */ 206 bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list); 207 /* Is debug enabled */ isDebug()208 static bool isDebug() { return sDebugLogs ? true : false; }; 209 /* Is feature enabled */ isEnabled()210 static bool isEnabled() { return sEnabled; }; 211 /* checks for mdp comp dimension limitation */ 212 bool isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer); 213 /* tracks non updating layers*/ 214 void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list, 215 FrameInfo& frame); 216 /* optimize layers for mdp comp*/ 217 bool markLayersForCaching(hwc_context_t* ctx, 218 hwc_display_contents_1_t* list); 219 int getBatch(hwc_display_contents_1_t* list, 220 int& maxBatchStart, int& maxBatchEnd, 221 int& maxBatchCount); 222 bool canPushBatchToTop(const hwc_display_contents_1_t* list, 223 int fromIndex, int toIndex); 224 bool intersectingUpdatingLayers(const hwc_display_contents_1_t* list, 225 int fromIndex, int toIndex, int targetLayerIndex); 226 227 /* drop other non-AIV layers from external display list.*/ 228 void dropNonAIVLayers(hwc_context_t* ctx, hwc_display_contents_1_t* list); 229 230 /* updates cache map with YUV info */ 231 void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list, 232 bool secureOnly, FrameInfo& frame); 233 /* updates cache map with secure RGB info */ 234 void updateSecureRGB(hwc_context_t* ctx, 235 hwc_display_contents_1_t* list); 236 /* Validates if the GPU/MDP layer split chosen by a strategy is supported 237 * by MDP. 238 * Sets up MDP comp data structures to reflect covnversion from layers to 239 * overlay pipes. 240 * Configures overlay. 241 * Configures if GPU should redraw. 242 */ 243 bool postHeuristicsHandling(hwc_context_t *ctx, 244 hwc_display_contents_1_t* list); 245 void reset(hwc_context_t *ctx); 246 bool isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer); 247 bool resourceCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list); 248 hwc_rect_t getUpdatingFBRect(hwc_context_t *ctx, 249 hwc_display_contents_1_t* list); 250 /* checks for conditions to enable partial udpate */ 251 bool canPartialUpdate(hwc_context_t *ctx, hwc_display_contents_1_t* list); 252 // Checks if only videocontent is updating 253 bool onlyVideosUpdating(hwc_context_t *ctx, hwc_display_contents_1_t* list); 254 static bool loadPerfLib(); 255 void setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list); 256 257 int mDpy; 258 static bool sEnabled; 259 static bool sEnableMixedMode; 260 static int sSimulationFlags; 261 static bool sDebugLogs; 262 static bool sIdleFallBack; 263 /* Handles the timeout event from kernel, if the value is set to true */ 264 static bool sHandleTimeout; 265 static int sMaxPipesPerMixer; 266 static bool sSrcSplitEnabled; 267 static IdleInvalidator *sIdleInvalidator; 268 static bool sIsSingleFullScreenUpdate; 269 static int sMaxSecLayers; 270 static bool sIsPartialUpdateActive; 271 struct FrameInfo mCurrentFrame; 272 struct LayerCache mCachedFrame; 273 //Enable 4kx2k yuv layer split 274 static bool sEnableYUVsplit; 275 bool mModeOn; // if prepare happened 276 bool allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index); 277 //Enable Partial Update for MDP3 targets 278 static bool enablePartialUpdateForMDP3; 279 static void *sLibPerfHint; 280 static int sPerfLockHandle; 281 static int (*sPerfLockAcquire)(int, int, int*, int); 282 static int (*sPerfLockRelease)(int value); 283 static int sPerfHintWindow; 284 285 }; 286 287 class MDPCompNonSplit : public MDPComp { 288 public: MDPCompNonSplit(int dpy)289 explicit MDPCompNonSplit(int dpy):MDPComp(dpy){}; ~MDPCompNonSplit()290 virtual ~MDPCompNonSplit(){}; 291 virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); 292 293 private: 294 struct MdpPipeInfoNonSplit : public MdpPipeInfo { 295 ovutils::eDest index; ~MdpPipeInfoNonSplitMdpPipeInfoNonSplit296 virtual ~MdpPipeInfoNonSplit() {}; 297 }; 298 299 /* configure's overlay pipes for the frame */ 300 virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 301 PipeLayerPair& pipeLayerPair); 302 303 /* allocates pipes to selected candidates */ 304 virtual bool allocLayerPipes(hwc_context_t *ctx, 305 hwc_display_contents_1_t* list); 306 307 /* Increments mdpCount if 4k2k yuv layer split is enabled. 308 * updates framebuffer z order if fb lies above source-split layer */ 309 virtual void adjustForSourceSplit(hwc_context_t *ctx, 310 hwc_display_contents_1_t* list); 311 312 /* configures 4kx2k yuv layer to 2 VG pipes*/ 313 virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer, 314 PipeLayerPair& PipeLayerPair); 315 /* generates ROI based on the modified area of the frame */ 316 virtual void generateROI(hwc_context_t *ctx, 317 hwc_display_contents_1_t* list); 318 /* validates the ROI generated for fallback conditions */ 319 virtual bool validateAndApplyROI(hwc_context_t *ctx, 320 hwc_display_contents_1_t* list); 321 /* Trims layer coordinates against ROI generated */ 322 virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop, 323 hwc_rect& dst); 324 }; 325 326 class MDPCompSplit : public MDPComp { 327 public: MDPCompSplit(int dpy)328 explicit MDPCompSplit(int dpy):MDPComp(dpy){}; ~MDPCompSplit()329 virtual ~MDPCompSplit(){}; 330 virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); 331 332 protected: 333 struct MdpPipeInfoSplit : public MdpPipeInfo { 334 ovutils::eDest lIndex; 335 ovutils::eDest rIndex; ~MdpPipeInfoSplitMdpPipeInfoSplit336 virtual ~MdpPipeInfoSplit() {}; 337 }; 338 339 virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 340 MdpPipeInfoSplit& pipe_info); 341 342 /* configure's overlay pipes for the frame */ 343 virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 344 PipeLayerPair& pipeLayerPair); 345 346 /* allocates pipes to selected candidates */ 347 virtual bool allocLayerPipes(hwc_context_t *ctx, 348 hwc_display_contents_1_t* list); 349 /* Trims layer coordinates against ROI generated */ 350 virtual void trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& crop, 351 hwc_rect& dst); 352 private: 353 /* Increments mdpCount if 4k2k yuv layer split is enabled. 354 * updates framebuffer z order if fb lies above source-split layer */ 355 virtual void adjustForSourceSplit(hwc_context_t *ctx, 356 hwc_display_contents_1_t* list); 357 358 /* configures 4kx2k yuv layer*/ 359 virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer, 360 PipeLayerPair& PipeLayerPair); 361 /* generates ROI based on the modified area of the frame */ 362 virtual void generateROI(hwc_context_t *ctx, 363 hwc_display_contents_1_t* list); 364 /* validates the ROI generated for fallback conditions */ 365 virtual bool validateAndApplyROI(hwc_context_t *ctx, 366 hwc_display_contents_1_t* list); 367 }; 368 369 class MDPCompSrcSplit : public MDPCompSplit { 370 public: MDPCompSrcSplit(int dpy)371 explicit MDPCompSrcSplit(int dpy) : MDPCompSplit(dpy){}; ~MDPCompSrcSplit()372 virtual ~MDPCompSrcSplit(){}; 373 private: 374 virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 375 MdpPipeInfoSplit& pipe_info); 376 377 virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 378 PipeLayerPair& pipeLayerPair); 379 /* generates ROI based on the modified area of the frame */ 380 virtual void generateROI(hwc_context_t *ctx, 381 hwc_display_contents_1_t* list); 382 /* validates the ROI generated for fallback conditions */ 383 virtual bool validateAndApplyROI(hwc_context_t *ctx, 384 hwc_display_contents_1_t* list); 385 }; 386 387 }; //namespace 388 #endif 389