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         if (layerUpdating(layer) ||
    509                 isYuvBuffer((private_handle_t *)layer->handle)) {
    510             hwc_rect_t dirtyRect = (struct hwc_rect){0, 0, 0, 0};;
    511             if(!needsScaling(layer) && !layer->transform) {
    512                 dirtyRect = calculateDirtyRect(layer, fullFrame);
    513             }
    514 
    515             roi = getUnion(roi, dirtyRect);
    516         }
    517     }
    518 
    519     /* No layer is updating. Still SF wants a refresh.*/
    520     if(!isValidRect(roi))
    521         return;
    522 
    523     // Align ROI coordinates to panel restrictions
    524     roi = getSanitizeROI(roi, fullFrame);
    525 
    526     ctx->listStats[mDpy].lRoi = roi;
    527     if(!validateAndApplyROI(ctx, list))
    528         resetROI(ctx, mDpy);
    529 
    530     ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
    531             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    532             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
    533 }
    534 
    535 void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
    536     hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
    537     hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
    538 
    539     hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
    540     hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
    541     fbRect = getUnion(l_fbRect, r_fbRect);
    542 }
    543 /* 1) Identify layers that are not visible or lying outside BOTH the updating
    544  *    ROI's and drop them from composition. If a layer is spanning across both
    545  *    the halves of the screen but needed by only ROI, the non-contributing
    546  *    half will not be programmed for MDP.
    547  * 2) If we have a scaling layer which needs cropping against generated
    548  *    ROI, reset ROI to full resolution. */
    549 bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
    550         hwc_display_contents_1_t* list) {
    551 
    552     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    553 
    554     hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
    555     hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
    556 
    557     for(int i = numAppLayers - 1; i >= 0; i--){
    558         if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
    559         {
    560             mCurrentFrame.drop[i] = true;
    561             mCurrentFrame.dropCount++;
    562             continue;
    563         }
    564 
    565         const hwc_layer_1_t* layer =  &list->hwLayers[i];
    566         hwc_rect_t dstRect = layer->displayFrame;
    567 
    568         hwc_rect_t l_res  = getIntersection(visibleRectL, dstRect);
    569         hwc_rect_t r_res  = getIntersection(visibleRectR, dstRect);
    570         hwc_rect_t res = getUnion(l_res, r_res);
    571 
    572         if(!isValidRect(l_res) && !isValidRect(r_res)) {
    573             mCurrentFrame.drop[i] = true;
    574             mCurrentFrame.dropCount++;
    575         } else {
    576             /* Reset frame ROI when any layer which needs scaling also needs ROI
    577              * cropping */
    578             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
    579                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    580                 mCurrentFrame.dropCount = 0;
    581                 return false;
    582             }
    583 
    584             if (layer->blending == HWC_BLENDING_NONE) {
    585                 visibleRectL = deductRect(visibleRectL, l_res);
    586                 visibleRectR = deductRect(visibleRectR, r_res);
    587             }
    588         }
    589     }
    590     return true;
    591 }
    592 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
    593  * are updating. If DirtyRegion is applicable, calculate it by accounting all
    594  * the changing layer's dirtyRegion. */
    595 void MDPCompSplit::generateROI(hwc_context_t *ctx,
    596         hwc_display_contents_1_t* list) {
    597     if(!canPartialUpdate(ctx, list))
    598         return;
    599 
    600     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    601     int lSplit = getLeftSplit(ctx, mDpy);
    602 
    603     int hw_h = (int)ctx->dpyAttr[mDpy].yres;
    604     int hw_w = (int)ctx->dpyAttr[mDpy].xres;
    605 
    606     struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
    607     struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
    608 
    609     struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
    610     struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
    611 
    612     for(int index = 0; index < numAppLayers; index++ ) {
    613         hwc_layer_1_t* layer = &list->hwLayers[index];
    614         private_handle_t *hnd = (private_handle_t *)layer->handle;
    615         if (layerUpdating(layer) || isYuvBuffer(hnd)) {
    616             hwc_rect_t l_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
    617             hwc_rect_t r_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
    618 
    619             if(!needsScaling(layer) && !layer->transform) {
    620                 l_dirtyRect = calculateDirtyRect(layer, l_frame);
    621                 r_dirtyRect = calculateDirtyRect(layer, r_frame);
    622             }
    623             if(isValidRect(l_dirtyRect))
    624                 l_roi = getUnion(l_roi, l_dirtyRect);
    625 
    626             if(isValidRect(r_dirtyRect))
    627                 r_roi = getUnion(r_roi, r_dirtyRect);
    628         }
    629     }
    630 
    631     /* For panels that cannot accept commands in both the interfaces, we cannot
    632      * send two ROI's (for each half). We merge them into single ROI and split
    633      * them across lSplit for MDP mixer use. The ROI's will be merged again
    634      * finally before udpating the panel in the driver. */
    635     if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
    636         hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
    637         l_roi = getIntersection(temp_roi, l_frame);
    638         r_roi = getIntersection(temp_roi, r_frame);
    639     }
    640 
    641     /* No layer is updating. Still SF wants a refresh. */
    642     if(!isValidRect(l_roi) && !isValidRect(r_roi))
    643         return;
    644 
    645     l_roi = getSanitizeROI(l_roi, l_frame);
    646     r_roi = getSanitizeROI(r_roi, r_frame);
    647 
    648     ctx->listStats[mDpy].lRoi = l_roi;
    649     ctx->listStats[mDpy].rRoi = r_roi;
    650 
    651     if(!validateAndApplyROI(ctx, list))
    652         resetROI(ctx, mDpy);
    653 
    654     ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
    655             "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
    656             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    657             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
    658             ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
    659             ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
    660 }
    661 
    662 /* Checks for conditions where all the layers marked for MDP comp cannot be
    663  * bypassed. On such conditions we try to bypass atleast YUV layers */
    664 bool MDPComp::tryFullFrame(hwc_context_t *ctx,
    665                                 hwc_display_contents_1_t* list){
    666 
    667     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    668     int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
    669 
    670     if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
    671         ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
    672         return false;
    673     }
    674 
    675     if(isSkipPresent(ctx, mDpy)) {
    676         ALOGD_IF(isDebug(),"%s: SKIP present: %d",
    677                 __FUNCTION__,
    678                 isSkipPresent(ctx, mDpy));
    679         return false;
    680     }
    681 
    682     if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
    683                               (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
    684         // Disable MDP comp on Secondary when the primary is highres panel and
    685         // the secondary is a normal 1080p, because, MDP comp on secondary under
    686         // in such usecase, decimation gets used for downscale and there will be
    687         // a quality mismatch when there will be a fallback to GPU comp
    688         ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
    689               __FUNCTION__);
    690         return false;
    691     }
    692 
    693     // check for action safe flag and downscale mode which requires scaling.
    694     if(ctx->dpyAttr[mDpy].mActionSafePresent
    695             || ctx->dpyAttr[mDpy].mDownScaleMode) {
    696         ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
    697         return false;
    698     }
    699 
    700     for(int i = 0; i < numAppLayers; ++i) {
    701         hwc_layer_1_t* layer = &list->hwLayers[i];
    702         private_handle_t *hnd = (private_handle_t *)layer->handle;
    703 
    704         if(isYuvBuffer(hnd) && has90Transform(layer)) {
    705             if(!canUseRotator(ctx, mDpy)) {
    706                 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
    707                         __FUNCTION__, mDpy);
    708                 return false;
    709             }
    710         }
    711 
    712         //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
    713         // may not need it if Gfx pre-rotation can handle all flips & rotations
    714         if(qdutils::MDPVersion::getInstance().is8x26() &&
    715                                 (ctx->dpyAttr[mDpy].xres > 1024) &&
    716                                 (layer->transform & HWC_TRANSFORM_FLIP_H) &&
    717                                 (!isYuvBuffer(hnd)))
    718                    return false;
    719     }
    720 
    721     if(ctx->mAD->isDoable()) {
    722         return false;
    723     }
    724 
    725     //If all above hard conditions are met we can do full or partial MDP comp.
    726     bool ret = false;
    727     if(fullMDPComp(ctx, list)) {
    728         ret = true;
    729     } else if(partialMDPComp(ctx, list)) {
    730         ret = true;
    731     }
    732 
    733     return ret;
    734 }
    735 
    736 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
    737 
    738     if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
    739         return false;
    740 
    741     //Will benefit presentation / secondary-only layer.
    742     if((mDpy > HWC_DISPLAY_PRIMARY) &&
    743             (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
    744         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
    745         return false;
    746     }
    747 
    748     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    749     for(int i = 0; i < numAppLayers; i++) {
    750         hwc_layer_1_t* layer = &list->hwLayers[i];
    751         if(not mCurrentFrame.drop[i] and
    752            not isSupportedForMDPComp(ctx, layer)) {
    753             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
    754             return false;
    755         }
    756 
    757         //For 8x26, if there is only one layer which needs scale for secondary
    758         //while no scale for primary display, DMA pipe is occupied by primary.
    759         //If need to fall back to GLES composition, virtual display lacks DMA
    760         //pipe and error is reported.
    761         if(qdutils::MDPVersion::getInstance().is8x26() &&
    762                                 mDpy >= HWC_DISPLAY_EXTERNAL &&
    763                                 qhwc::needsScaling(layer))
    764             return false;
    765     }
    766 
    767     mCurrentFrame.fbCount = 0;
    768     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
    769            sizeof(mCurrentFrame.isFBComposed));
    770     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
    771         mCurrentFrame.dropCount;
    772 
    773     if(sEnable4k2kYUVSplit){
    774         adjustForSourceSplit(ctx, list);
    775     }
    776 
    777     if(!postHeuristicsHandling(ctx, list)) {
    778         ALOGD_IF(isDebug(), "post heuristic handling failed");
    779         reset(ctx);
    780         return false;
    781     }
    782     ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
    783              __FUNCTION__);
    784     return true;
    785 }
    786 
    787 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
    788 {
    789     if(!sEnableMixedMode) {
    790         //Mixed mode is disabled. No need to even try caching.
    791         return false;
    792     }
    793 
    794     bool ret = false;
    795     if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
    796         ret =   loadBasedComp(ctx, list) or
    797                 cacheBasedComp(ctx, list);
    798     } else {
    799         ret =   cacheBasedComp(ctx, list) or
    800                 loadBasedComp(ctx, list);
    801     }
    802 
    803     return ret;
    804 }
    805 
    806 bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
    807         hwc_display_contents_1_t* list) {
    808     if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
    809         return false;
    810 
    811     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    812     mCurrentFrame.reset(numAppLayers);
    813     updateLayerCache(ctx, list);
    814 
    815     //If an MDP marked layer is unsupported cannot do partial MDP Comp
    816     for(int i = 0; i < numAppLayers; i++) {
    817         if(!mCurrentFrame.isFBComposed[i]) {
    818             hwc_layer_1_t* layer = &list->hwLayers[i];
    819             if(not isSupportedForMDPComp(ctx, layer)) {
    820                 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
    821                         __FUNCTION__);
    822                 reset(ctx);
    823                 return false;
    824             }
    825         }
    826     }
    827 
    828     updateYUV(ctx, list, false /*secure only*/);
    829     bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
    830     if(!ret) {
    831         ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
    832         reset(ctx);
    833         return false;
    834     }
    835 
    836     int mdpCount = mCurrentFrame.mdpCount;
    837 
    838     if(sEnable4k2kYUVSplit){
    839         adjustForSourceSplit(ctx, list);
    840     }
    841 
    842     //Will benefit cases where a video has non-updating background.
    843     if((mDpy > HWC_DISPLAY_PRIMARY) and
    844             (mdpCount > MAX_SEC_LAYERS)) {
    845         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
    846         reset(ctx);
    847         return false;
    848     }
    849 
    850     if(!postHeuristicsHandling(ctx, list)) {
    851         ALOGD_IF(isDebug(), "post heuristic handling failed");
    852         reset(ctx);
    853         return false;
    854     }
    855     ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
    856              __FUNCTION__);
    857 
    858     return true;
    859 }
    860 
    861 bool MDPComp::loadBasedComp(hwc_context_t *ctx,
    862         hwc_display_contents_1_t* list) {
    863     if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
    864         return false;
    865 
    866     if(not isLoadBasedCompDoable(ctx)) {
    867         return false;
    868     }
    869 
    870     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    871     const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
    872     const int stagesForMDP = min(sMaxPipesPerMixer,
    873             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
    874 
    875     int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
    876     int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
    877     int lastMDPSupportedIndex = numAppLayers;
    878     int dropCount = 0;
    879 
    880     //Find the minimum MDP batch size
    881     for(int i = 0; i < numAppLayers;i++) {
    882         if(mCurrentFrame.drop[i]) {
    883             dropCount++;
    884             continue;
    885         }
    886         hwc_layer_1_t* layer = &list->hwLayers[i];
    887         if(not isSupportedForMDPComp(ctx, layer)) {
    888             lastMDPSupportedIndex = i;
    889             mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
    890             fbBatchSize = numNonDroppedLayers - mdpBatchSize;
    891             break;
    892         }
    893     }
    894 
    895     ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
    896             "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
    897             mCurrentFrame.dropCount);
    898 
    899     //Start at a point where the fb batch should at least have 2 layers, for
    900     //this mode to be justified.
    901     while(fbBatchSize < 2) {
    902         ++fbBatchSize;
    903         --mdpBatchSize;
    904     }
    905 
    906     //If there are no layers for MDP, this mode doesnt make sense.
    907     if(mdpBatchSize < 1) {
    908         ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
    909                 __FUNCTION__);
    910         return false;
    911     }
    912 
    913     mCurrentFrame.reset(numAppLayers);
    914 
    915     //Try with successively smaller mdp batch sizes until we succeed or reach 1
    916     while(mdpBatchSize > 0) {
    917         //Mark layers for MDP comp
    918         int mdpBatchLeft = mdpBatchSize;
    919         for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
    920             if(mCurrentFrame.drop[i]) {
    921                 continue;
    922             }
    923             mCurrentFrame.isFBComposed[i] = false;
    924             --mdpBatchLeft;
    925         }
    926 
    927         mCurrentFrame.fbZ = mdpBatchSize;
    928         mCurrentFrame.fbCount = fbBatchSize;
    929         mCurrentFrame.mdpCount = mdpBatchSize;
    930 
    931         ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
    932                 __FUNCTION__, mdpBatchSize, fbBatchSize,
    933                 mCurrentFrame.dropCount);
    934 
    935         if(postHeuristicsHandling(ctx, list)) {
    936             ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
    937                      __FUNCTION__);
    938             ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
    939                      __FUNCTION__);
    940             return true;
    941         }
    942 
    943         reset(ctx);
    944         --mdpBatchSize;
    945         ++fbBatchSize;
    946     }
    947 
    948     return false;
    949 }
    950 
    951 bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
    952     if(mDpy or isSecurePresent(ctx, mDpy) or
    953             isYuvPresent(ctx, mDpy)) {
    954         return false;
    955     }
    956     return true;
    957 }
    958 
    959 bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
    960         hwc_display_contents_1_t* list){
    961     if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
    962             isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
    963             mDpy ) {
    964         return false;
    965     }
    966     return true;
    967 }
    968 
    969 bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
    970         hwc_display_contents_1_t* list) {
    971     const bool secureOnly = true;
    972     return videoOnlyComp(ctx, list, not secureOnly) or
    973             videoOnlyComp(ctx, list, secureOnly);
    974 }
    975 
    976 bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
    977         hwc_display_contents_1_t* list, bool secureOnly) {
    978     if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
    979         return false;
    980     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    981 
    982     mCurrentFrame.reset(numAppLayers);
    983     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
    984     updateYUV(ctx, list, secureOnly);
    985     int mdpCount = mCurrentFrame.mdpCount;
    986 
    987     if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
    988         reset(ctx);
    989         return false;
    990     }
    991 
    992     /* Bail out if we are processing only secured video layers
    993      * and we dont have any */
    994     if(!isSecurePresent(ctx, mDpy) && secureOnly){
    995         reset(ctx);
    996         return false;
    997     }
    998 
    999     if(mCurrentFrame.fbCount)
   1000         mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
   1001 
   1002     if(sEnable4k2kYUVSplit){
   1003         adjustForSourceSplit(ctx, list);
   1004     }
   1005 
   1006     if(!postHeuristicsHandling(ctx, list)) {
   1007         ALOGD_IF(isDebug(), "post heuristic handling failed");
   1008         reset(ctx);
   1009         return false;
   1010     }
   1011 
   1012     ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
   1013              __FUNCTION__);
   1014     return true;
   1015 }
   1016 
   1017 /* Checks for conditions where YUV layers cannot be bypassed */
   1018 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
   1019     if(isSkipLayer(layer)) {
   1020         ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
   1021         return false;
   1022     }
   1023 
   1024     if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
   1025         ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
   1026         return false;
   1027     }
   1028 
   1029     if(isSecuring(ctx, layer)) {
   1030         ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
   1031         return false;
   1032     }
   1033 
   1034     if(!isValidDimension(ctx, layer)) {
   1035         ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
   1036             __FUNCTION__);
   1037         return false;
   1038     }
   1039 
   1040     if(layer->planeAlpha < 0xFF) {
   1041         ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
   1042                  in video only mode",
   1043                  __FUNCTION__);
   1044         return false;
   1045     }
   1046 
   1047     return true;
   1048 }
   1049 
   1050 /* starts at fromIndex and check for each layer to find
   1051  * if it it has overlapping with any Updating layer above it in zorder
   1052  * till the end of the batch. returns true if it finds any intersection */
   1053 bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
   1054         int fromIndex, int toIndex) {
   1055     for(int i = fromIndex; i < toIndex; i++) {
   1056         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1057             if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
   1058                 return false;
   1059             }
   1060         }
   1061     }
   1062     return true;
   1063 }
   1064 
   1065 /* Checks if given layer at targetLayerIndex has any
   1066  * intersection with all the updating layers in beween
   1067  * fromIndex and toIndex. Returns true if it finds intersectiion */
   1068 bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
   1069         int fromIndex, int toIndex, int targetLayerIndex) {
   1070     for(int i = fromIndex; i <= toIndex; i++) {
   1071         if(!mCurrentFrame.isFBComposed[i]) {
   1072             if(areLayersIntersecting(&list->hwLayers[i],
   1073                         &list->hwLayers[targetLayerIndex]))  {
   1074                 return true;
   1075             }
   1076         }
   1077     }
   1078     return false;
   1079 }
   1080 
   1081 int MDPComp::getBatch(hwc_display_contents_1_t* list,
   1082         int& maxBatchStart, int& maxBatchEnd,
   1083         int& maxBatchCount) {
   1084     int i = 0;
   1085     int fbZOrder =-1;
   1086     int droppedLayerCt = 0;
   1087     while (i < mCurrentFrame.layerCount) {
   1088         int batchCount = 0;
   1089         int batchStart = i;
   1090         int batchEnd = i;
   1091         /* Adjust batch Z order with the dropped layers so far */
   1092         int fbZ = batchStart - droppedLayerCt;
   1093         int firstZReverseIndex = -1;
   1094         int updatingLayersAbove = 0;//Updating layer count in middle of batch
   1095         while(i < mCurrentFrame.layerCount) {
   1096             if(!mCurrentFrame.isFBComposed[i]) {
   1097                 if(!batchCount) {
   1098                     i++;
   1099                     break;
   1100                 }
   1101                 updatingLayersAbove++;
   1102                 i++;
   1103                 continue;
   1104             } else {
   1105                 if(mCurrentFrame.drop[i]) {
   1106                     i++;
   1107                     droppedLayerCt++;
   1108                     continue;
   1109                 } else if(updatingLayersAbove <= 0) {
   1110                     batchCount++;
   1111                     batchEnd = i;
   1112                     i++;
   1113                     continue;
   1114                 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
   1115 
   1116                     // We have a valid updating layer already. If layer-i not
   1117                     // have overlapping with all updating layers in between
   1118                     // batch-start and i, then we can add layer i to batch.
   1119                     if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
   1120                         batchCount++;
   1121                         batchEnd = i;
   1122                         i++;
   1123                         continue;
   1124                     } else if(canPushBatchToTop(list, batchStart, i)) {
   1125                         //If All the non-updating layers with in this batch
   1126                         //does not have intersection with the updating layers
   1127                         //above in z-order, then we can safely move the batch to
   1128                         //higher z-order. Increment fbZ as it is moving up.
   1129                         if( firstZReverseIndex < 0) {
   1130                             firstZReverseIndex = i;
   1131                         }
   1132                         batchCount++;
   1133                         batchEnd = i;
   1134                         fbZ += updatingLayersAbove;
   1135                         i++;
   1136                         updatingLayersAbove = 0;
   1137                         continue;
   1138                     } else {
   1139                         //both failed.start the loop again from here.
   1140                         if(firstZReverseIndex >= 0) {
   1141                             i = firstZReverseIndex;
   1142                         }
   1143                         break;
   1144                     }
   1145                 }
   1146             }
   1147         }
   1148         if(batchCount > maxBatchCount) {
   1149             maxBatchCount = batchCount;
   1150             maxBatchStart = batchStart;
   1151             maxBatchEnd = batchEnd;
   1152             fbZOrder = fbZ;
   1153         }
   1154     }
   1155     return fbZOrder;
   1156 }
   1157 
   1158 bool  MDPComp::markLayersForCaching(hwc_context_t* ctx,
   1159         hwc_display_contents_1_t* list) {
   1160     /* Idea is to keep as many non-updating(cached) layers in FB and
   1161      * send rest of them through MDP. This is done in 2 steps.
   1162      *   1. Find the maximum contiguous batch of non-updating layers.
   1163      *   2. See if we can improve this batch size for caching by adding
   1164      *      opaque layers around the batch, if they don't have
   1165      *      any overlapping with the updating layers in between.
   1166      * NEVER mark an updating layer for caching.
   1167      * But cached ones can be marked for MDP */
   1168 
   1169     int maxBatchStart = -1;
   1170     int maxBatchEnd = -1;
   1171     int maxBatchCount = 0;
   1172     int fbZ = -1;
   1173 
   1174     /* Nothing is cached. No batching needed */
   1175     if(mCurrentFrame.fbCount == 0) {
   1176         return true;
   1177     }
   1178 
   1179     /* No MDP comp layers, try to use other comp modes */
   1180     if(mCurrentFrame.mdpCount == 0) {
   1181         return false;
   1182     }
   1183 
   1184     fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
   1185 
   1186     /* reset rest of the layers lying inside ROI for MDP comp */
   1187     for(int i = 0; i < mCurrentFrame.layerCount; i++) {
   1188         hwc_layer_1_t* layer = &list->hwLayers[i];
   1189         if((i < maxBatchStart || i > maxBatchEnd) &&
   1190                 mCurrentFrame.isFBComposed[i]){
   1191             if(!mCurrentFrame.drop[i]){
   1192                 //If an unsupported layer is being attempted to
   1193                 //be pulled out we should fail
   1194                 if(not isSupportedForMDPComp(ctx, layer)) {
   1195                     return false;
   1196                 }
   1197                 mCurrentFrame.isFBComposed[i] = false;
   1198             }
   1199         }
   1200     }
   1201 
   1202     // update the frame data
   1203     mCurrentFrame.fbZ = fbZ;
   1204     mCurrentFrame.fbCount = maxBatchCount;
   1205     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1206             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1207 
   1208     ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
   1209             mCurrentFrame.fbCount);
   1210 
   1211     return true;
   1212 }
   1213 
   1214 void MDPComp::updateLayerCache(hwc_context_t* ctx,
   1215         hwc_display_contents_1_t* list) {
   1216     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1217     int fbCount = 0;
   1218 
   1219     for(int i = 0; i < numAppLayers; i++) {
   1220         hwc_layer_1_t * layer = &list->hwLayers[i];
   1221         if (!layerUpdating(layer)) {
   1222             if(!mCurrentFrame.drop[i])
   1223                 fbCount++;
   1224             mCurrentFrame.isFBComposed[i] = true;
   1225         } else {
   1226             mCurrentFrame.isFBComposed[i] = false;
   1227         }
   1228     }
   1229 
   1230     mCurrentFrame.fbCount = fbCount;
   1231     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
   1232                                                     - mCurrentFrame.dropCount;
   1233 
   1234     ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
   1235              ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
   1236             mCurrentFrame.dropCount);
   1237 }
   1238 
   1239 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
   1240         bool secureOnly) {
   1241     int nYuvCount = ctx->listStats[mDpy].yuvCount;
   1242     for(int index = 0;index < nYuvCount; index++){
   1243         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
   1244         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
   1245 
   1246         if(!isYUVDoable(ctx, layer)) {
   1247             if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
   1248                 mCurrentFrame.isFBComposed[nYuvIndex] = true;
   1249                 mCurrentFrame.fbCount++;
   1250             }
   1251         } else {
   1252             if(mCurrentFrame.isFBComposed[nYuvIndex]) {
   1253                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1254                 if(!secureOnly || isSecureBuffer(hnd)) {
   1255                     mCurrentFrame.isFBComposed[nYuvIndex] = false;
   1256                     mCurrentFrame.fbCount--;
   1257                 }
   1258             }
   1259         }
   1260     }
   1261 
   1262     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1263             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1264     ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
   1265              mCurrentFrame.fbCount);
   1266 }
   1267 
   1268 hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
   1269         hwc_display_contents_1_t* list){
   1270     hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
   1271 
   1272     /* Update only the region of FB needed for composition */
   1273     for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
   1274         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1275             hwc_layer_1_t* layer = &list->hwLayers[i];
   1276             hwc_rect_t dst = layer->displayFrame;
   1277             fbRect = getUnion(fbRect, dst);
   1278         }
   1279     }
   1280     trimAgainstROI(ctx, fbRect);
   1281     return fbRect;
   1282 }
   1283 
   1284 bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
   1285         hwc_display_contents_1_t* list) {
   1286 
   1287     //Capability checks
   1288     if(!resourceCheck()) {
   1289         ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
   1290         return false;
   1291     }
   1292 
   1293     //Limitations checks
   1294     if(!hwLimitationsCheck(ctx, list)) {
   1295         ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
   1296         return false;
   1297     }
   1298 
   1299     //Configure framebuffer first if applicable
   1300     if(mCurrentFrame.fbZ >= 0) {
   1301         hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
   1302         if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
   1303         {
   1304             ALOGD_IF(isDebug(), "%s configure framebuffer failed",
   1305                     __FUNCTION__);
   1306             return false;
   1307         }
   1308     }
   1309 
   1310     mCurrentFrame.map();
   1311 
   1312     if(!allocLayerPipes(ctx, list)) {
   1313         ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
   1314         return false;
   1315     }
   1316 
   1317     for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1318             index++) {
   1319         if(!mCurrentFrame.isFBComposed[index]) {
   1320             int mdpIndex = mCurrentFrame.layerToMDP[index];
   1321             hwc_layer_1_t* layer = &list->hwLayers[index];
   1322 
   1323             //Leave fbZ for framebuffer. CACHE/GLES layers go here.
   1324             if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1325                 mdpNextZOrder++;
   1326             }
   1327             MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1328             cur_pipe->zOrder = mdpNextZOrder++;
   1329 
   1330             private_handle_t *hnd = (private_handle_t *)layer->handle;
   1331             if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1332                 if(configure4k2kYuv(ctx, layer,
   1333                             mCurrentFrame.mdpToLayer[mdpIndex])
   1334                         != 0 ){
   1335                     ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
   1336                             for layer %d",__FUNCTION__, index);
   1337                     return false;
   1338                 }
   1339                 else{
   1340                     mdpNextZOrder++;
   1341                 }
   1342                 continue;
   1343             }
   1344             if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
   1345                 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
   1346                         layer %d",__FUNCTION__, index);
   1347                 return false;
   1348             }
   1349         }
   1350     }
   1351 
   1352     if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
   1353         ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
   1354                 ,__FUNCTION__, mDpy);
   1355         return false;
   1356     }
   1357 
   1358     setRedraw(ctx, list);
   1359     return true;
   1360 }
   1361 
   1362 bool MDPComp::resourceCheck() {
   1363     const bool fbUsed = mCurrentFrame.fbCount;
   1364     if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
   1365         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
   1366         return false;
   1367     }
   1368     return true;
   1369 }
   1370 
   1371 bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
   1372         hwc_display_contents_1_t* list) {
   1373 
   1374     //A-family hw limitation:
   1375     //If a layer need alpha scaling, MDP can not support.
   1376     if(ctx->mMDP.version < qdutils::MDSS_V5) {
   1377         for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
   1378             if(!mCurrentFrame.isFBComposed[i] &&
   1379                     isAlphaScaled( &list->hwLayers[i])) {
   1380                 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
   1381                 return false;
   1382             }
   1383         }
   1384     }
   1385 
   1386     // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
   1387     //If multiple layers requires downscaling and also they are overlapping
   1388     //fall back to GPU since MDSS can not handle it.
   1389     if(qdutils::MDPVersion::getInstance().is8x74v2() ||
   1390             qdutils::MDPVersion::getInstance().is8x26()) {
   1391         for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
   1392             hwc_layer_1_t* botLayer = &list->hwLayers[i];
   1393             if(!mCurrentFrame.isFBComposed[i] &&
   1394                     isDownscaleRequired(botLayer)) {
   1395                 //if layer-i is marked for MDP and needs downscaling
   1396                 //check if any MDP layer on top of i & overlaps with layer-i
   1397                 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
   1398                     hwc_layer_1_t* topLayer = &list->hwLayers[j];
   1399                     if(!mCurrentFrame.isFBComposed[j] &&
   1400                             isDownscaleRequired(topLayer)) {
   1401                         hwc_rect_t r = getIntersection(botLayer->displayFrame,
   1402                                 topLayer->displayFrame);
   1403                         if(isValidRect(r))
   1404                             return false;
   1405                     }
   1406                 }
   1407             }
   1408         }
   1409     }
   1410     return true;
   1411 }
   1412 
   1413 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1414     int ret = 0;
   1415     const int numLayers = ctx->listStats[mDpy].numAppLayers;
   1416     char property[PROPERTY_VALUE_MAX];
   1417 
   1418     if(property_get("debug.hwc.simulate", property, NULL) > 0) {
   1419         int currentFlags = atoi(property);
   1420         if(currentFlags != sSimulationFlags) {
   1421             sSimulationFlags = currentFlags;
   1422             ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
   1423                     sSimulationFlags, sSimulationFlags);
   1424         }
   1425     }
   1426 
   1427     //Do not cache the information for next draw cycle.
   1428     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
   1429         ALOGI("%s: Unsupported layer count for mdp composition",
   1430                 __FUNCTION__);
   1431         mCachedFrame.reset();
   1432         return -1;
   1433     }
   1434 
   1435     //reset old data
   1436     mCurrentFrame.reset(numLayers);
   1437     memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   1438     mCurrentFrame.dropCount = 0;
   1439 
   1440     // Detect the start of animation and fall back to GPU only once to cache
   1441     // all the layers in FB and display FB content untill animation completes.
   1442     if(ctx->listStats[mDpy].isDisplayAnimating) {
   1443         mCurrentFrame.needsRedraw = false;
   1444         if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
   1445             mCurrentFrame.needsRedraw = true;
   1446             ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
   1447         }
   1448         setMDPCompLayerFlags(ctx, list);
   1449         mCachedFrame.updateCounts(mCurrentFrame);
   1450         ret = -1;
   1451         return ret;
   1452     } else {
   1453         ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
   1454     }
   1455 
   1456     //Hard conditions, if not met, cannot do MDP comp
   1457     if(isFrameDoable(ctx)) {
   1458         generateROI(ctx, list);
   1459 
   1460         if(tryFullFrame(ctx, list) || tryVideoOnly(ctx, list)) {
   1461             setMDPCompLayerFlags(ctx, list);
   1462         } else {
   1463             resetROI(ctx, mDpy);
   1464             reset(ctx);
   1465             memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   1466             mCurrentFrame.dropCount = 0;
   1467             ret = -1;
   1468         }
   1469     } else {
   1470         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
   1471                 __FUNCTION__);
   1472         ret = -1;
   1473     }
   1474 
   1475     if(isDebug()) {
   1476         ALOGD("GEOMETRY change: %d",
   1477                 (list->flags & HWC_GEOMETRY_CHANGED));
   1478         android::String8 sDump("");
   1479         dump(sDump, ctx);
   1480         ALOGD("%s",sDump.string());
   1481     }
   1482 
   1483     mCachedFrame.updateCounts(mCurrentFrame);
   1484     return ret;
   1485 }
   1486 
   1487 bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
   1488 
   1489     bool bRet = true;
   1490     int mdpIndex = mCurrentFrame.layerToMDP[index];
   1491     PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1492     info.pipeInfo = new MdpYUVPipeInfo;
   1493     info.rot = NULL;
   1494     MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
   1495 
   1496     pipe_info.lIndex = ovutils::OV_INVALID;
   1497     pipe_info.rIndex = ovutils::OV_INVALID;
   1498 
   1499     Overlay::PipeSpecs pipeSpecs;
   1500     pipeSpecs.formatClass = Overlay::FORMAT_YUV;
   1501     pipeSpecs.needsScaling = true;
   1502     pipeSpecs.dpy = mDpy;
   1503     pipeSpecs.fb = false;
   1504 
   1505     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1506     if(pipe_info.lIndex == ovutils::OV_INVALID){
   1507         bRet = false;
   1508         ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
   1509                 __FUNCTION__);
   1510     }
   1511     pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1512     if(pipe_info.rIndex == ovutils::OV_INVALID){
   1513         bRet = false;
   1514         ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
   1515                 __FUNCTION__);
   1516     }
   1517     return bRet;
   1518 }
   1519 //=============MDPCompNonSplit==================================================
   1520 
   1521 void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
   1522         hwc_display_contents_1_t* list) {
   1523     //If 4k2k Yuv layer split is possible,  and if
   1524     //fbz is above 4k2k layer, increment fb zorder by 1
   1525     //as we split 4k2k layer and increment zorder for right half
   1526     //of the layer
   1527     if(mCurrentFrame.fbZ >= 0) {
   1528         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1529                 index++) {
   1530             if(!mCurrentFrame.isFBComposed[index]) {
   1531                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1532                     mdpNextZOrder++;
   1533                 }
   1534                 mdpNextZOrder++;
   1535                 hwc_layer_1_t* layer = &list->hwLayers[index];
   1536                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1537                 if(is4kx2kYuvBuffer(hnd)) {
   1538                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   1539                         mCurrentFrame.fbZ += 1;
   1540                     mdpNextZOrder++;
   1541                     //As we split 4kx2k yuv layer and program to 2 VG pipes
   1542                     //(if available) increase mdpcount by 1.
   1543                     mCurrentFrame.mdpCount++;
   1544                 }
   1545             }
   1546         }
   1547     }
   1548 }
   1549 
   1550 /*
   1551  * Configures pipe(s) for MDP composition
   1552  */
   1553 int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1554                              PipeLayerPair& PipeLayerPair) {
   1555     MdpPipeInfoNonSplit& mdp_info =
   1556         *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
   1557     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   1558     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1559     eIsFg isFg = IS_FG_OFF;
   1560     eDest dest = mdp_info.index;
   1561 
   1562     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
   1563              __FUNCTION__, layer, zOrder, dest);
   1564 
   1565     return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
   1566                            &PipeLayerPair.rot);
   1567 }
   1568 
   1569 bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
   1570         hwc_display_contents_1_t* list) {
   1571     for(int index = 0; index < mCurrentFrame.layerCount; index++) {
   1572 
   1573         if(mCurrentFrame.isFBComposed[index]) continue;
   1574 
   1575         hwc_layer_1_t* layer = &list->hwLayers[index];
   1576         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1577         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1578             if(allocSplitVGPipesfor4k2k(ctx, index)){
   1579                 continue;
   1580             }
   1581         }
   1582 
   1583         int mdpIndex = mCurrentFrame.layerToMDP[index];
   1584         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1585         info.pipeInfo = new MdpPipeInfoNonSplit;
   1586         info.rot = NULL;
   1587         MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
   1588 
   1589         Overlay::PipeSpecs pipeSpecs;
   1590         pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   1591                 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   1592         pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
   1593                 (qdutils::MDPVersion::getInstance().is8x26() and
   1594                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
   1595         pipeSpecs.dpy = mDpy;
   1596         pipeSpecs.fb = false;
   1597 
   1598         pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
   1599 
   1600         if(pipe_info.index == ovutils::OV_INVALID) {
   1601             ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
   1602             return false;
   1603         }
   1604     }
   1605     return true;
   1606 }
   1607 
   1608 int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1609         PipeLayerPair& PipeLayerPair) {
   1610     MdpYUVPipeInfo& mdp_info =
   1611             *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   1612     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1613     eIsFg isFg = IS_FG_OFF;
   1614     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1615     eDest lDest = mdp_info.lIndex;
   1616     eDest rDest = mdp_info.rIndex;
   1617 
   1618     return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
   1619             lDest, rDest, &PipeLayerPair.rot);
   1620 }
   1621 
   1622 bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1623 
   1624     if(!isEnabled()) {
   1625         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
   1626         return true;
   1627     }
   1628 
   1629     if(!ctx || !list) {
   1630         ALOGE("%s: invalid contxt or list",__FUNCTION__);
   1631         return false;
   1632     }
   1633 
   1634     if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
   1635         ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
   1636         return true;
   1637     }
   1638 
   1639     // Set the Handle timeout to true for MDP or MIXED composition.
   1640     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
   1641         sHandleTimeout = true;
   1642     }
   1643 
   1644     overlay::Overlay& ov = *ctx->mOverlay;
   1645     LayerProp *layerProp = ctx->layerProp[mDpy];
   1646 
   1647     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   1648     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   1649     {
   1650         if(mCurrentFrame.isFBComposed[i]) continue;
   1651 
   1652         hwc_layer_1_t *layer = &list->hwLayers[i];
   1653         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1654         if(!hnd) {
   1655             if (!(layer->flags & HWC_COLOR_FILL)) {
   1656                 ALOGE("%s handle null", __FUNCTION__);
   1657                 return false;
   1658             }
   1659             // No PLAY for Color layer
   1660             layerProp[i].mFlags &= ~HWC_MDPCOMP;
   1661             continue;
   1662         }
   1663 
   1664         int mdpIndex = mCurrentFrame.layerToMDP[i];
   1665 
   1666         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
   1667         {
   1668             MdpYUVPipeInfo& pipe_info =
   1669                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1670             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1671             ovutils::eDest indexL = pipe_info.lIndex;
   1672             ovutils::eDest indexR = pipe_info.rIndex;
   1673             int fd = hnd->fd;
   1674             uint32_t offset = (uint32_t)hnd->offset;
   1675             if(rot) {
   1676                 rot->queueBuffer(fd, offset);
   1677                 fd = rot->getDstMemId();
   1678                 offset = rot->getDstOffset();
   1679             }
   1680             if(indexL != ovutils::OV_INVALID) {
   1681                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1682                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1683                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1684                 if (!ov.queueBuffer(fd, offset, destL)) {
   1685                     ALOGE("%s: queueBuffer failed for display:%d",
   1686                             __FUNCTION__, mDpy);
   1687                     return false;
   1688                 }
   1689             }
   1690 
   1691             if(indexR != ovutils::OV_INVALID) {
   1692                 ovutils::eDest destR = (ovutils::eDest)indexR;
   1693                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1694                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   1695                 if (!ov.queueBuffer(fd, offset, destR)) {
   1696                     ALOGE("%s: queueBuffer failed for display:%d",
   1697                             __FUNCTION__, mDpy);
   1698                     return false;
   1699                 }
   1700             }
   1701         }
   1702         else{
   1703             MdpPipeInfoNonSplit& pipe_info =
   1704             *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1705             ovutils::eDest dest = pipe_info.index;
   1706             if(dest == ovutils::OV_INVALID) {
   1707                 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
   1708                 return false;
   1709             }
   1710 
   1711             if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   1712                 continue;
   1713             }
   1714 
   1715             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1716                     using  pipe: %d", __FUNCTION__, layer,
   1717                     hnd, dest );
   1718 
   1719             int fd = hnd->fd;
   1720             uint32_t offset = (uint32_t)hnd->offset;
   1721 
   1722             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1723             if(rot) {
   1724                 if(!rot->queueBuffer(fd, offset))
   1725                     return false;
   1726                 fd = rot->getDstMemId();
   1727                 offset = rot->getDstOffset();
   1728             }
   1729 
   1730             if (!ov.queueBuffer(fd, offset, dest)) {
   1731                 ALOGE("%s: queueBuffer failed for display:%d ",
   1732                         __FUNCTION__, mDpy);
   1733                 return false;
   1734             }
   1735         }
   1736 
   1737         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   1738     }
   1739     return true;
   1740 }
   1741 
   1742 //=============MDPCompSplit===================================================
   1743 
   1744 void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
   1745          hwc_display_contents_1_t* list){
   1746     //if 4kx2k yuv layer is totally present in either in left half
   1747     //or right half then try splitting the yuv layer to avoid decimation
   1748     const int lSplit = getLeftSplit(ctx, mDpy);
   1749     if(mCurrentFrame.fbZ >= 0) {
   1750         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1751                 index++) {
   1752             if(!mCurrentFrame.isFBComposed[index]) {
   1753                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1754                     mdpNextZOrder++;
   1755                 }
   1756                 mdpNextZOrder++;
   1757                 hwc_layer_1_t* layer = &list->hwLayers[index];
   1758                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1759                 if(is4kx2kYuvBuffer(hnd)) {
   1760                     hwc_rect_t dst = layer->displayFrame;
   1761                     if((dst.left > lSplit) || (dst.right < lSplit)) {
   1762                         mCurrentFrame.mdpCount += 1;
   1763                     }
   1764                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   1765                         mCurrentFrame.fbZ += 1;
   1766                     mdpNextZOrder++;
   1767                 }
   1768             }
   1769         }
   1770     }
   1771 }
   1772 
   1773 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   1774         MdpPipeInfoSplit& pipe_info) {
   1775 
   1776     const int lSplit = getLeftSplit(ctx, mDpy);
   1777     private_handle_t *hnd = (private_handle_t *)layer->handle;
   1778     hwc_rect_t dst = layer->displayFrame;
   1779     pipe_info.lIndex = ovutils::OV_INVALID;
   1780     pipe_info.rIndex = ovutils::OV_INVALID;
   1781 
   1782     Overlay::PipeSpecs pipeSpecs;
   1783     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   1784             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   1785     pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
   1786     pipeSpecs.dpy = mDpy;
   1787     pipeSpecs.mixer = Overlay::MIXER_LEFT;
   1788     pipeSpecs.fb = false;
   1789 
   1790     // Acquire pipe only for the updating half
   1791     hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
   1792     hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
   1793 
   1794     if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
   1795         pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1796         if(pipe_info.lIndex == ovutils::OV_INVALID)
   1797             return false;
   1798     }
   1799 
   1800     if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
   1801         pipeSpecs.mixer = Overlay::MIXER_RIGHT;
   1802         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   1803         if(pipe_info.rIndex == ovutils::OV_INVALID)
   1804             return false;
   1805     }
   1806 
   1807     return true;
   1808 }
   1809 
   1810 bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
   1811         hwc_display_contents_1_t* list) {
   1812     for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
   1813 
   1814         if(mCurrentFrame.isFBComposed[index]) continue;
   1815 
   1816         hwc_layer_1_t* layer = &list->hwLayers[index];
   1817         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1818         hwc_rect_t dst = layer->displayFrame;
   1819         const int lSplit = getLeftSplit(ctx, mDpy);
   1820         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
   1821             if((dst.left > lSplit)||(dst.right < lSplit)){
   1822                 if(allocSplitVGPipesfor4k2k(ctx, index)){
   1823                     continue;
   1824                 }
   1825             }
   1826         }
   1827         int mdpIndex = mCurrentFrame.layerToMDP[index];
   1828         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   1829         info.pipeInfo = new MdpPipeInfoSplit;
   1830         info.rot = NULL;
   1831         MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
   1832 
   1833         if(!acquireMDPPipes(ctx, layer, pipe_info)) {
   1834             ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
   1835                     __FUNCTION__);
   1836             return false;
   1837         }
   1838     }
   1839     return true;
   1840 }
   1841 
   1842 int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1843         PipeLayerPair& PipeLayerPair) {
   1844     const int lSplit = getLeftSplit(ctx, mDpy);
   1845     hwc_rect_t dst = layer->displayFrame;
   1846     if((dst.left > lSplit)||(dst.right < lSplit)){
   1847         MdpYUVPipeInfo& mdp_info =
   1848                 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   1849         eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1850         eIsFg isFg = IS_FG_OFF;
   1851         eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1852         eDest lDest = mdp_info.lIndex;
   1853         eDest rDest = mdp_info.rIndex;
   1854 
   1855         return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
   1856                 lDest, rDest, &PipeLayerPair.rot);
   1857     }
   1858     else{
   1859         return configure(ctx, layer, PipeLayerPair);
   1860     }
   1861 }
   1862 
   1863 /*
   1864  * Configures pipe(s) for MDP composition
   1865  */
   1866 int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   1867         PipeLayerPair& PipeLayerPair) {
   1868     MdpPipeInfoSplit& mdp_info =
   1869         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   1870     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   1871     eIsFg isFg = IS_FG_OFF;
   1872     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   1873     eDest lDest = mdp_info.lIndex;
   1874     eDest rDest = mdp_info.rIndex;
   1875 
   1876     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   1877              "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
   1878 
   1879     return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
   1880                             rDest, &PipeLayerPair.rot);
   1881 }
   1882 
   1883 bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1884 
   1885     if(!isEnabled()) {
   1886         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
   1887         return true;
   1888     }
   1889 
   1890     if(!ctx || !list) {
   1891         ALOGE("%s: invalid contxt or list",__FUNCTION__);
   1892         return false;
   1893     }
   1894 
   1895     if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
   1896         ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
   1897         return true;
   1898     }
   1899 
   1900     // Set the Handle timeout to true for MDP or MIXED composition.
   1901     if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
   1902         sHandleTimeout = true;
   1903     }
   1904 
   1905     overlay::Overlay& ov = *ctx->mOverlay;
   1906     LayerProp *layerProp = ctx->layerProp[mDpy];
   1907 
   1908     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   1909     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   1910     {
   1911         if(mCurrentFrame.isFBComposed[i]) continue;
   1912 
   1913         hwc_layer_1_t *layer = &list->hwLayers[i];
   1914         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1915         if(!hnd) {
   1916             ALOGE("%s handle null", __FUNCTION__);
   1917             return false;
   1918         }
   1919 
   1920         if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   1921             continue;
   1922         }
   1923 
   1924         int mdpIndex = mCurrentFrame.layerToMDP[i];
   1925 
   1926         if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
   1927         {
   1928             MdpYUVPipeInfo& pipe_info =
   1929                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1930             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1931             ovutils::eDest indexL = pipe_info.lIndex;
   1932             ovutils::eDest indexR = pipe_info.rIndex;
   1933             int fd = hnd->fd;
   1934             uint32_t offset = (uint32_t)hnd->offset;
   1935             if(rot) {
   1936                 rot->queueBuffer(fd, offset);
   1937                 fd = rot->getDstMemId();
   1938                 offset = rot->getDstOffset();
   1939             }
   1940             if(indexL != ovutils::OV_INVALID) {
   1941                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1942                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1943                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1944                 if (!ov.queueBuffer(fd, offset, destL)) {
   1945                     ALOGE("%s: queueBuffer failed for display:%d",
   1946                             __FUNCTION__, mDpy);
   1947                     return false;
   1948                 }
   1949             }
   1950 
   1951             if(indexR != ovutils::OV_INVALID) {
   1952                 ovutils::eDest destR = (ovutils::eDest)indexR;
   1953                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1954                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   1955                 if (!ov.queueBuffer(fd, offset, destR)) {
   1956                     ALOGE("%s: queueBuffer failed for display:%d",
   1957                             __FUNCTION__, mDpy);
   1958                     return false;
   1959                 }
   1960             }
   1961         }
   1962         else{
   1963             MdpPipeInfoSplit& pipe_info =
   1964                 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1965             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   1966 
   1967             ovutils::eDest indexL = pipe_info.lIndex;
   1968             ovutils::eDest indexR = pipe_info.rIndex;
   1969 
   1970             int fd = hnd->fd;
   1971             int offset = (uint32_t)hnd->offset;
   1972 
   1973             if(ctx->mAD->isModeOn()) {
   1974                 if(ctx->mAD->draw(ctx, fd, offset)) {
   1975                     fd = ctx->mAD->getDstFd();
   1976                     offset = ctx->mAD->getDstOffset();
   1977                 }
   1978             }
   1979 
   1980             if(rot) {
   1981                 rot->queueBuffer(fd, offset);
   1982                 fd = rot->getDstMemId();
   1983                 offset = rot->getDstOffset();
   1984             }
   1985 
   1986             //************* play left mixer **********
   1987             if(indexL != ovutils::OV_INVALID) {
   1988                 ovutils::eDest destL = (ovutils::eDest)indexL;
   1989                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   1990                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   1991                 if (!ov.queueBuffer(fd, offset, destL)) {
   1992                     ALOGE("%s: queueBuffer failed for left mixer",
   1993                             __FUNCTION__);
   1994                     return false;
   1995                 }
   1996             }
   1997 
   1998             //************* play right mixer **********
   1999             if(indexR != ovutils::OV_INVALID) {
   2000                 ovutils::eDest destR = (ovutils::eDest)indexR;
   2001                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2002                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   2003                 if (!ov.queueBuffer(fd, offset, destR)) {
   2004                     ALOGE("%s: queueBuffer failed for right mixer",
   2005                             __FUNCTION__);
   2006                     return false;
   2007                 }
   2008             }
   2009         }
   2010 
   2011         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   2012     }
   2013 
   2014     return true;
   2015 }
   2016 
   2017 //================MDPCompSrcSplit==============================================
   2018 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   2019         MdpPipeInfoSplit& pipe_info) {
   2020     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2021     hwc_rect_t dst = layer->displayFrame;
   2022     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2023     pipe_info.lIndex = ovutils::OV_INVALID;
   2024     pipe_info.rIndex = ovutils::OV_INVALID;
   2025 
   2026     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
   2027     //should have a higher priority than the right one. Pipe priorities are
   2028     //starting with VG0, VG1 ... , RGB0 ..., DMA1
   2029 
   2030     Overlay::PipeSpecs pipeSpecs;
   2031     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   2032             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   2033     pipeSpecs.needsScaling = qhwc::needsScaling(layer);
   2034     pipeSpecs.dpy = mDpy;
   2035     pipeSpecs.fb = false;
   2036 
   2037     //1 pipe by default for a layer
   2038     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2039     if(pipe_info.lIndex == ovutils::OV_INVALID) {
   2040         return false;
   2041     }
   2042 
   2043     /* Use 2 pipes IF
   2044         a) Layer's crop width is > 2048 or
   2045         b) Layer's dest width > 2048 or
   2046         c) On primary, driver has indicated with caps to split always. This is
   2047            based on an empirically derived value of panel height. Applied only
   2048            if the layer's width is > mixer's width
   2049     */
   2050 
   2051     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
   2052             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
   2053     int lSplit = getLeftSplit(ctx, mDpy);
   2054     int dstWidth = dst.right - dst.left;
   2055     int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
   2056             crop.right - crop.left;
   2057 
   2058     if(dstWidth > qdutils::MAX_DISPLAY_DIM or
   2059             cropWidth > qdutils::MAX_DISPLAY_DIM or
   2060             (primarySplitAlways and (cropWidth > lSplit))) {
   2061         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2062         if(pipe_info.rIndex == ovutils::OV_INVALID) {
   2063             return false;
   2064         }
   2065 
   2066         // Return values
   2067         // 1  Left pipe is higher priority, do nothing.
   2068         // 0  Pipes of same priority.
   2069         //-1  Right pipe is of higher priority, needs swap.
   2070         if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
   2071                 pipe_info.rIndex) == -1) {
   2072             qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
   2073         }
   2074     }
   2075 
   2076     return true;
   2077 }
   2078 
   2079 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2080         PipeLayerPair& PipeLayerPair) {
   2081     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2082     if(!hnd) {
   2083         ALOGE("%s: layer handle is NULL", __FUNCTION__);
   2084         return -1;
   2085     }
   2086     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
   2087     MdpPipeInfoSplit& mdp_info =
   2088         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   2089     Rotator **rot = &PipeLayerPair.rot;
   2090     eZorder z = static_cast<eZorder>(mdp_info.zOrder);
   2091     eIsFg isFg = IS_FG_OFF;
   2092     eDest lDest = mdp_info.lIndex;
   2093     eDest rDest = mdp_info.rIndex;
   2094     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2095     hwc_rect_t dst = layer->displayFrame;
   2096     int transform = layer->transform;
   2097     eTransform orient = static_cast<eTransform>(transform);
   2098     const int downscale = 0;
   2099     int rotFlags = ROT_FLAGS_NONE;
   2100     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
   2101     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
   2102 
   2103     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   2104              "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
   2105 
   2106     // Handle R/B swap
   2107     if (layer->flags & HWC_FORMAT_RB_SWAP) {
   2108         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
   2109             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
   2110         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
   2111             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
   2112     }
   2113 
   2114     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   2115     setMdpFlags(layer, mdpFlags, 0, transform);
   2116 
   2117     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2118         //Enable overfetch
   2119         setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
   2120     }
   2121 
   2122     if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
   2123         (*rot) = ctx->mRotMgr->getNext();
   2124         if((*rot) == NULL) return -1;
   2125         ctx->mLayerRotMap[mDpy]->add(layer, *rot);
   2126         //If the video is using a single pipe, enable BWC
   2127         if(rDest == OV_INVALID) {
   2128             BwcPM::setBwc(crop, dst, transform, mdpFlags);
   2129         }
   2130         //Configure rotator for pre-rotation
   2131         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
   2132             ALOGE("%s: configRotator failed!", __FUNCTION__);
   2133             return -1;
   2134         }
   2135         whf.format = (*rot)->getDstFormat();
   2136         updateSource(orient, whf, crop);
   2137         rotFlags |= ROT_PREROTATED;
   2138     }
   2139 
   2140     //If 2 pipes being used, divide layer into half, crop and dst
   2141     hwc_rect_t cropL = crop;
   2142     hwc_rect_t cropR = crop;
   2143     hwc_rect_t dstL = dst;
   2144     hwc_rect_t dstR = dst;
   2145     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2146         cropL.right = (crop.right + crop.left) / 2;
   2147         cropR.left = cropL.right;
   2148         sanitizeSourceCrop(cropL, cropR, hnd);
   2149 
   2150         //Swap crops on H flip since 2 pipes are being used
   2151         if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
   2152             hwc_rect_t tmp = cropL;
   2153             cropL = cropR;
   2154             cropR = tmp;
   2155         }
   2156 
   2157         dstL.right = (dst.right + dst.left) / 2;
   2158         dstR.left = dstL.right;
   2159     }
   2160 
   2161     //For the mdp, since either we are pre-rotating or MDP does flips
   2162     orient = OVERLAY_TRANSFORM_0;
   2163     transform = 0;
   2164 
   2165     //configure left pipe
   2166     if(lDest != OV_INVALID) {
   2167         PipeArgs pargL(mdpFlags, whf, z, isFg,
   2168                 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
   2169                 (ovutils::eBlending) getBlending(layer->blending));
   2170 
   2171         if(configMdp(ctx->mOverlay, pargL, orient,
   2172                     cropL, dstL, metadata, lDest) < 0) {
   2173             ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
   2174             return -1;
   2175         }
   2176     }
   2177 
   2178     //configure right pipe
   2179     if(rDest != OV_INVALID) {
   2180         PipeArgs pargR(mdpFlags, whf, z, isFg,
   2181                 static_cast<eRotFlags>(rotFlags),
   2182                 layer->planeAlpha,
   2183                 (ovutils::eBlending) getBlending(layer->blending));
   2184         if(configMdp(ctx->mOverlay, pargR, orient,
   2185                     cropR, dstR, metadata, rDest) < 0) {
   2186             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
   2187             return -1;
   2188         }
   2189     }
   2190 
   2191     return 0;
   2192 }
   2193 
   2194 }; //namespace
   2195 
   2196