Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
      3  * Not a Contribution, Apache license notifications and license are retained
      4  * for attribution purposes only.
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <math.h>
     20 #include "hwc_mdpcomp.h"
     21 #include <sys/ioctl.h>
     22 #include "external.h"
     23 #include "virtual.h"
     24 #include "qdMetaData.h"
     25 #include "mdp_version.h"
     26 #include "hwc_fbupdate.h"
     27 #include "hwc_ad.h"
     28 #include <overlayRotator.h>
     29 
     30 using namespace overlay;
     31 using namespace qdutils;
     32 using namespace overlay::utils;
     33 namespace ovutils = overlay::utils;
     34 
     35 namespace qhwc {
     36 
     37 //==============MDPComp========================================================
     38 
     39 IdleInvalidator *MDPComp::idleInvalidator = NULL;
     40 bool MDPComp::sIdleFallBack = false;
     41 bool MDPComp::sHandleTimeout = false;
     42 bool MDPComp::sDebugLogs = false;
     43 bool MDPComp::sEnabled = false;
     44 bool MDPComp::sEnableMixedMode = true;
     45 int MDPComp::sSimulationFlags = 0;
     46 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
     47 bool MDPComp::sEnable4k2kYUVSplit = false;
     48 bool MDPComp::sSrcSplitEnabled = false;
     49 MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
     50     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
     51         sSrcSplitEnabled = true;
     52         return new MDPCompSrcSplit(dpy);
     53     } else if(isDisplaySplit(ctx, dpy)) {
     54         return new MDPCompSplit(dpy);
     55     }
     56     return new MDPCompNonSplit(dpy);
     57 }
     58 
     59 MDPComp::MDPComp(int dpy):mDpy(dpy){};
     60 
     61 void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
     62 {
     63     if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
     64         return;
     65 
     66     dumpsys_log(buf,"HWC Map for Dpy: %s \n",
     67                 (mDpy == 0) ? "\"PRIMARY\"" :
     68                 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
     69     dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
     70                 "fbCount:%2d \n", mCurrentFrame.layerCount,
     71                 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
     72     dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
     73                 (mCurrentFrame.needsRedraw? "YES" : "NO"),
     74                 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
     75     if(isDisplaySplit(ctx, mDpy)) {
     76         dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
     77                 "Right: [%d, %d, %d, %d] \n",
     78                 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
     79                 ctx->listStats[mDpy].lRoi.right,
     80                 ctx->listStats[mDpy].lRoi.bottom,
     81                 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
     82                 ctx->listStats[mDpy].rRoi.right,
     83                 ctx->listStats[mDpy].rRoi.bottom);
     84     } else {
     85         dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
     86                 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
     87                 ctx->listStats[mDpy].lRoi.right,
     88                 ctx->listStats[mDpy].lRoi.bottom);
     89     }
     90     dumpsys_log(buf," ---------------------------------------------  \n");
     91     dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
     92     dumpsys_log(buf," ---------------------------------------------  \n");
     93     for(int index = 0; index < mCurrentFrame.layerCount; index++ )
     94         dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
     95                     index,
     96                     (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
     97                      mCurrentFrame.layerToMDP[index],
     98                     (mCurrentFrame.isFBComposed[index] ?
     99                     (mCurrentFrame.drop[index] ? "DROP" :
    100                     (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
    101                     (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
    102     mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
    103     dumpsys_log(buf,"\n");
    104 }
    105 
    106 bool MDPComp::init(hwc_context_t *ctx) {
    107 
    108     if(!ctx) {
    109         ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
    110         return false;
    111     }
    112 
    113     char property[PROPERTY_VALUE_MAX];
    114 
    115     sEnabled = false;
    116     if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
    117        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    118         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    119         sEnabled = true;
    120     }
    121 
    122     sEnableMixedMode = true;
    123     if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
    124        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    125         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    126         sEnableMixedMode = false;
    127     }
    128 
    129     if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
    130         if(atoi(property) != 0)
    131             sDebugLogs = true;
    132     }
    133 
    134     sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
    135     if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
    136         int val = atoi(property);
    137         if(val >= 0)
    138             sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
    139     }
    140 
    141     if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
    142         // Idle invalidation is not necessary on command mode panels
    143         long idle_timeout = DEFAULT_IDLE_TIME;
    144         if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
    145             if(atoi(property) != 0)
    146                 idle_timeout = atoi(property);
    147         }
    148 
    149         //create Idle Invalidator only when not disabled through property
    150         if(idle_timeout != -1)
    151             idleInvalidator = IdleInvalidator::getInstance();
    152 
    153         if(idleInvalidator == NULL) {
    154             ALOGE("%s: failed to instantiate idleInvalidator object",
    155                   __FUNCTION__);
    156         } else {
    157             idleInvalidator->init(timeout_handler, ctx,
    158                                   (unsigned int)idle_timeout);
    159         }
    160     }
    161 
    162     if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
    163             property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
    164             (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
    165             !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
    166         sEnable4k2kYUVSplit = true;
    167     }
    168     return true;
    169 }
    170 
    171 void MDPComp::reset(hwc_context_t *ctx) {
    172     const int numLayers = ctx->listStats[mDpy].numAppLayers;
    173     mCurrentFrame.reset(numLayers);
    174     ctx->mOverlay->clear(mDpy);
    175     ctx->mLayerRotMap[mDpy]->clear();
    176 }
    177 
    178 void MDPComp::timeout_handler(void *udata) {
    179     struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
    180 
    181     if(!ctx) {
    182         ALOGE("%s: received empty data in timer callback", __FUNCTION__);
    183         return;
    184     }
    185     Locker::Autolock _l(ctx->mDrawLock);
    186     // Handle timeout event only if the previous composition is MDP or MIXED.
    187     if(!sHandleTimeout) {
    188         ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
    189         return;
    190     }
    191     if(!ctx->proc) {
    192         ALOGE("%s: HWC proc not registered", __FUNCTION__);
    193         return;
    194     }
    195     sIdleFallBack = true;
    196     /* Trigger SF to redraw the current frame */
    197     ctx->proc->invalidate(ctx->proc);
    198 }
    199 
    200 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
    201                                    hwc_display_contents_1_t* list) {
    202     LayerProp *layerProp = ctx->layerProp[mDpy];
    203 
    204     for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
    205         hwc_layer_1_t* layer = &(list->hwLayers[index]);
    206         if(!mCurrentFrame.isFBComposed[index]) {
    207             layerProp[index].mFlags |= HWC_MDPCOMP;
    208             layer->compositionType = HWC_OVERLAY;
    209             layer->hints |= HWC_HINT_CLEAR_FB;
    210         } else {
    211             /* Drop the layer when its already present in FB OR when it lies
    212              * outside frame's ROI */
    213             if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
    214                 layer->compositionType = HWC_OVERLAY;
    215             }
    216         }
    217     }
    218 }
    219 
    220 void MDPComp::setRedraw(hwc_context_t *ctx,
    221         hwc_display_contents_1_t* list) {
    222     mCurrentFrame.needsRedraw = false;
    223     if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
    224             (list->flags & HWC_GEOMETRY_CHANGED) ||
    225             isSkipPresent(ctx, mDpy)) {
    226         mCurrentFrame.needsRedraw = true;
    227     }
    228 }
    229 
    230 MDPComp::FrameInfo::FrameInfo() {
    231     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
    232     reset(0);
    233 }
    234 
    235 void MDPComp::FrameInfo::reset(const int& numLayers) {
    236     for(int i = 0 ; i < MAX_PIPES_PER_MIXER; i++ ) {
    237         if(mdpToLayer[i].pipeInfo) {
    238             delete mdpToLayer[i].pipeInfo;
    239             mdpToLayer[i].pipeInfo = NULL;
    240             //We dont own the rotator
    241             mdpToLayer[i].rot = NULL;
    242         }
    243     }
    244 
    245     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
    246     memset(&layerToMDP, -1, sizeof(layerToMDP));
    247     memset(&isFBComposed, 1, sizeof(isFBComposed));
    248 
    249     layerCount = numLayers;
    250     fbCount = numLayers;
    251     mdpCount = 0;
    252     needsRedraw = true;
    253     fbZ = -1;
    254 }
    255 
    256 void MDPComp::FrameInfo::map() {
    257     // populate layer and MDP maps
    258     int mdpIdx = 0;
    259     for(int idx = 0; idx < layerCount; idx++) {
    260         if(!isFBComposed[idx]) {
    261             mdpToLayer[mdpIdx].listIndex = idx;
    262             layerToMDP[idx] = mdpIdx++;
    263         }
    264     }
    265 }
    266 
    267 MDPComp::LayerCache::LayerCache() {
    268     reset();
    269 }
    270 
    271 void MDPComp::LayerCache::reset() {
    272     memset(&isFBComposed, true, sizeof(isFBComposed));
    273     memset(&drop, false, sizeof(drop));
    274     layerCount = 0;
    275 }
    276 
    277 void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
    278     layerCount = curFrame.layerCount;
    279     memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
    280     memcpy(&drop, &curFrame.drop, sizeof(drop));
    281 }
    282 
    283 bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
    284                                       hwc_display_contents_1_t* list) {
    285     if(layerCount != curFrame.layerCount)
    286         return false;
    287     for(int i = 0; i < curFrame.layerCount; i++) {
    288         if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
    289                 (curFrame.drop[i] != drop[i])) {
    290             return false;
    291         }
    292         hwc_layer_1_t const* layer = &list->hwLayers[i];
    293         if(curFrame.isFBComposed[i] && layerUpdating(layer)){
    294             return false;
    295         }
    296     }
    297     return true;
    298 }
    299 
    300 bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
    301     private_handle_t *hnd = (private_handle_t *)layer->handle;
    302     if((not isYuvBuffer(hnd) and has90Transform(layer)) or
    303         (not isValidDimension(ctx,layer))
    304         //More conditions here, SKIP, sRGB+Blend etc
    305         ) {
    306         return false;
    307     }
    308     return true;
    309 }
    310 
    311 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
    312     private_handle_t *hnd = (private_handle_t *)layer->handle;
    313 
    314     if(!hnd) {
    315         if (layer->flags & HWC_COLOR_FILL) {
    316             // Color layer
    317             return true;
    318         }
    319         ALOGE("%s: layer handle is NULL", __FUNCTION__);
    320         return false;
    321     }
    322 
    323     //XXX: Investigate doing this with pixel phase on MDSS
    324     if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
    325         return false;
    326 
    327     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    328     hwc_rect_t dst = layer->displayFrame;
    329     int crop_w = crop.right - crop.left;
    330     int crop_h = crop.bottom - crop.top;
    331     int dst_w = dst.right - dst.left;
    332     int dst_h = dst.bottom - dst.top;
    333     float w_scale = ((float)crop_w / (float)dst_w);
    334     float h_scale = ((float)crop_h / (float)dst_h);
    335 
    336     /* Workaround for MDP HW limitation in DSI command mode panels where
    337      * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
    338      * less than 5 pixels
    339      * There also is a HW limilation in MDP, minimum block size is 2x2
    340      * Fallback to GPU if height is less than 2.
    341      */
    342     if(qdutils::MDPVersion::getInstance().hasMinCropWidthLimitation() and
    343             (crop_w < 5 or crop_h < 5))
    344         return false;
    345 
    346     if((w_scale > 1.0f) || (h_scale > 1.0f)) {
    347         const uint32_t maxMDPDownscale =
    348             qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
    349         const float w_dscale = w_scale;
    350         const float h_dscale = h_scale;
    351 
    352         if(ctx->mMDP.version >= qdutils::MDSS_V5) {
    353 
    354             if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
    355                 /* On targets that doesnt support Decimation (eg.,8x26)
    356                  * maximum downscale support is overlay pipe downscale.
    357                  */
    358                 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
    359                         h_dscale > maxMDPDownscale)
    360                     return false;
    361             } else {
    362                 // Decimation on macrotile format layers is not supported.
    363                 if(isTileRendered(hnd)) {
    364                     /* MDP can read maximum MAX_DISPLAY_DIM width.
    365                      * Bail out if
    366                      *      1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
    367                      *      2. exceeds maximum downscale limit
    368                      */
    369                     if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
    370                             w_dscale > maxMDPDownscale ||
    371                             h_dscale > maxMDPDownscale) {
    372                         return false;
    373                     }
    374                 } else if(w_dscale > 64 || h_dscale > 64)
    375                     return false;
    376             }
    377         } else { //A-family
    378             if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
    379                 return false;
    380         }
    381     }
    382 
    383     if((w_scale < 1.0f) || (h_scale < 1.0f)) {
    384         const uint32_t upscale =
    385             qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
    386         const float w_uscale = 1.0f / w_scale;
    387         const float h_uscale = 1.0f / h_scale;
    388 
    389         if(w_uscale > upscale || h_uscale > upscale)
    390             return false;
    391     }
    392 
    393     return true;
    394 }
    395 
    396 bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
    397     bool ret = true;
    398 
    399     if(!isEnabled()) {
    400         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
    401         ret = false;
    402     } else if(qdutils::MDPVersion::getInstance().is8x26() &&
    403             ctx->mVideoTransFlag &&
    404             isSecondaryConnected(ctx)) {
    405         //1 Padding round to shift pipes across mixers
    406         ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
    407                 __FUNCTION__);
    408         ret = false;
    409     } else if(isSecondaryConfiguring(ctx)) {
    410         ALOGD_IF( isDebug(),"%s: External Display connection is pending",
    411                   __FUNCTION__);
    412         ret = false;
    413     } else if(ctx->isPaddingRound) {
    414         ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
    415                  __FUNCTION__,mDpy);
    416         ret = false;
    417     }
    418     return ret;
    419 }
    420 
    421 hwc_rect_t MDPComp::calculateDirtyRect(const hwc_layer_1_t* layer,
    422                     hwc_rect_t& scissor) {
    423   hwc_region_t surfDamage = layer->surfaceDamage;
    424   hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
    425   hwc_rect_t dst = layer->displayFrame;
    426   int x_off = dst.left - src.left;
    427   int y_off = dst.top - src.top;
    428   hwc_rect dirtyRect = (hwc_rect){0, 0, 0, 0};
    429   hwc_rect_t updatingRect = dst;
    430 
    431   if (surfDamage.numRects == 0) {
    432       // full layer updating, dirty rect is full frame
    433       dirtyRect = getIntersection(layer->displayFrame, scissor);
    434   } else {
    435       for(uint32_t i = 0; i < surfDamage.numRects; i++) {
    436           updatingRect = moveRect(surfDamage.rects[i], x_off, y_off);
    437           hwc_rect_t intersect = getIntersection(updatingRect, scissor);
    438           if(isValidRect(intersect)) {
    439               dirtyRect = getUnion(intersect, dirtyRect);
    440           }
    441       }
    442   }
    443 
    444   return dirtyRect;
    445 }
    446 
    447 void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
    448     hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
    449     fbRect = getIntersection(fbRect, roi);
    450 }
    451 
    452 /* 1) Identify layers that are not visible or lying outside the updating ROI and
    453  *    drop them from composition.
    454  * 2) If we have a scaling layer which needs cropping against generated
    455  *    ROI, reset ROI to full resolution. */
    456 bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
    457         hwc_display_contents_1_t* list) {
    458     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    459     hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
    460 
    461     for(int i = numAppLayers - 1; i >= 0; i--){
    462         if(!isValidRect(visibleRect)) {
    463             mCurrentFrame.drop[i] = true;
    464             mCurrentFrame.dropCount++;
    465             continue;
    466         }
    467 
    468         const hwc_layer_1_t* layer =  &list->hwLayers[i];
    469         hwc_rect_t dstRect = layer->displayFrame;
    470         hwc_rect_t res  = getIntersection(visibleRect, dstRect);
    471 
    472         if(!isValidRect(res)) {
    473             mCurrentFrame.drop[i] = true;
    474             mCurrentFrame.dropCount++;
    475         } else {
    476             /* Reset frame ROI when any layer which needs scaling also needs ROI
    477              * cropping */
    478             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
    479                 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
    480                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    481                 mCurrentFrame.dropCount = 0;
    482                 return false;
    483             }
    484 
    485             /* deduct any opaque region from visibleRect */
    486             if (layer->blending == HWC_BLENDING_NONE)
    487                 visibleRect = deductRect(visibleRect, res);
    488         }
    489     }
    490     return true;
    491 }
    492 
    493 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
    494  * are updating. If DirtyRegion is applicable, calculate it by accounting all
    495  * the changing layer's dirtyRegion. */
    496 void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
    497         hwc_display_contents_1_t* list) {
    498     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    499     if(!canPartialUpdate(ctx, list))
    500         return;
    501 
    502     struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
    503     hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
    504         (int)ctx->dpyAttr[mDpy].yres};
    505 
    506     for(int index = 0; index < numAppLayers; index++ ) {
    507         hwc_layer_1_t* layer = &list->hwLayers[index];
    508 
    509         if (layerUpdating(layer) ||
    510                 isYuvBuffer((private_handle_t *)layer->handle)) {
    511             hwc_rect_t dirtyRect = getIntersection(layer->displayFrame,
    512                                                     fullFrame);
    513             if(!needsScaling(layer) && !layer->transform) {
    514                 dirtyRect = calculateDirtyRect(layer, fullFrame);
    515             }
    516 
    517             roi = getUnion(roi, dirtyRect);
    518         }
    519     }
    520 
    521     /* No layer is updating. Still SF wants a refresh.*/
    522     if(!isValidRect(roi))
    523         return;
    524 
    525     // Align ROI coordinates to panel restrictions
    526     roi = getSanitizeROI(roi, fullFrame);
    527 
    528     ctx->listStats[mDpy].lRoi = roi;
    529     if(!validateAndApplyROI(ctx, list))
    530         resetROI(ctx, mDpy);
    531 
    532     ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
    533             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    534             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
    535 }
    536 
    537 void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
    538     hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
    539     hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
    540 
    541     hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
    542     hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
    543     fbRect = getUnion(l_fbRect, r_fbRect);
    544 }
    545 /* 1) Identify layers that are not visible or lying outside BOTH the updating
    546  *    ROI's and drop them from composition. If a layer is spanning across both
    547  *    the halves of the screen but needed by only ROI, the non-contributing
    548  *    half will not be programmed for MDP.
    549  * 2) If we have a scaling layer which needs cropping against generated
    550  *    ROI, reset ROI to full resolution. */
    551 bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
    552         hwc_display_contents_1_t* list) {
    553 
    554     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    555 
    556     hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
    557     hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
    558 
    559     for(int i = numAppLayers - 1; i >= 0; i--){
    560         if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
    561         {
    562             mCurrentFrame.drop[i] = true;
    563             mCurrentFrame.dropCount++;
    564             continue;
    565         }
    566 
    567         const hwc_layer_1_t* layer =  &list->hwLayers[i];
    568         hwc_rect_t dstRect = layer->displayFrame;
    569 
    570         hwc_rect_t l_res  = getIntersection(visibleRectL, dstRect);
    571         hwc_rect_t r_res  = getIntersection(visibleRectR, dstRect);
    572         hwc_rect_t res = getUnion(l_res, r_res);
    573 
    574         if(!isValidRect(l_res) && !isValidRect(r_res)) {
    575             mCurrentFrame.drop[i] = true;
    576             mCurrentFrame.dropCount++;
    577         } else {
    578             /* Reset frame ROI when any layer which needs scaling also needs ROI
    579              * cropping */
    580             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
    581                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    582                 mCurrentFrame.dropCount = 0;
    583                 return false;
    584             }
    585 
    586             if (layer->blending == HWC_BLENDING_NONE) {
    587                 visibleRectL = deductRect(visibleRectL, l_res);
    588                 visibleRectR = deductRect(visibleRectR, r_res);
    589             }
    590         }
    591     }
    592     return true;
    593 }
    594 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
    595  * are updating. If DirtyRegion is applicable, calculate it by accounting all
    596  * the changing layer's dirtyRegion. */
    597 void MDPCompSplit::generateROI(hwc_context_t *ctx,
    598         hwc_display_contents_1_t* list) {
    599     if(!canPartialUpdate(ctx, list))
    600         return;
    601 
    602     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    603     int lSplit = getLeftSplit(ctx, mDpy);
    604 
    605     int hw_h = (int)ctx->dpyAttr[mDpy].yres;
    606     int hw_w = (int)ctx->dpyAttr[mDpy].xres;
    607 
    608     struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
    609     struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
    610 
    611     struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
    612     struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
    613 
    614     for(int index = 0; index < numAppLayers; index++ ) {
    615         hwc_layer_1_t* layer = &list->hwLayers[index];
    616         private_handle_t *hnd = (private_handle_t *)layer->handle;
    617 
    618         if (layerUpdating(layer) || isYuvBuffer(hnd)) {
    619             hwc_rect_t l_dirtyRect = getIntersection(layer->displayFrame,
    620                                         l_frame);
    621             hwc_rect_t r_dirtyRect = getIntersection(layer->displayFrame,
    622                                         r_frame);
    623 
    624             if(!needsScaling(layer) && !layer->transform) {
    625                 l_dirtyRect = calculateDirtyRect(layer, l_frame);
    626                 r_dirtyRect = calculateDirtyRect(layer, r_frame);
    627             }
    628             if(isValidRect(l_dirtyRect))
    629                 l_roi = getUnion(l_roi, l_dirtyRect);
    630 
    631             if(isValidRect(r_dirtyRect))
    632                 r_roi = getUnion(r_roi, r_dirtyRect);
    633         }
    634     }
    635 
    636     /* For panels that cannot accept commands in both the interfaces, we cannot
    637      * send two ROI's (for each half). We merge them into single ROI and split
    638      * them across lSplit for MDP mixer use. The ROI's will be merged again
    639      * finally before udpating the panel in the driver. */
    640     if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
    641         hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
    642         l_roi = getIntersection(temp_roi, l_frame);
    643         r_roi = getIntersection(temp_roi, r_frame);
    644     }
    645 
    646     /* No layer is updating. Still SF wants a refresh. */
    647     if(!isValidRect(l_roi) && !isValidRect(r_roi))
    648         return;
    649 
    650     l_roi = getSanitizeROI(l_roi, l_frame);
    651     r_roi = getSanitizeROI(r_roi, r_frame);
    652 
    653     ctx->listStats[mDpy].lRoi = l_roi;
    654     ctx->listStats[mDpy].rRoi = r_roi;
    655 
    656     if(!validateAndApplyROI(ctx, list))
    657         resetROI(ctx, mDpy);
    658 
    659     ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
    660             "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
    661             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    662             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
    663             ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
    664             ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
    665 }
    666 
    667 /* Checks for conditions where all the layers marked for MDP comp cannot be
    668  * bypassed. On such conditions we try to bypass atleast YUV layers */
    669 bool MDPComp::tryFullFrame(hwc_context_t *ctx,
    670                                 hwc_display_contents_1_t* list){
    671 
    672     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    673     int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
    674 
    675     if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
    676         ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
    677         return false;
    678     }
    679 
    680     if(isSkipPresent(ctx, mDpy)) {
    681         ALOGD_IF(isDebug(),"%s: SKIP present: %d",
    682                 __FUNCTION__,
    683                 isSkipPresent(ctx, mDpy));
    684         return false;
    685     }
    686 
    687     if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
    688                               (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
    689         // Disable MDP comp on Secondary when the primary is highres panel and
    690         // the secondary is a normal 1080p, because, MDP comp on secondary under
    691         // in such usecase, decimation gets used for downscale and there will be
    692         // a quality mismatch when there will be a fallback to GPU comp
    693         ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
    694               __FUNCTION__);
    695         return false;
    696     }
    697 
    698     // check for action safe flag and downscale mode which requires scaling.
    699     if(ctx->dpyAttr[mDpy].mActionSafePresent
    700             || ctx->dpyAttr[mDpy].mDownScaleMode) {
    701         ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
    702         return false;
    703     }
    704 
    705     for(int i = 0; i < numAppLayers; ++i) {
    706         hwc_layer_1_t* layer = &list->hwLayers[i];
    707         private_handle_t *hnd = (private_handle_t *)layer->handle;
    708 
    709         if(isYuvBuffer(hnd) && has90Transform(layer)) {
    710             if(!canUseRotator(ctx, mDpy)) {
    711                 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
    712                         __FUNCTION__, mDpy);
    713                 return false;
    714             }
    715         }
    716 
    717         //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
    718         // may not need it if Gfx pre-rotation can handle all flips & rotations
    719         if(qdutils::MDPVersion::getInstance().is8x26() &&
    720                                 (ctx->dpyAttr[mDpy].xres > 1024) &&
    721                                 (layer->transform & HWC_TRANSFORM_FLIP_H) &&
    722                                 (!isYuvBuffer(hnd)))
    723                    return false;
    724     }
    725 
    726     if(ctx->mAD->isDoable()) {
    727         return false;
    728     }
    729 
    730     //If all above hard conditions are met we can do full or partial MDP comp.
    731     bool ret = false;
    732     if(fullMDPComp(ctx, list)) {
    733         ret = true;
    734     } else if(partialMDPComp(ctx, list)) {
    735         ret = true;
    736     }
    737 
    738     return ret;
    739 }
    740 
    741 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
    742 
    743     if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
    744         return false;
    745 
    746     //Will benefit presentation / secondary-only layer.
    747     if((mDpy > HWC_DISPLAY_PRIMARY) &&
    748             (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
    749         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
    750         return false;
    751     }
    752 
    753     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    754     for(int i = 0; i < numAppLayers; i++) {
    755         hwc_layer_1_t* layer = &list->hwLayers[i];
    756         if(not mCurrentFrame.drop[i] and
    757            not isSupportedForMDPComp(ctx, layer)) {
    758             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
    759             return false;
    760         }
    761 
    762         //For 8x26, if there is only one layer which needs scale for secondary
    763         //while no scale for primary display, DMA pipe is occupied by primary.
    764         //If need to fall back to GLES composition, virtual display lacks DMA
    765         //pipe and error is reported.
    766         if(qdutils::MDPVersion::getInstance().is8x26() &&
    767                                 mDpy >= HWC_DISPLAY_EXTERNAL &&
    768                                 qhwc::needsScaling(layer))
    769             return false;
    770     }
    771 
    772     mCurrentFrame.fbCount = 0;
    773     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
    774            sizeof(mCurrentFrame.isFBComposed));
    775     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
    776         mCurrentFrame.dropCount;
    777 
    778     if(sEnable4k2kYUVSplit){
    779         adjustForSourceSplit(ctx, list);
    780     }
    781 
    782     if(!postHeuristicsHandling(ctx, list)) {
    783         ALOGD_IF(isDebug(), "post heuristic handling failed");
    784         reset(ctx);
    785         return false;
    786     }
    787     ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
    788              __FUNCTION__);
    789     return true;
    790 }
    791 
    792 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
    793 {
    794     if(!sEnableMixedMode) {
    795         //Mixed mode is disabled. No need to even try caching.
    796         return false;
    797     }
    798 
    799     bool ret = false;
    800     if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
    801         ret =   loadBasedComp(ctx, list) or
    802                 cacheBasedComp(ctx, list);
    803     } else {
    804         ret =   cacheBasedComp(ctx, list) or
    805                 loadBasedComp(ctx, list);
    806     }
    807 
    808     return ret;
    809 }
    810 
    811 bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
    812         hwc_display_contents_1_t* list) {
    813     if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
    814         return false;
    815 
    816     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    817     mCurrentFrame.reset(numAppLayers);
    818     updateLayerCache(ctx, list);
    819 
    820     //If an MDP marked layer is unsupported cannot do partial MDP Comp
    821     for(int i = 0; i < numAppLayers; i++) {
    822         if(!mCurrentFrame.isFBComposed[i]) {
    823             hwc_layer_1_t* layer = &list->hwLayers[i];
    824             if(not isSupportedForMDPComp(ctx, layer)) {
    825                 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
    826                         __FUNCTION__);
    827                 reset(ctx);
    828                 return false;
    829             }
    830         }
    831     }
    832 
    833     updateYUV(ctx, list, false /*secure only*/);
    834     bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
    835     if(!ret) {
    836         ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
    837         reset(ctx);
    838         return false;
    839     }
    840 
    841     int mdpCount = mCurrentFrame.mdpCount;
    842 
    843     if(sEnable4k2kYUVSplit){
    844         adjustForSourceSplit(ctx, list);
    845     }
    846 
    847     //Will benefit cases where a video has non-updating background.
    848     if((mDpy > HWC_DISPLAY_PRIMARY) and
    849             (mdpCount > MAX_SEC_LAYERS)) {
    850         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
    851         reset(ctx);
    852         return false;
    853     }
    854 
    855     if(!postHeuristicsHandling(ctx, list)) {
    856         ALOGD_IF(isDebug(), "post heuristic handling failed");
    857         reset(ctx);
    858         return false;
    859     }
    860     ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
    861              __FUNCTION__);
    862 
    863     return true;
    864 }
    865 
    866 bool MDPComp::loadBasedComp(hwc_context_t *ctx,
    867         hwc_display_contents_1_t* list) {
    868     if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
    869         return false;
    870 
    871     if(not isLoadBasedCompDoable(ctx)) {
    872         return false;
    873     }
    874 
    875     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    876     const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
    877     const int stagesForMDP = min(sMaxPipesPerMixer,
    878             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
    879 
    880     int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
    881     int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
    882     int lastMDPSupportedIndex = numAppLayers;
    883     int dropCount = 0;
    884 
    885     //Find the minimum MDP batch size
    886     for(int i = 0; i < numAppLayers;i++) {
    887         if(mCurrentFrame.drop[i]) {
    888             dropCount++;
    889             continue;
    890         }
    891         hwc_layer_1_t* layer = &list->hwLayers[i];
    892         if(not isSupportedForMDPComp(ctx, layer)) {
    893             lastMDPSupportedIndex = i;
    894             mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
    895             fbBatchSize = numNonDroppedLayers - mdpBatchSize;
    896             break;
    897         }
    898     }
    899 
    900     ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
    901             "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
    902             mCurrentFrame.dropCount);
    903 
    904     //Start at a point where the fb batch should at least have 2 layers, for
    905     //this mode to be justified.
    906     while(fbBatchSize < 2) {
    907         ++fbBatchSize;
    908         --mdpBatchSize;
    909     }
    910 
    911     //If there are no layers for MDP, this mode doesnt make sense.
    912     if(mdpBatchSize < 1) {
    913         ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
    914                 __FUNCTION__);
    915         return false;
    916     }
    917 
    918     mCurrentFrame.reset(numAppLayers);
    919 
    920     //Try with successively smaller mdp batch sizes until we succeed or reach 1
    921     while(mdpBatchSize > 0) {
    922         //Mark layers for MDP comp
    923         int mdpBatchLeft = mdpBatchSize;
    924         for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
    925             if(mCurrentFrame.drop[i]) {
    926                 continue;
    927             }
    928             mCurrentFrame.isFBComposed[i] = false;
    929             --mdpBatchLeft;
    930         }
    931 
    932         mCurrentFrame.fbZ = mdpBatchSize;
    933         mCurrentFrame.fbCount = fbBatchSize;
    934         mCurrentFrame.mdpCount = mdpBatchSize;
    935 
    936         ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
    937                 __FUNCTION__, mdpBatchSize, fbBatchSize,
    938                 mCurrentFrame.dropCount);
    939 
    940         if(postHeuristicsHandling(ctx, list)) {
    941             ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
    942                      __FUNCTION__);
    943             ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
    944                      __FUNCTION__);
    945             return true;
    946         }
    947 
    948         reset(ctx);
    949         --mdpBatchSize;
    950         ++fbBatchSize;
    951     }
    952 
    953     return false;
    954 }
    955 
    956 bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
    957     if(mDpy or isSecurePresent(ctx, mDpy) or
    958             isYuvPresent(ctx, mDpy)) {
    959         return false;
    960     }
    961     return true;
    962 }
    963 
    964 bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
    965         hwc_display_contents_1_t* list){
    966     if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
    967             isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
    968             mDpy ) {
    969         return false;
    970     }
    971     return true;
    972 }
    973 
    974 bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
    975         hwc_display_contents_1_t* list) {
    976     const bool secureOnly = true;
    977     return videoOnlyComp(ctx, list, not secureOnly) or
    978             videoOnlyComp(ctx, list, secureOnly);
    979 }
    980 
    981 bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
    982         hwc_display_contents_1_t* list, bool secureOnly) {
    983     if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
    984         return false;
    985     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    986 
    987     mCurrentFrame.reset(numAppLayers);
    988     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
    989     updateYUV(ctx, list, secureOnly);
    990     int mdpCount = mCurrentFrame.mdpCount;
    991 
    992     if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
    993         reset(ctx);
    994         return false;
    995     }
    996 
    997     /* Bail out if we are processing only secured video layers
    998      * and we dont have any */
    999     if(!isSecurePresent(ctx, mDpy) && secureOnly){
   1000         reset(ctx);
   1001         return false;
   1002     }
   1003 
   1004     if(mCurrentFrame.fbCount)
   1005         mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
   1006 
   1007     if(sEnable4k2kYUVSplit){
   1008         adjustForSourceSplit(ctx, list);
   1009     }
   1010 
   1011     if(!postHeuristicsHandling(ctx, list)) {
   1012         ALOGD_IF(isDebug(), "post heuristic handling failed");
   1013         reset(ctx);
   1014         return false;
   1015     }
   1016 
   1017     ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
   1018              __FUNCTION__);
   1019     return true;
   1020 }
   1021 
   1022 /* Checks for conditions where YUV layers cannot be bypassed */
   1023 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
   1024     if(isSkipLayer(layer)) {
   1025         ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
   1026         return false;
   1027     }
   1028 
   1029     if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
   1030         ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
   1031         return false;
   1032     }
   1033 
   1034     if(isSecuring(ctx, layer)) {
   1035         ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
   1036         return false;
   1037     }
   1038 
   1039     if(!isValidDimension(ctx, layer)) {
   1040         ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
   1041             __FUNCTION__);
   1042         return false;
   1043     }
   1044 
   1045     if(layer->planeAlpha < 0xFF) {
   1046         ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
   1047                  in video only mode",
   1048                  __FUNCTION__);
   1049         return false;
   1050     }
   1051 
   1052     return true;
   1053 }
   1054 
   1055 /* starts at fromIndex and check for each layer to find
   1056  * if it it has overlapping with any Updating layer above it in zorder
   1057  * till the end of the batch. returns true if it finds any intersection */
   1058 bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
   1059         int fromIndex, int toIndex) {
   1060     for(int i = fromIndex; i < toIndex; i++) {
   1061         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1062             if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
   1063                 return false;
   1064             }
   1065         }
   1066     }
   1067     return true;
   1068 }
   1069 
   1070 /* Checks if given layer at targetLayerIndex has any
   1071  * intersection with all the updating layers in beween
   1072  * fromIndex and toIndex. Returns true if it finds intersectiion */
   1073 bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
   1074         int fromIndex, int toIndex, int targetLayerIndex) {
   1075     for(int i = fromIndex; i <= toIndex; i++) {
   1076         if(!mCurrentFrame.isFBComposed[i]) {
   1077             if(areLayersIntersecting(&list->hwLayers[i],
   1078                         &list->hwLayers[targetLayerIndex]))  {
   1079                 return true;
   1080             }
   1081         }
   1082     }
   1083     return false;
   1084 }
   1085 
   1086 int MDPComp::getBatch(hwc_display_contents_1_t* list,
   1087         int& maxBatchStart, int& maxBatchEnd,
   1088         int& maxBatchCount) {
   1089     int i = 0;
   1090     int fbZOrder =-1;
   1091     int droppedLayerCt = 0;
   1092     while (i < mCurrentFrame.layerCount) {
   1093         int batchCount = 0;
   1094         int batchStart = i;
   1095         int batchEnd = i;
   1096         /* Adjust batch Z order with the dropped layers so far */
   1097         int fbZ = batchStart - droppedLayerCt;
   1098         int firstZReverseIndex = -1;
   1099         int updatingLayersAbove = 0;//Updating layer count in middle of batch
   1100         while(i < mCurrentFrame.layerCount) {
   1101             if(!mCurrentFrame.isFBComposed[i]) {
   1102                 if(!batchCount) {
   1103                     i++;
   1104                     break;
   1105                 }
   1106                 updatingLayersAbove++;
   1107                 i++;
   1108                 continue;
   1109             } else {
   1110                 if(mCurrentFrame.drop[i]) {
   1111                     i++;
   1112                     droppedLayerCt++;
   1113                     continue;
   1114                 } else if(updatingLayersAbove <= 0) {
   1115                     batchCount++;
   1116                     batchEnd = i;
   1117                     i++;
   1118                     continue;
   1119                 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
   1120 
   1121                     // We have a valid updating layer already. If layer-i not
   1122                     // have overlapping with all updating layers in between
   1123                     // batch-start and i, then we can add layer i to batch.
   1124                     if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
   1125                         batchCount++;
   1126                         batchEnd = i;
   1127                         i++;
   1128                         continue;
   1129                     } else if(canPushBatchToTop(list, batchStart, i)) {
   1130                         //If All the non-updating layers with in this batch
   1131                         //does not have intersection with the updating layers
   1132                         //above in z-order, then we can safely move the batch to
   1133                         //higher z-order. Increment fbZ as it is moving up.
   1134                         if( firstZReverseIndex < 0) {
   1135                             firstZReverseIndex = i;
   1136                         }
   1137                         batchCount++;
   1138                         batchEnd = i;
   1139                         fbZ += updatingLayersAbove;
   1140                         i++;
   1141                         updatingLayersAbove = 0;
   1142                         continue;
   1143                     } else {
   1144                         //both failed.start the loop again from here.
   1145                         if(firstZReverseIndex >= 0) {
   1146                             i = firstZReverseIndex;
   1147                         }
   1148                         break;
   1149                     }
   1150                 }
   1151             }
   1152         }
   1153         if(batchCount > maxBatchCount) {
   1154             maxBatchCount = batchCount;
   1155             maxBatchStart = batchStart;
   1156             maxBatchEnd = batchEnd;
   1157             fbZOrder = fbZ;
   1158         }
   1159     }
   1160     return fbZOrder;
   1161 }
   1162 
   1163 bool  MDPComp::markLayersForCaching(hwc_context_t* ctx,
   1164         hwc_display_contents_1_t* list) {
   1165     /* Idea is to keep as many non-updating(cached) layers in FB and
   1166      * send rest of them through MDP. This is done in 2 steps.
   1167      *   1. Find the maximum contiguous batch of non-updating layers.
   1168      *   2. See if we can improve this batch size for caching by adding
   1169      *      opaque layers around the batch, if they don't have
   1170      *      any overlapping with the updating layers in between.
   1171      * NEVER mark an updating layer for caching.
   1172      * But cached ones can be marked for MDP */
   1173 
   1174     int maxBatchStart = -1;
   1175     int maxBatchEnd = -1;
   1176     int maxBatchCount = 0;
   1177     int fbZ = -1;
   1178 
   1179     /* Nothing is cached. No batching needed */
   1180     if(mCurrentFrame.fbCount == 0) {
   1181         return true;
   1182     }
   1183 
   1184     /* No MDP comp layers, try to use other comp modes */
   1185     if(mCurrentFrame.mdpCount == 0) {
   1186         return false;
   1187     }
   1188 
   1189     fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
   1190 
   1191     /* reset rest of the layers lying inside ROI for MDP comp */
   1192     for(int i = 0; i < mCurrentFrame.layerCount; i++) {
   1193         hwc_layer_1_t* layer = &list->hwLayers[i];
   1194         if((i < maxBatchStart || i > maxBatchEnd) &&
   1195                 mCurrentFrame.isFBComposed[i]){
   1196             if(!mCurrentFrame.drop[i]){
   1197                 //If an unsupported layer is being attempted to
   1198                 //be pulled out we should fail
   1199                 if(not isSupportedForMDPComp(ctx, layer)) {
   1200                     return false;
   1201                 }
   1202                 mCurrentFrame.isFBComposed[i] = false;
   1203             }
   1204         }
   1205     }
   1206 
   1207     // update the frame data
   1208     mCurrentFrame.fbZ = fbZ;
   1209     mCurrentFrame.fbCount = maxBatchCount;
   1210     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1211             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1212 
   1213     ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
   1214             mCurrentFrame.fbCount);
   1215 
   1216     return true;
   1217 }
   1218 
   1219 void MDPComp::updateLayerCache(hwc_context_t* ctx,
   1220         hwc_display_contents_1_t* list) {
   1221     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1222     int fbCount = 0;
   1223 
   1224     for(int i = 0; i < numAppLayers; i++) {
   1225         hwc_layer_1_t * layer = &list->hwLayers[i];
   1226         if (!layerUpdating(layer)) {
   1227             if(!mCurrentFrame.drop[i])
   1228                 fbCount++;
   1229             mCurrentFrame.isFBComposed[i] = true;
   1230         } else {
   1231             mCurrentFrame.isFBComposed[i] = false;
   1232         }
   1233     }
   1234 
   1235     mCurrentFrame.fbCount = fbCount;
   1236     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
   1237                                                     - mCurrentFrame.dropCount;
   1238 
   1239     ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
   1240              ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
   1241             mCurrentFrame.dropCount);
   1242 }
   1243 
   1244 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
   1245         bool secureOnly) {
   1246     int nYuvCount = ctx->listStats[mDpy].yuvCount;
   1247     for(int index = 0;index < nYuvCount; index++){
   1248         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
   1249         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
   1250 
   1251         if(!isYUVDoable(ctx, layer)) {
   1252             if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
   1253                 mCurrentFrame.isFBComposed[nYuvIndex] = true;
   1254                 mCurrentFrame.fbCount++;
   1255             }
   1256         } else {
   1257             if(mCurrentFrame.isFBComposed[nYuvIndex]) {
   1258                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1259                 if(!secureOnly || isSecureBuffer(hnd)) {
   1260                     mCurrentFrame.isFBComposed[nYuvIndex] = false;
   1261                     mCurrentFrame.fbCount--;
   1262                 }
   1263             }
   1264         }
   1265     }
   1266 
   1267     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1268             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1269     ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
   1270              mCurrentFrame.fbCount);
   1271 }
   1272 
   1273 hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
   1274         hwc_display_contents_1_t* list){
   1275     hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
   1276 
   1277     /* Update only the region of FB needed for composition */
   1278     for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
   1279         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1280             hwc_layer_1_t* layer = &list->hwLayers[i];
   1281             hwc_rect_t dst = layer->displayFrame;
   1282             fbRect = getUnion(fbRect, dst);
   1283         }
   1284     }
   1285     trimAgainstROI(ctx, fbRect);
   1286     return fbRect;
   1287 }
   1288 
   1289 bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
   1290         hwc_display_contents_1_t* list) {
   1291 
   1292     //Capability checks
   1293     if(!resourceCheck()) {
   1294         ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
   1295         return false;
   1296     }
   1297 
   1298     //Limitations checks
   1299     if(!hwLimitationsCheck(ctx, list)) {
   1300         ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
   1301         return false;
   1302     }
   1303 
   1304     //Configure framebuffer first if applicable
   1305     if(mCurrentFrame.fbZ >= 0) {
   1306         hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
   1307         if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
   1308         {
   1309             ALOGD_IF(isDebug(), "%s configure framebuffer failed",
   1310                     __FUNCTION__);
   1311             return false;
   1312         }
   1313     }
   1314 
   1315     mCurrentFrame.map();
   1316 
   1317     if(!allocLayerPipes(ctx, list)) {
   1318         ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
   1319         return false;
   1320     }
   1321 
   1322     for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1323             index++) {
   1324         if(!mCurrentFrame.isFBComposed[index]) {
   1325             int mdpIndex = mCurrentFrame.layerToMDP[index];
   1326             hwc_layer_1_t* layer = &list->hwLayers[index];
   1327 
   1328             //Leave fbZ for framebuffer. CACHE/GLES layers go here.
   1329             if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1330                 mdpNextZOrder++;
   1331             }
   1332             MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1333             cur_pipe->zOrder = mdpNextZOrder++;
   1334 
   1335             private_handle_t *hnd = (private_handle_t *)layer->handle;
   1336             if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1337                 if(configure4k2kYuv(ctx, layer,
   1338                             mCurrentFrame.mdpToLayer[mdpIndex])
   1339                         != 0 ){
   1340                     ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
   1341                             for layer %d",__FUNCTION__, index);
   1342                     return false;
   1343                 }
   1344                 else{
   1345                     mdpNextZOrder++;
   1346                 }
   1347                 continue;
   1348             }
   1349             if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
   1350                 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
   1351                         layer %d",__FUNCTION__, index);
   1352                 return false;
   1353             }
   1354         }
   1355     }
   1356 
   1357     if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
   1358         ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
   1359                 ,__FUNCTION__, mDpy);
   1360         return false;
   1361     }
   1362 
   1363     setRedraw(ctx, list);
   1364     return true;
   1365 }
   1366 
   1367 bool MDPComp::resourceCheck() {
   1368     const bool fbUsed = mCurrentFrame.fbCount;
   1369     if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
   1370         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
   1371         return false;
   1372     }
   1373     return true;
   1374 }
   1375 
   1376 bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
   1377         hwc_display_contents_1_t* list) {
   1378 
   1379     //A-family hw limitation:
   1380     //If a layer need alpha scaling, MDP can not support.
   1381     if(ctx->mMDP.version < qdutils::MDSS_V5) {
   1382         for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
   1383             if(!mCurrentFrame.isFBComposed[i] &&
   1384                     isAlphaScaled( &list->hwLayers[i])) {
   1385                 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
   1386                 return false;
   1387             }
   1388         }
   1389     }
   1390 
   1391     // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
   1392     //If multiple layers requires downscaling and also they are overlapping
   1393     //fall back to GPU since MDSS can not handle it.
   1394     if(qdutils::MDPVersion::getInstance().is8x74v2() ||
   1395             qdutils::MDPVersion::getInstance().is8x26()) {
   1396         for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
   1397             hwc_layer_1_t* botLayer = &list->hwLayers[i];
   1398             if(!mCurrentFrame.isFBComposed[i] &&
   1399                     isDownscaleRequired(botLayer)) {
   1400                 //if layer-i is marked for MDP and needs downscaling
   1401                 //check if any MDP layer on top of i & overlaps with layer-i
   1402                 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
   1403                     hwc_layer_1_t* topLayer = &list->hwLayers[j];
   1404                     if(!mCurrentFrame.isFBComposed[j] &&
   1405                             isDownscaleRequired(topLayer)) {
   1406                         hwc_rect_t r = getIntersection(botLayer->displayFrame,
   1407                                 topLayer->displayFrame);
   1408                         if(isValidRect(r))
   1409                             return false;
   1410                     }
   1411                 }
   1412             }
   1413         }
   1414     }
   1415     return true;
   1416 }
   1417 
   1418 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1419     int ret = 0;
   1420     const int numLayers = ctx->listStats[mDpy].numAppLayers;
   1421     char property[PROPERTY_VALUE_MAX];
   1422 
   1423     if(property_get("debug.hwc.simulate", property, NULL) > 0) {
   1424         int currentFlags = atoi(property);
   1425         if(currentFlags != sSimulationFlags) {
   1426             sSimulationFlags = currentFlags;
   1427             ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
   1428                     sSimulationFlags, sSimulationFlags);
   1429         }
   1430     }
   1431 
   1432     //Do not cache the information for next draw cycle.
   1433     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
   1434         ALOGI("%s: Unsupported layer count for mdp composition",
   1435                 __FUNCTION__);
   1436         mCachedFrame.reset();
   1437         return -1;
   1438     }
   1439 
   1440     //reset old data
   1441     mCurrentFrame.reset(numLayers);
   1442     memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   1443     mCurrentFrame.dropCount = 0;
   1444 
   1445     // Detect the start of animation and fall back to GPU only once to cache
   1446     // all the layers in FB and display FB content untill animation completes.
   1447     if(ctx->listStats[mDpy].isDisplayAnimating) {
   1448         mCurrentFrame.needsRedraw = false;
   1449         if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
   1450             mCurrentFrame.needsRedraw = true;
   1451             ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
   1452         }
   1453         setMDPCompLayerFlags(ctx, list);
   1454         mCachedFrame.updateCounts(mCurrentFrame);
   1455         ret = -1;
   1456         return ret;
   1457     } else {
   1458         ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
   1459     }
   1460 
   1461     //Hard conditions, if not met, cannot do MDP comp
   1462     if(isFrameDoable(ctx)) {
   1463         generateROI(ctx, list);
   1464 
   1465         if(tryFullFrame(ctx, list) || tryVideoOnly(ctx, list)) {
   1466             setMDPCompLayerFlags(ctx, list);
   1467         } else {
   1468             resetROI(ctx, mDpy);
   1469             reset(ctx);
   1470             memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   1471             mCurrentFrame.dropCount = 0;
   1472             ret = -1;
   1473         }
   1474     } else {
   1475         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
   1476                 __FUNCTION__);
   1477         ret = -1;
   1478     }
   1479 
   1480     if(isDebug()) {
   1481         ALOGD("GEOMETRY change: %d",
   1482                 (list->flags & HWC_GEOMETRY_CHANGED));
   1483         android::String8 sDump("");
   1484         dump(sDump, ctx);
   1485         ALOGD("%s",sDump.string());
   1486     }
   1487 
   1488     mCachedFrame.updateCounts(mCurrentFrame);
   1489     return ret;
   1490 }
   1491 
   1492 bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
   1493 
   1494     bool bRet = true;
   1495     int mdpIndex = mCurrentFrame.layerToMDP[index];
   1496     PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1497     info.pipeInfo = new MdpYUVPipeInfo;
   1498     info.rot = NULL;
   1499     MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
   1500 
   1501     pipe_info.lIndex = ovutils::OV_INVALID;
   1502     pipe_info.rIndex = ovutils::OV_INVALID;
   1503 
   1504     Overlay::PipeSpecs pipeSpecs;
   1505     pipeSpecs.formatClass = Overlay::FORMAT_YUV;
   1506     pipeSpecs.needsScaling = true;
   1507     pipeSpecs.dpy = mDpy;
   1508     pipeSpecs.fb = false;
   1509 
   1510     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1511     if(pipe_info.lIndex == ovutils::OV_INVALID){
   1512         bRet = false;
   1513         ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
   1514                 __FUNCTION__);
   1515     }
   1516     pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1517     if(pipe_info.rIndex == ovutils::OV_INVALID){
   1518         bRet = false;
   1519         ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
   1520                 __FUNCTION__);
   1521     }
   1522     return bRet;
   1523 }
   1524 //=============MDPCompNonSplit==================================================
   1525 
   1526 void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
   1527         hwc_display_contents_1_t* list) {
   1528     //If 4k2k Yuv layer split is possible,  and if
   1529     //fbz is above 4k2k layer, increment fb zorder by 1
   1530     //as we split 4k2k layer and increment zorder for right half
   1531     //of the layer
   1532     if(mCurrentFrame.fbZ >= 0) {
   1533         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1534                 index++) {
   1535             if(!mCurrentFrame.isFBComposed[index]) {
   1536                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1537                     mdpNextZOrder++;
   1538                 }
   1539                 mdpNextZOrder++;
   1540                 hwc_layer_1_t* layer = &list->hwLayers[index];
   1541                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1542                 if(is4kx2kYuvBuffer(hnd)) {
   1543                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   1544                         mCurrentFrame.fbZ += 1;
   1545                     mdpNextZOrder++;
   1546                     //As we split 4kx2k yuv layer and program to 2 VG pipes
   1547                     //(if available) increase mdpcount by 1.
   1548                     mCurrentFrame.mdpCount++;
   1549                 }
   1550             }
   1551         }
   1552     }
   1553 }
   1554 
   1555 /*
   1556  * Configures pipe(s) for MDP composition
   1557  */
   1558 int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1559                              PipeLayerPair& PipeLayerPair) {
   1560     MdpPipeInfoNonSplit& mdp_info =
   1561         *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
   1562     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   1563     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1564     eIsFg isFg = IS_FG_OFF;
   1565     eDest dest = mdp_info.index;
   1566 
   1567     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
   1568              __FUNCTION__, layer, zOrder, dest);
   1569 
   1570     return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
   1571                            &PipeLayerPair.rot);
   1572 }
   1573 
   1574 bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
   1575         hwc_display_contents_1_t* list) {
   1576     for(int index = 0; index < mCurrentFrame.layerCount; index++) {
   1577 
   1578         if(mCurrentFrame.isFBComposed[index]) continue;
   1579 
   1580         hwc_layer_1_t* layer = &list->hwLayers[index];
   1581         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1582         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1583             if(allocSplitVGPipesfor4k2k(ctx, index)){
   1584                 continue;
   1585             }
   1586         }
   1587 
   1588         int mdpIndex = mCurrentFrame.layerToMDP[index];
   1589         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1590         info.pipeInfo = new MdpPipeInfoNonSplit;
   1591         info.rot = NULL;
   1592         MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
   1593 
   1594         Overlay::PipeSpecs pipeSpecs;
   1595         pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   1596                 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   1597         pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
   1598                 (qdutils::MDPVersion::getInstance().is8x26() and
   1599                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
   1600         pipeSpecs.dpy = mDpy;
   1601         pipeSpecs.fb = false;
   1602 
   1603         pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
   1604 
   1605         if(pipe_info.index == ovutils::OV_INVALID) {
   1606             ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
   1607             return false;
   1608         }
   1609     }
   1610     return true;
   1611 }
   1612 
   1613 int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1614         PipeLayerPair& PipeLayerPair) {
   1615     MdpYUVPipeInfo& mdp_info =
   1616             *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   1617     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1618     eIsFg isFg = IS_FG_OFF;
   1619     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1620     eDest lDest = mdp_info.lIndex;
   1621     eDest rDest = mdp_info.rIndex;
   1622 
   1623     return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
   1624             lDest, rDest, &PipeLayerPair.rot);
   1625 }
   1626 
   1627 bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1628 
   1629     if(!isEnabled()) {
   1630         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
   1631         return true;
   1632     }
   1633 
   1634     if(!ctx || !list) {
   1635         ALOGE("%s: invalid contxt or list",__FUNCTION__);
   1636         return false;
   1637     }
   1638 
   1639     if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
   1640         ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
   1641         return true;
   1642     }
   1643 
   1644     // Set the Handle timeout to true for MDP or MIXED composition.
   1645     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
   1646         sHandleTimeout = true;
   1647     }
   1648 
   1649     overlay::Overlay& ov = *ctx->mOverlay;
   1650     LayerProp *layerProp = ctx->layerProp[mDpy];
   1651 
   1652     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   1653     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   1654     {
   1655         if(mCurrentFrame.isFBComposed[i]) continue;
   1656 
   1657         hwc_layer_1_t *layer = &list->hwLayers[i];
   1658         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1659         if(!hnd) {
   1660             if (!(layer->flags & HWC_COLOR_FILL)) {
   1661                 ALOGE("%s handle null", __FUNCTION__);
   1662                 return false;
   1663             }
   1664             // No PLAY for Color layer
   1665             layerProp[i].mFlags &= ~HWC_MDPCOMP;
   1666             continue;
   1667         }
   1668 
   1669         int mdpIndex = mCurrentFrame.layerToMDP[i];
   1670 
   1671         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
   1672         {
   1673             MdpYUVPipeInfo& pipe_info =
   1674                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1675             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1676             ovutils::eDest indexL = pipe_info.lIndex;
   1677             ovutils::eDest indexR = pipe_info.rIndex;
   1678             int fd = hnd->fd;
   1679             uint32_t offset = (uint32_t)hnd->offset;
   1680             if(rot) {
   1681                 rot->queueBuffer(fd, offset);
   1682                 fd = rot->getDstMemId();
   1683                 offset = rot->getDstOffset();
   1684             }
   1685             if(indexL != ovutils::OV_INVALID) {
   1686                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1687                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1688                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1689                 if (!ov.queueBuffer(fd, offset, destL)) {
   1690                     ALOGE("%s: queueBuffer failed for display:%d",
   1691                             __FUNCTION__, mDpy);
   1692                     return false;
   1693                 }
   1694             }
   1695 
   1696             if(indexR != ovutils::OV_INVALID) {
   1697                 ovutils::eDest destR = (ovutils::eDest)indexR;
   1698                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1699                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   1700                 if (!ov.queueBuffer(fd, offset, destR)) {
   1701                     ALOGE("%s: queueBuffer failed for display:%d",
   1702                             __FUNCTION__, mDpy);
   1703                     return false;
   1704                 }
   1705             }
   1706         }
   1707         else{
   1708             MdpPipeInfoNonSplit& pipe_info =
   1709             *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1710             ovutils::eDest dest = pipe_info.index;
   1711             if(dest == ovutils::OV_INVALID) {
   1712                 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
   1713                 return false;
   1714             }
   1715 
   1716             if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   1717                 continue;
   1718             }
   1719 
   1720             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1721                     using  pipe: %d", __FUNCTION__, layer,
   1722                     hnd, dest );
   1723 
   1724             int fd = hnd->fd;
   1725             uint32_t offset = (uint32_t)hnd->offset;
   1726 
   1727             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1728             if(rot) {
   1729                 if(!rot->queueBuffer(fd, offset))
   1730                     return false;
   1731                 fd = rot->getDstMemId();
   1732                 offset = rot->getDstOffset();
   1733             }
   1734 
   1735             if (!ov.queueBuffer(fd, offset, dest)) {
   1736                 ALOGE("%s: queueBuffer failed for display:%d ",
   1737                         __FUNCTION__, mDpy);
   1738                 return false;
   1739             }
   1740         }
   1741 
   1742         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   1743     }
   1744     return true;
   1745 }
   1746 
   1747 //=============MDPCompSplit===================================================
   1748 
   1749 void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
   1750          hwc_display_contents_1_t* list){
   1751     //if 4kx2k yuv layer is totally present in either in left half
   1752     //or right half then try splitting the yuv layer to avoid decimation
   1753     const int lSplit = getLeftSplit(ctx, mDpy);
   1754     if(mCurrentFrame.fbZ >= 0) {
   1755         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1756                 index++) {
   1757             if(!mCurrentFrame.isFBComposed[index]) {
   1758                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1759                     mdpNextZOrder++;
   1760                 }
   1761                 mdpNextZOrder++;
   1762                 hwc_layer_1_t* layer = &list->hwLayers[index];
   1763                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1764                 if(is4kx2kYuvBuffer(hnd)) {
   1765                     hwc_rect_t dst = layer->displayFrame;
   1766                     if((dst.left > lSplit) || (dst.right < lSplit)) {
   1767                         mCurrentFrame.mdpCount += 1;
   1768                     }
   1769                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   1770                         mCurrentFrame.fbZ += 1;
   1771                     mdpNextZOrder++;
   1772                 }
   1773             }
   1774         }
   1775     }
   1776 }
   1777 
   1778 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   1779         MdpPipeInfoSplit& pipe_info) {
   1780 
   1781     const int lSplit = getLeftSplit(ctx, mDpy);
   1782     private_handle_t *hnd = (private_handle_t *)layer->handle;
   1783     hwc_rect_t dst = layer->displayFrame;
   1784     pipe_info.lIndex = ovutils::OV_INVALID;
   1785     pipe_info.rIndex = ovutils::OV_INVALID;
   1786 
   1787     Overlay::PipeSpecs pipeSpecs;
   1788     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   1789             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   1790     pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
   1791     pipeSpecs.dpy = mDpy;
   1792     pipeSpecs.mixer = Overlay::MIXER_LEFT;
   1793     pipeSpecs.fb = false;
   1794 
   1795     // Acquire pipe only for the updating half
   1796     hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
   1797     hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
   1798 
   1799     if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
   1800         pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1801         if(pipe_info.lIndex == ovutils::OV_INVALID)
   1802             return false;
   1803     }
   1804 
   1805     if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
   1806         pipeSpecs.mixer = Overlay::MIXER_RIGHT;
   1807         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1808         if(pipe_info.rIndex == ovutils::OV_INVALID)
   1809             return false;
   1810     }
   1811 
   1812     return true;
   1813 }
   1814 
   1815 bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
   1816         hwc_display_contents_1_t* list) {
   1817     for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
   1818 
   1819         if(mCurrentFrame.isFBComposed[index]) continue;
   1820 
   1821         hwc_layer_1_t* layer = &list->hwLayers[index];
   1822         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1823         hwc_rect_t dst = layer->displayFrame;
   1824         const int lSplit = getLeftSplit(ctx, mDpy);
   1825         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1826             if((dst.left > lSplit)||(dst.right < lSplit)){
   1827                 if(allocSplitVGPipesfor4k2k(ctx, index)){
   1828                     continue;
   1829                 }
   1830             }
   1831         }
   1832         int mdpIndex = mCurrentFrame.layerToMDP[index];
   1833         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1834         info.pipeInfo = new MdpPipeInfoSplit;
   1835         info.rot = NULL;
   1836         MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
   1837 
   1838         if(!acquireMDPPipes(ctx, layer, pipe_info)) {
   1839             ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
   1840                     __FUNCTION__);
   1841             return false;
   1842         }
   1843     }
   1844     return true;
   1845 }
   1846 
   1847 int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1848         PipeLayerPair& PipeLayerPair) {
   1849     const int lSplit = getLeftSplit(ctx, mDpy);
   1850     hwc_rect_t dst = layer->displayFrame;
   1851     if((dst.left > lSplit)||(dst.right < lSplit)){
   1852         MdpYUVPipeInfo& mdp_info =
   1853                 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   1854         eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1855         eIsFg isFg = IS_FG_OFF;
   1856         eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1857         eDest lDest = mdp_info.lIndex;
   1858         eDest rDest = mdp_info.rIndex;
   1859 
   1860         return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
   1861                 lDest, rDest, &PipeLayerPair.rot);
   1862     }
   1863     else{
   1864         return configure(ctx, layer, PipeLayerPair);
   1865     }
   1866 }
   1867 
   1868 /*
   1869  * Configures pipe(s) for MDP composition
   1870  */
   1871 int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1872         PipeLayerPair& PipeLayerPair) {
   1873     MdpPipeInfoSplit& mdp_info =
   1874         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   1875     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1876     eIsFg isFg = IS_FG_OFF;
   1877     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1878     eDest lDest = mdp_info.lIndex;
   1879     eDest rDest = mdp_info.rIndex;
   1880 
   1881     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   1882              "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
   1883 
   1884     return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
   1885                             rDest, &PipeLayerPair.rot);
   1886 }
   1887 
   1888 bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1889 
   1890     if(!isEnabled()) {
   1891         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
   1892         return true;
   1893     }
   1894 
   1895     if(!ctx || !list) {
   1896         ALOGE("%s: invalid contxt or list",__FUNCTION__);
   1897         return false;
   1898     }
   1899 
   1900     if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
   1901         ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
   1902         return true;
   1903     }
   1904 
   1905     // Set the Handle timeout to true for MDP or MIXED composition.
   1906     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
   1907         sHandleTimeout = true;
   1908     }
   1909 
   1910     overlay::Overlay& ov = *ctx->mOverlay;
   1911     LayerProp *layerProp = ctx->layerProp[mDpy];
   1912 
   1913     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   1914     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   1915     {
   1916         if(mCurrentFrame.isFBComposed[i]) continue;
   1917 
   1918         hwc_layer_1_t *layer = &list->hwLayers[i];
   1919         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1920         if(!hnd) {
   1921             ALOGE("%s handle null", __FUNCTION__);
   1922             return false;
   1923         }
   1924 
   1925         if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   1926             continue;
   1927         }
   1928 
   1929         int mdpIndex = mCurrentFrame.layerToMDP[i];
   1930 
   1931         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
   1932         {
   1933             MdpYUVPipeInfo& pipe_info =
   1934                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1935             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1936             ovutils::eDest indexL = pipe_info.lIndex;
   1937             ovutils::eDest indexR = pipe_info.rIndex;
   1938             int fd = hnd->fd;
   1939             uint32_t offset = (uint32_t)hnd->offset;
   1940             if(rot) {
   1941                 rot->queueBuffer(fd, offset);
   1942                 fd = rot->getDstMemId();
   1943                 offset = rot->getDstOffset();
   1944             }
   1945             if(indexL != ovutils::OV_INVALID) {
   1946                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1947                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1948                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1949                 if (!ov.queueBuffer(fd, offset, destL)) {
   1950                     ALOGE("%s: queueBuffer failed for display:%d",
   1951                             __FUNCTION__, mDpy);
   1952                     return false;
   1953                 }
   1954             }
   1955 
   1956             if(indexR != ovutils::OV_INVALID) {
   1957                 ovutils::eDest destR = (ovutils::eDest)indexR;
   1958                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1959                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   1960                 if (!ov.queueBuffer(fd, offset, destR)) {
   1961                     ALOGE("%s: queueBuffer failed for display:%d",
   1962                             __FUNCTION__, mDpy);
   1963                     return false;
   1964                 }
   1965             }
   1966         }
   1967         else{
   1968             MdpPipeInfoSplit& pipe_info =
   1969                 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1970             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1971 
   1972             ovutils::eDest indexL = pipe_info.lIndex;
   1973             ovutils::eDest indexR = pipe_info.rIndex;
   1974 
   1975             int fd = hnd->fd;
   1976             int offset = (uint32_t)hnd->offset;
   1977 
   1978             if(ctx->mAD->isModeOn()) {
   1979                 if(ctx->mAD->draw(ctx, fd, offset)) {
   1980                     fd = ctx->mAD->getDstFd();
   1981                     offset = ctx->mAD->getDstOffset();
   1982                 }
   1983             }
   1984 
   1985             if(rot) {
   1986                 rot->queueBuffer(fd, offset);
   1987                 fd = rot->getDstMemId();
   1988                 offset = rot->getDstOffset();
   1989             }
   1990 
   1991             //************* play left mixer **********
   1992             if(indexL != ovutils::OV_INVALID) {
   1993                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1994                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1995                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1996                 if (!ov.queueBuffer(fd, offset, destL)) {
   1997                     ALOGE("%s: queueBuffer failed for left mixer",
   1998                             __FUNCTION__);
   1999                     return false;
   2000                 }
   2001             }
   2002 
   2003             //************* play right mixer **********
   2004             if(indexR != ovutils::OV_INVALID) {
   2005                 ovutils::eDest destR = (ovutils::eDest)indexR;
   2006                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2007                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   2008                 if (!ov.queueBuffer(fd, offset, destR)) {
   2009                     ALOGE("%s: queueBuffer failed for right mixer",
   2010                             __FUNCTION__);
   2011                     return false;
   2012                 }
   2013             }
   2014         }
   2015 
   2016         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   2017     }
   2018 
   2019     return true;
   2020 }
   2021 
   2022 //================MDPCompSrcSplit==============================================
   2023 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   2024         MdpPipeInfoSplit& pipe_info) {
   2025     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2026     hwc_rect_t dst = layer->displayFrame;
   2027     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2028     pipe_info.lIndex = ovutils::OV_INVALID;
   2029     pipe_info.rIndex = ovutils::OV_INVALID;
   2030 
   2031     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
   2032     //should have a higher priority than the right one. Pipe priorities are
   2033     //starting with VG0, VG1 ... , RGB0 ..., DMA1
   2034 
   2035     Overlay::PipeSpecs pipeSpecs;
   2036     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   2037             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   2038     pipeSpecs.needsScaling = qhwc::needsScaling(layer);
   2039     pipeSpecs.dpy = mDpy;
   2040     pipeSpecs.fb = false;
   2041 
   2042     //1 pipe by default for a layer
   2043     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2044     if(pipe_info.lIndex == ovutils::OV_INVALID) {
   2045         return false;
   2046     }
   2047 
   2048     /* Use 2 pipes IF
   2049         a) Layer's crop width is > 2048 or
   2050         b) Layer's dest width > 2048 or
   2051         c) On primary, driver has indicated with caps to split always. This is
   2052            based on an empirically derived value of panel height. Applied only
   2053            if the layer's width is > mixer's width
   2054     */
   2055 
   2056     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
   2057             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
   2058     int lSplit = getLeftSplit(ctx, mDpy);
   2059     int dstWidth = dst.right - dst.left;
   2060     int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
   2061             crop.right - crop.left;
   2062 
   2063     if(dstWidth > qdutils::MAX_DISPLAY_DIM or
   2064             cropWidth > qdutils::MAX_DISPLAY_DIM or
   2065             (primarySplitAlways and (cropWidth > lSplit))) {
   2066         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2067         if(pipe_info.rIndex == ovutils::OV_INVALID) {
   2068             return false;
   2069         }
   2070 
   2071         // Return values
   2072         // 1  Left pipe is higher priority, do nothing.
   2073         // 0  Pipes of same priority.
   2074         //-1  Right pipe is of higher priority, needs swap.
   2075         if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
   2076                 pipe_info.rIndex) == -1) {
   2077             qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
   2078         }
   2079     }
   2080 
   2081     return true;
   2082 }
   2083 
   2084 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2085         PipeLayerPair& PipeLayerPair) {
   2086     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2087     if(!hnd) {
   2088         ALOGE("%s: layer handle is NULL", __FUNCTION__);
   2089         return -1;
   2090     }
   2091     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
   2092     MdpPipeInfoSplit& mdp_info =
   2093         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   2094     Rotator **rot = &PipeLayerPair.rot;
   2095     eZorder z = static_cast<eZorder>(mdp_info.zOrder);
   2096     eIsFg isFg = IS_FG_OFF;
   2097     eDest lDest = mdp_info.lIndex;
   2098     eDest rDest = mdp_info.rIndex;
   2099     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2100     hwc_rect_t dst = layer->displayFrame;
   2101     int transform = layer->transform;
   2102     eTransform orient = static_cast<eTransform>(transform);
   2103     const int downscale = 0;
   2104     int rotFlags = ROT_FLAGS_NONE;
   2105     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
   2106     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
   2107 
   2108     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   2109              "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
   2110 
   2111     // Handle R/B swap
   2112     if (layer->flags & HWC_FORMAT_RB_SWAP) {
   2113         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
   2114             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
   2115         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
   2116             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
   2117     }
   2118 
   2119     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   2120     setMdpFlags(layer, mdpFlags, 0, transform);
   2121 
   2122     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2123         //Enable overfetch
   2124         setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
   2125     }
   2126 
   2127     if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
   2128         (*rot) = ctx->mRotMgr->getNext();
   2129         if((*rot) == NULL) return -1;
   2130         ctx->mLayerRotMap[mDpy]->add(layer, *rot);
   2131         //If the video is using a single pipe, enable BWC
   2132         if(rDest == OV_INVALID) {
   2133             BwcPM::setBwc(crop, dst, transform, mdpFlags);
   2134         }
   2135         //Configure rotator for pre-rotation
   2136         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
   2137             ALOGE("%s: configRotator failed!", __FUNCTION__);
   2138             return -1;
   2139         }
   2140         whf.format = (*rot)->getDstFormat();
   2141         updateSource(orient, whf, crop);
   2142         rotFlags |= ROT_PREROTATED;
   2143     }
   2144 
   2145     //If 2 pipes being used, divide layer into half, crop and dst
   2146     hwc_rect_t cropL = crop;
   2147     hwc_rect_t cropR = crop;
   2148     hwc_rect_t dstL = dst;
   2149     hwc_rect_t dstR = dst;
   2150     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2151         cropL.right = (crop.right + crop.left) / 2;
   2152         cropR.left = cropL.right;
   2153         sanitizeSourceCrop(cropL, cropR, hnd);
   2154 
   2155         //Swap crops on H flip since 2 pipes are being used
   2156         if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
   2157             hwc_rect_t tmp = cropL;
   2158             cropL = cropR;
   2159             cropR = tmp;
   2160         }
   2161 
   2162         dstL.right = (dst.right + dst.left) / 2;
   2163         dstR.left = dstL.right;
   2164     }
   2165 
   2166     //For the mdp, since either we are pre-rotating or MDP does flips
   2167     orient = OVERLAY_TRANSFORM_0;
   2168     transform = 0;
   2169 
   2170     //configure left pipe
   2171     if(lDest != OV_INVALID) {
   2172         PipeArgs pargL(mdpFlags, whf, z, isFg,
   2173                 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
   2174                 (ovutils::eBlending) getBlending(layer->blending));
   2175 
   2176         if(configMdp(ctx->mOverlay, pargL, orient,
   2177                     cropL, dstL, metadata, lDest) < 0) {
   2178             ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
   2179             return -1;
   2180         }
   2181     }
   2182 
   2183     //configure right pipe
   2184     if(rDest != OV_INVALID) {
   2185         PipeArgs pargR(mdpFlags, whf, z, isFg,
   2186                 static_cast<eRotFlags>(rotFlags),
   2187                 layer->planeAlpha,
   2188                 (ovutils::eBlending) getBlending(layer->blending));
   2189         if(configMdp(ctx->mOverlay, pargR, orient,
   2190                     cropR, dstR, metadata, rDest) < 0) {
   2191             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
   2192             return -1;
   2193         }
   2194     }
   2195 
   2196     return 0;
   2197 }
   2198 
   2199 }; //namespace
   2200 
   2201