Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2012-2016, 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 "hdmi.h"
     23 #include "qdMetaData.h"
     24 #include "mdp_version.h"
     25 #include "hwc_fbupdate.h"
     26 #include "hwc_ad.h"
     27 #include <overlayRotator.h>
     28 #include "hwc_copybit.h"
     29 #include "qd_utils.h"
     30 
     31 using namespace overlay;
     32 using namespace qdutils;
     33 using namespace overlay::utils;
     34 namespace ovutils = overlay::utils;
     35 
     36 namespace qhwc {
     37 
     38 //==============MDPComp========================================================
     39 
     40 IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
     41 bool MDPComp::sIdleFallBack = 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::sEnableYUVsplit = false;
     48 bool MDPComp::sSrcSplitEnabled = false;
     49 bool MDPComp::enablePartialUpdateForMDP3 = false;
     50 bool MDPComp::sIsPartialUpdateActive = true;
     51 MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
     52     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
     53         sSrcSplitEnabled = true;
     54         return new MDPCompSrcSplit(dpy);
     55     } else if(isDisplaySplit(ctx, dpy)) {
     56         return new MDPCompSplit(dpy);
     57     }
     58     return new MDPCompNonSplit(dpy);
     59 }
     60 
     61 MDPComp::MDPComp(int dpy) : mDpy(dpy), mModeOn(false), mPrevModeOn(false) {
     62 };
     63 
     64 void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
     65 {
     66     if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
     67         return;
     68 
     69     dumpsys_log(buf,"HWC Map for Dpy: %s \n",
     70                 (mDpy == 0) ? "\"PRIMARY\"" :
     71                 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
     72     dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
     73                 "fbCount:%2d \n", mCurrentFrame.layerCount,
     74                 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
     75     dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
     76                 (mCurrentFrame.needsRedraw? "YES" : "NO"),
     77                 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
     78     if(isDisplaySplit(ctx, mDpy)) {
     79         dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
     80                 "Right: [%d, %d, %d, %d] \n",
     81                 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
     82                 ctx->listStats[mDpy].lRoi.right,
     83                 ctx->listStats[mDpy].lRoi.bottom,
     84                 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
     85                 ctx->listStats[mDpy].rRoi.right,
     86                 ctx->listStats[mDpy].rRoi.bottom);
     87     } else {
     88         dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
     89                 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
     90                 ctx->listStats[mDpy].lRoi.right,
     91                 ctx->listStats[mDpy].lRoi.bottom);
     92     }
     93     dumpsys_log(buf," ---------------------------------------------  \n");
     94     dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
     95     dumpsys_log(buf," ---------------------------------------------  \n");
     96     for(int index = 0; index < mCurrentFrame.layerCount; index++ )
     97         dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
     98                     index,
     99                     (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
    100                      mCurrentFrame.layerToMDP[index],
    101                     (mCurrentFrame.isFBComposed[index] ?
    102                     (mCurrentFrame.drop[index] ? "DROP" :
    103                     (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
    104                     (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
    105     mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
    106     dumpsys_log(buf,"\n");
    107 }
    108 
    109 bool MDPComp::init(hwc_context_t *ctx) {
    110 
    111     if(!ctx) {
    112         ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
    113         return false;
    114     }
    115 
    116     char property[PROPERTY_VALUE_MAX] = {0};
    117 
    118     sEnabled = false;
    119     if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
    120        (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
    121        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    122         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    123         sEnabled = true;
    124     }
    125 
    126     sEnableMixedMode = true;
    127     if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
    128        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    129         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    130         sEnableMixedMode = false;
    131     }
    132 
    133     sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
    134     if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
    135         int val = atoi(property);
    136         if(val >= 0)
    137             sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
    138     }
    139 
    140     if(ctx->mMDP.panel != MIPI_CMD_PANEL &&
    141             (ctx->mMDP.version >= qdutils::MDP_V4_0)) {
    142         sIdleInvalidator = IdleInvalidator::getInstance();
    143         if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
    144             delete sIdleInvalidator;
    145             sIdleInvalidator = NULL;
    146         }
    147     }
    148 
    149     if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
    150         !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
    151             property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
    152             (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
    153             !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
    154         sEnableYUVsplit = true;
    155     }
    156 
    157     bool defaultPTOR = false;
    158     //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
    159     //8x16 and 8x39 targets by default
    160     if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
    161             (qdutils::MDPVersion::getInstance().is8x16() ||
    162                 qdutils::MDPVersion::getInstance().is8x39())) {
    163         defaultPTOR = true;
    164     }
    165 
    166     if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
    167                 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
    168         ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
    169                                                     HWC_DISPLAY_PRIMARY);
    170     }
    171 
    172     if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
    173           (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
    174        enablePartialUpdateForMDP3 = true;
    175     }
    176 
    177     if(!enablePartialUpdateForMDP3 &&
    178           (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    179            (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    180        enablePartialUpdateForMDP3 = true;
    181     }
    182 
    183     int retPartialUpdatePref = getPartialUpdatePref(ctx);
    184     if(retPartialUpdatePref >= 0)
    185        sIsPartialUpdateActive = (retPartialUpdatePref != 0);
    186 
    187     return true;
    188 }
    189 
    190 void MDPComp::reset(hwc_context_t *ctx) {
    191     const int numLayers = ctx->listStats[mDpy].numAppLayers;
    192     mCurrentFrame.reset(numLayers);
    193     ctx->mOverlay->clear(mDpy);
    194     ctx->mLayerRotMap[mDpy]->clear();
    195     resetROI(ctx, mDpy);
    196     memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    197     mCurrentFrame.dropCount = 0;
    198 }
    199 
    200 void MDPComp::reset() {
    201     mPrevModeOn = mModeOn;
    202     mModeOn = false;
    203 }
    204 
    205 void MDPComp::timeout_handler(void *udata) {
    206     struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
    207     bool handleTimeout = false;
    208 
    209     if(!ctx) {
    210         ALOGE("%s: received empty data in timer callback", __FUNCTION__);
    211         return;
    212     }
    213 
    214     ctx->mDrawLock.lock();
    215 
    216     /* Handle timeout event only if the previous composition
    217        on any display is MDP or MIXED*/
    218     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
    219         if(ctx->mMDPComp[i])
    220             handleTimeout =
    221                     ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
    222     }
    223 
    224     if(!handleTimeout) {
    225         ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
    226         ctx->mDrawLock.unlock();
    227         return;
    228     }
    229     if(!ctx->proc) {
    230         ALOGE("%s: HWC proc not registered", __FUNCTION__);
    231         ctx->mDrawLock.unlock();
    232         return;
    233     }
    234     sIdleFallBack = true;
    235     ctx->mDrawLock.unlock();
    236     /* Trigger SF to redraw the current frame */
    237     ctx->proc->invalidate(ctx->proc);
    238 }
    239 
    240 void MDPComp::setIdleTimeout(const uint32_t& timeout) {
    241     enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
    242 
    243     if(sIdleInvalidator) {
    244         if(timeout <= ONE_REFRESH_PERIOD_MS) {
    245             //If the specified timeout is < 1 draw cycle worth, "virtually"
    246             //disable idle timeout. The ideal way for clients to disable
    247             //timeout is to set it to 0
    248             sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
    249             ALOGI("Disabled idle timeout");
    250             return;
    251         }
    252         sIdleInvalidator->setIdleTimeout(timeout);
    253         ALOGI("Idle timeout set to %u", timeout);
    254     } else {
    255         ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
    256     }
    257 }
    258 
    259 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
    260                                    hwc_display_contents_1_t* list) {
    261     LayerProp *layerProp = ctx->layerProp[mDpy];
    262 
    263     for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
    264         hwc_layer_1_t* layer = &(list->hwLayers[index]);
    265         if(!mCurrentFrame.isFBComposed[index]) {
    266             layerProp[index].mFlags |= HWC_MDPCOMP;
    267             layer->compositionType = HWC_OVERLAY;
    268             layer->hints |= HWC_HINT_CLEAR_FB;
    269         } else {
    270             /* Drop the layer when its already present in FB OR when it lies
    271              * outside frame's ROI */
    272             if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
    273                 layer->compositionType = HWC_OVERLAY;
    274             }
    275         }
    276     }
    277 }
    278 
    279 void MDPComp::setRedraw(hwc_context_t *ctx,
    280         hwc_display_contents_1_t* list) {
    281     mCurrentFrame.needsRedraw = false;
    282     if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
    283             (list->flags & HWC_GEOMETRY_CHANGED) ||
    284             isSkipPresent(ctx, mDpy)) {
    285         mCurrentFrame.needsRedraw = true;
    286     }
    287 }
    288 
    289 MDPComp::FrameInfo::FrameInfo() {
    290     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
    291     reset(0);
    292 }
    293 
    294 void MDPComp::FrameInfo::reset(const int& numLayers) {
    295     for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
    296         if(mdpToLayer[i].pipeInfo) {
    297             delete mdpToLayer[i].pipeInfo;
    298             mdpToLayer[i].pipeInfo = NULL;
    299             //We dont own the rotator
    300             mdpToLayer[i].rot = NULL;
    301         }
    302     }
    303 
    304     memset(&mdpToLayer, 0, sizeof(mdpToLayer));
    305     memset(&layerToMDP, -1, sizeof(layerToMDP));
    306     memset(&isFBComposed, 1, sizeof(isFBComposed));
    307 
    308     layerCount = numLayers;
    309     fbCount = numLayers;
    310     mdpCount = 0;
    311     needsRedraw = true;
    312     fbZ = -1;
    313 }
    314 
    315 void MDPComp::FrameInfo::map() {
    316     // populate layer and MDP maps
    317     int mdpIdx = 0;
    318     for(int idx = 0; idx < layerCount; idx++) {
    319         if(!isFBComposed[idx]) {
    320             mdpToLayer[mdpIdx].listIndex = idx;
    321             layerToMDP[idx] = mdpIdx++;
    322         }
    323     }
    324 }
    325 
    326 MDPComp::LayerCache::LayerCache() {
    327     reset();
    328 }
    329 
    330 void MDPComp::LayerCache::reset() {
    331     memset(&isFBComposed, true, sizeof(isFBComposed));
    332     memset(&drop, false, sizeof(drop));
    333     layerCount = 0;
    334 }
    335 
    336 void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
    337     layerCount = curFrame.layerCount;
    338     memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
    339     memcpy(&drop, &curFrame.drop, sizeof(drop));
    340 }
    341 
    342 bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
    343                                       hwc_display_contents_1_t* list) {
    344     if(layerCount != curFrame.layerCount)
    345         return false;
    346     for(int i = 0; i < curFrame.layerCount; i++) {
    347         if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
    348                 (curFrame.drop[i] != drop[i])) {
    349             return false;
    350         }
    351         hwc_layer_1_t const* layer = &list->hwLayers[i];
    352         if(curFrame.isFBComposed[i] && layerUpdating(layer)) {
    353             return false;
    354         }
    355     }
    356     return true;
    357 }
    358 
    359 bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
    360                                       hwc_display_contents_1_t* list) {
    361 
    362     if(layerCount != ctx->listStats[dpy].numAppLayers)
    363         return false;
    364 
    365     if((list->flags & HWC_GEOMETRY_CHANGED) ||
    366        isSkipPresent(ctx, dpy)) {
    367         return false;
    368     }
    369 
    370     for(int i = 0; i < layerCount; i++) {
    371         hwc_layer_1_t const* layer = &list->hwLayers[i];
    372         if(layerUpdating(layer))
    373             return false;
    374     }
    375 
    376     return true;
    377 }
    378 
    379 bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
    380     private_handle_t *hnd = (private_handle_t *)layer->handle;
    381     if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
    382         (not isValidDimension(ctx,layer)) ||
    383         isSkipLayer(layer)) {
    384         //More conditions here, sRGB+Blend etc
    385         return false;
    386     }
    387     return true;
    388 }
    389 
    390 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
    391     private_handle_t *hnd = (private_handle_t *)layer->handle;
    392 
    393     if(!hnd) {
    394         if (layer->flags & HWC_COLOR_FILL) {
    395             // Color layer
    396             return true;
    397         }
    398         ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
    399         return false;
    400     }
    401 
    402     //XXX: Investigate doing this with pixel phase on MDSS
    403     if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
    404         return false;
    405 
    406     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    407     hwc_rect_t dst = layer->displayFrame;
    408     bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
    409     int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
    410     int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
    411     int dst_w = dst.right - dst.left;
    412     int dst_h = dst.bottom - dst.top;
    413     float w_scale = ((float)crop_w / (float)dst_w);
    414     float h_scale = ((float)crop_h / (float)dst_h);
    415     MDPVersion& mdpHw = MDPVersion::getInstance();
    416 
    417     /* Workaround for MDP HW limitation in DSI command mode panels where
    418      * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
    419      * less than 5 pixels
    420      * There also is a HW limilation in MDP, minimum block size is 2x2
    421      * Fallback to GPU if height is less than 2.
    422      */
    423     if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
    424         return false;
    425 
    426     if((w_scale > 1.0f) || (h_scale > 1.0f)) {
    427         const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
    428         const float w_dscale = w_scale;
    429         const float h_dscale = h_scale;
    430 
    431         if(ctx->mMDP.version >= qdutils::MDSS_V5) {
    432 
    433             if(!mdpHw.supportsDecimation()) {
    434                 /* On targets that doesnt support Decimation (eg.,8x26)
    435                  * maximum downscale support is overlay pipe downscale.
    436                  */
    437                 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
    438                         w_dscale > maxMDPDownscale ||
    439                         h_dscale > maxMDPDownscale)
    440                     return false;
    441             } else {
    442                 // Decimation on macrotile format layers is not supported.
    443                 if(isTileRendered(hnd)) {
    444                     /* Bail out if
    445                      *      1. Src crop > Mixer limit on nonsplit MDPComp
    446                      *      2. exceeds maximum downscale limit
    447                      */
    448                     if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
    449                                 !sSrcSplitEnabled) ||
    450                             w_dscale > maxMDPDownscale ||
    451                             h_dscale > maxMDPDownscale) {
    452                         return false;
    453                     }
    454                 } else if(w_dscale > 64 || h_dscale > 64)
    455                     return false;
    456             }
    457         } else { //A-family
    458             if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
    459                 return false;
    460         }
    461     }
    462 
    463     if((w_scale < 1.0f) || (h_scale < 1.0f)) {
    464         const uint32_t upscale = mdpHw.getMaxMDPUpscale();
    465         const float w_uscale = 1.0f / w_scale;
    466         const float h_uscale = 1.0f / h_scale;
    467 
    468         if(w_uscale > upscale || h_uscale > upscale)
    469             return false;
    470     }
    471 
    472     return true;
    473 }
    474 
    475 bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
    476     bool ret = true;
    477 
    478     if(!isEnabled()) {
    479         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
    480         ret = false;
    481     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
    482                qdutils::MDPVersion::getInstance().is8x16() ||
    483                qdutils::MDPVersion::getInstance().is8x39()) &&
    484             ctx->mVideoTransFlag &&
    485             isSecondaryConnected(ctx)) {
    486         //1 Padding round to shift pipes across mixers
    487         ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
    488                 __FUNCTION__);
    489         ret = false;
    490     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
    491                qdutils::MDPVersion::getInstance().is8x16() ||
    492                qdutils::MDPVersion::getInstance().is8x39()) &&
    493               !mDpy && isSecondaryAnimating(ctx) &&
    494               isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
    495         ALOGD_IF(isDebug(),"%s: Display animation in progress",
    496                  __FUNCTION__);
    497         ret = false;
    498     } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
    499        /* TODO: freeing up all the resources only for the targets having total
    500                 number of pipes < 8. Need to analyze number of VIG pipes used
    501                 for primary in previous draw cycle and accordingly decide
    502                 whether to fall back to full GPU comp or video only comp
    503         */
    504         if(isSecondaryConfiguring(ctx)) {
    505             ALOGD_IF( isDebug(),"%s: External Display connection is pending",
    506                       __FUNCTION__);
    507             ret = false;
    508         } else if(ctx->isPaddingRound) {
    509             ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
    510                      __FUNCTION__,mDpy);
    511             ret = false;
    512         }
    513     }
    514     return ret;
    515 }
    516 
    517 void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
    518     hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
    519     fbRect = getIntersection(fbRect, roi);
    520 }
    521 
    522 /* 1) Identify layers that are not visible or lying outside the updating ROI and
    523  *    drop them from composition.
    524  * 2) If we have a scaling layer which needs cropping against generated
    525  *    ROI, reset ROI to full resolution. */
    526 bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
    527         hwc_display_contents_1_t* list) {
    528     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    529     hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
    530 
    531     for(int i = numAppLayers - 1; i >= 0; i--){
    532         if(!isValidRect(visibleRect)) {
    533             mCurrentFrame.drop[i] = true;
    534             mCurrentFrame.dropCount++;
    535             continue;
    536         }
    537 
    538         const hwc_layer_1_t* layer =  &list->hwLayers[i];
    539         hwc_rect_t dstRect = layer->displayFrame;
    540         hwc_rect_t res  = getIntersection(visibleRect, dstRect);
    541 
    542         if(!isValidRect(res)) {
    543             mCurrentFrame.drop[i] = true;
    544             mCurrentFrame.dropCount++;
    545         } else {
    546             /* Reset frame ROI when any layer which needs scaling also needs ROI
    547              * cropping */
    548             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
    549                 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
    550                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    551                 mCurrentFrame.dropCount = 0;
    552                 return false;
    553             }
    554 
    555             /* deduct any opaque region from visibleRect */
    556             if (layer->blending == HWC_BLENDING_NONE &&
    557                     layer->planeAlpha == 0xFF)
    558                 visibleRect = deductRect(visibleRect, res);
    559         }
    560     }
    561     return true;
    562 }
    563 
    564 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
    565  * are updating. If DirtyRegion is applicable, calculate it by accounting all
    566  * the changing layer's dirtyRegion. */
    567 void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
    568         hwc_display_contents_1_t* list) {
    569     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    570     if(!canPartialUpdate(ctx, list))
    571         return;
    572 
    573     struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
    574     hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
    575         (int)ctx->dpyAttr[mDpy].yres};
    576 
    577     for(int index = 0; index < numAppLayers; index++ ) {
    578         hwc_layer_1_t* layer = &list->hwLayers[index];
    579         if (layerUpdating(layer) ||
    580                 isYuvBuffer((private_handle_t *)layer->handle)) {
    581             hwc_rect_t dirtyRect = (struct hwc_rect){0, 0, 0, 0};;
    582             if(!needsScaling(layer) && !layer->transform &&
    583                    (!isYuvBuffer((private_handle_t *)layer->handle)))
    584             {
    585                 dirtyRect = calculateDirtyRect(layer, fullFrame);
    586             }
    587 
    588             roi = getUnion(roi, dirtyRect);
    589         }
    590     }
    591 
    592     /* No layer is updating. Still SF wants a refresh.*/
    593     if(!isValidRect(roi))
    594         return;
    595 
    596     // Align ROI coordinates to panel restrictions
    597     roi = getSanitizeROI(roi, fullFrame);
    598 
    599     ctx->listStats[mDpy].lRoi = roi;
    600     if(!validateAndApplyROI(ctx, list))
    601         resetROI(ctx, mDpy);
    602 
    603     ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
    604             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    605             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
    606 }
    607 
    608 void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
    609     hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
    610     hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
    611 
    612     hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
    613     hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
    614     fbRect = getUnion(l_fbRect, r_fbRect);
    615 }
    616 /* 1) Identify layers that are not visible or lying outside BOTH the updating
    617  *    ROI's and drop them from composition. If a layer is spanning across both
    618  *    the halves of the screen but needed by only ROI, the non-contributing
    619  *    half will not be programmed for MDP.
    620  * 2) If we have a scaling layer which needs cropping against generated
    621  *    ROI, reset ROI to full resolution. */
    622 bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
    623         hwc_display_contents_1_t* list) {
    624 
    625     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    626 
    627     hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
    628     hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
    629 
    630     for(int i = numAppLayers - 1; i >= 0; i--){
    631         if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
    632         {
    633             mCurrentFrame.drop[i] = true;
    634             mCurrentFrame.dropCount++;
    635             continue;
    636         }
    637 
    638         const hwc_layer_1_t* layer =  &list->hwLayers[i];
    639         hwc_rect_t dstRect = layer->displayFrame;
    640 
    641         hwc_rect_t l_res  = getIntersection(visibleRectL, dstRect);
    642         hwc_rect_t r_res  = getIntersection(visibleRectR, dstRect);
    643         hwc_rect_t res = getUnion(l_res, r_res);
    644 
    645         if(!isValidRect(l_res) && !isValidRect(r_res)) {
    646             mCurrentFrame.drop[i] = true;
    647             mCurrentFrame.dropCount++;
    648         } else {
    649             /* Reset frame ROI when any layer which needs scaling also needs ROI
    650              * cropping */
    651             if(!isSameRect(res, dstRect) && needsScaling (layer)) {
    652                 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
    653                 mCurrentFrame.dropCount = 0;
    654                 return false;
    655             }
    656 
    657             if (layer->blending == HWC_BLENDING_NONE &&
    658                     layer->planeAlpha == 0xFF) {
    659                 visibleRectL = deductRect(visibleRectL, l_res);
    660                 visibleRectR = deductRect(visibleRectR, r_res);
    661             }
    662         }
    663     }
    664     return true;
    665 }
    666 /* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
    667  * are updating. If DirtyRegion is applicable, calculate it by accounting all
    668  * the changing layer's dirtyRegion. */
    669 void MDPCompSplit::generateROI(hwc_context_t *ctx,
    670         hwc_display_contents_1_t* list) {
    671     if(!canPartialUpdate(ctx, list))
    672         return;
    673 
    674     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    675     int lSplit = getLeftSplit(ctx, mDpy);
    676 
    677     int hw_h = (int)ctx->dpyAttr[mDpy].yres;
    678     int hw_w = (int)ctx->dpyAttr[mDpy].xres;
    679 
    680     struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
    681     struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
    682 
    683     struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
    684     struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
    685 
    686     for(int index = 0; index < numAppLayers; index++ ) {
    687         hwc_layer_1_t* layer = &list->hwLayers[index];
    688         private_handle_t *hnd = (private_handle_t *)layer->handle;
    689         if (layerUpdating(layer) || isYuvBuffer(hnd)) {
    690             hwc_rect_t l_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
    691             hwc_rect_t r_dirtyRect = (struct hwc_rect){0, 0, 0, 0};
    692             if(!needsScaling(layer) && !layer->transform)
    693             {
    694                 l_dirtyRect = calculateDirtyRect(layer, l_frame);
    695                 r_dirtyRect = calculateDirtyRect(layer, r_frame);
    696             }
    697             if(isValidRect(l_dirtyRect))
    698                 l_roi = getUnion(l_roi, l_dirtyRect);
    699 
    700             if(isValidRect(r_dirtyRect))
    701                 r_roi = getUnion(r_roi, r_dirtyRect);
    702         }
    703     }
    704 
    705     /* For panels that cannot accept commands in both the interfaces, we cannot
    706      * send two ROI's (for each half). We merge them into single ROI and split
    707      * them across lSplit for MDP mixer use. The ROI's will be merged again
    708      * finally before udpating the panel in the driver. */
    709     if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
    710         hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
    711         l_roi = getIntersection(temp_roi, l_frame);
    712         r_roi = getIntersection(temp_roi, r_frame);
    713     }
    714 
    715     /* No layer is updating. Still SF wants a refresh. */
    716     if(!isValidRect(l_roi) && !isValidRect(r_roi))
    717         return;
    718 
    719     l_roi = getSanitizeROI(l_roi, l_frame);
    720     r_roi = getSanitizeROI(r_roi, r_frame);
    721 
    722     ctx->listStats[mDpy].lRoi = l_roi;
    723     ctx->listStats[mDpy].rRoi = r_roi;
    724 
    725     if(!validateAndApplyROI(ctx, list))
    726         resetROI(ctx, mDpy);
    727 
    728     ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
    729             "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
    730             ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
    731             ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
    732             ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
    733             ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
    734 }
    735 
    736 /* Checks for conditions where all the layers marked for MDP comp cannot be
    737  * bypassed. On such conditions we try to bypass atleast YUV layers */
    738 bool MDPComp::tryFullFrame(hwc_context_t *ctx,
    739                                 hwc_display_contents_1_t* list){
    740 
    741     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    742     int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
    743 
    744     // Fall back to video only composition, if AIV video mode is enabled
    745     if(ctx->listStats[mDpy].mAIVVideoMode) {
    746         ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
    747             __FUNCTION__, mDpy);
    748         return false;
    749     }
    750 
    751     // No Idle fall back, if secure display or secure RGB layers are present or
    752     // if there's only a single layer being composed
    753     if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
    754                     !ctx->listStats[mDpy].secureRGBCount) &&
    755                     (ctx->listStats[mDpy].numAppLayers != 1)) {
    756         ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
    757         return false;
    758     }
    759 
    760     if(!mDpy && isSecondaryAnimating(ctx) &&
    761        (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
    762        isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
    763         ALOGD_IF(isDebug(),"%s: Display animation in progress",
    764                  __FUNCTION__);
    765         return false;
    766     }
    767 
    768     // if secondary is configuring or Padding round, fall back to video only
    769     // composition and release all assigned non VIG pipes from primary.
    770     if(isSecondaryConfiguring(ctx)) {
    771         ALOGD_IF( isDebug(),"%s: External Display connection is pending",
    772                   __FUNCTION__);
    773         return false;
    774     } else if(ctx->isPaddingRound) {
    775         ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
    776                  __FUNCTION__,mDpy);
    777         return false;
    778     }
    779 
    780     MDPVersion& mdpHw = MDPVersion::getInstance();
    781     if(mDpy > HWC_DISPLAY_PRIMARY &&
    782             (priDispW >  (int) mdpHw.getMaxMixerWidth()) &&
    783             (ctx->dpyAttr[mDpy].xres <  mdpHw.getMaxMixerWidth())) {
    784         // Disable MDP comp on Secondary when the primary is highres panel and
    785         // the secondary is a normal 1080p, because, MDP comp on secondary under
    786         // in such usecase, decimation gets used for downscale and there will be
    787         // a quality mismatch when there will be a fallback to GPU comp
    788         ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
    789               __FUNCTION__);
    790         return false;
    791     }
    792 
    793     // check for action safe flag and MDP scaling mode which requires scaling.
    794     if(ctx->dpyAttr[mDpy].mActionSafePresent
    795             || ctx->dpyAttr[mDpy].mMDPScalingMode) {
    796         ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
    797         return false;
    798     }
    799 
    800     for(int i = 0; i < numAppLayers; ++i) {
    801         hwc_layer_1_t* layer = &list->hwLayers[i];
    802         private_handle_t *hnd = (private_handle_t *)layer->handle;
    803 
    804         if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
    805             if(!canUseRotator(ctx, mDpy)) {
    806                 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
    807                         __FUNCTION__, mDpy);
    808                 return false;
    809             }
    810         }
    811 
    812         //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
    813         // may not need it if Gfx pre-rotation can handle all flips & rotations
    814         int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
    815         if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
    816                 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
    817             return false;
    818     }
    819 
    820     if(ctx->mAD->isDoable()) {
    821         return false;
    822     }
    823 
    824     //If all above hard conditions are met we can do full or partial MDP comp.
    825     bool ret = false;
    826     if(fullMDPComp(ctx, list)) {
    827         ret = true;
    828     } else if(fullMDPCompWithPTOR(ctx, list)) {
    829         ret = true;
    830     } else if(partialMDPComp(ctx, list)) {
    831         ret = true;
    832     }
    833 
    834     return ret;
    835 }
    836 
    837 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
    838 
    839     if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
    840         return false;
    841 
    842     //Will benefit presentation / secondary-only layer.
    843     if((mDpy > HWC_DISPLAY_PRIMARY) &&
    844             (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
    845         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
    846         return false;
    847     }
    848 
    849     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    850     for(int i = 0; i < numAppLayers; i++) {
    851         hwc_layer_1_t* layer = &list->hwLayers[i];
    852         if(not mCurrentFrame.drop[i] and
    853            not isSupportedForMDPComp(ctx, layer)) {
    854             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
    855             return false;
    856         }
    857     }
    858 
    859     if(!mDpy && isSecondaryConnected(ctx) &&
    860            (qdutils::MDPVersion::getInstance().is8x16() ||
    861             qdutils::MDPVersion::getInstance().is8x26() ||
    862             qdutils::MDPVersion::getInstance().is8x39()) &&
    863            isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
    864         ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
    865         return false;
    866     }
    867 
    868     mCurrentFrame.fbCount = 0;
    869     memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
    870            sizeof(mCurrentFrame.isFBComposed));
    871     mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
    872         mCurrentFrame.dropCount;
    873 
    874     if(sEnableYUVsplit){
    875         adjustForSourceSplit(ctx, list);
    876     }
    877 
    878     if(!postHeuristicsHandling(ctx, list)) {
    879         ALOGD_IF(isDebug(), "post heuristic handling failed");
    880         reset(ctx);
    881         return false;
    882     }
    883     ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
    884              __FUNCTION__);
    885     return true;
    886 }
    887 
    888 /* Full MDP Composition with Peripheral Tiny Overlap Removal.
    889  * MDP bandwidth limitations can be avoided, if the overlap region
    890  * covered by the smallest layer at a higher z-order, gets composed
    891  * by Copybit on a render buffer, which can be queued to MDP.
    892  */
    893 bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
    894     hwc_display_contents_1_t* list) {
    895 
    896     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
    897     const int stagesForMDP = min(sMaxPipesPerMixer,
    898             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
    899 
    900     // Hard checks where we cannot use this mode
    901     if (mDpy || !ctx->mCopyBit[mDpy]) {
    902         ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
    903         return false;
    904     }
    905 
    906     // Frame level checks
    907     if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
    908         isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
    909         isSecurePresent(ctx, mDpy)) {
    910         ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
    911         return false;
    912     }
    913     // MDP comp checks
    914     for(int i = 0; i < numAppLayers; i++) {
    915         hwc_layer_1_t* layer = &list->hwLayers[i];
    916         if(not isSupportedForMDPComp(ctx, layer)) {
    917             ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
    918             return false;
    919         }
    920     }
    921 
    922     if(!mDpy && isSecondaryConnected(ctx) &&
    923            (qdutils::MDPVersion::getInstance().is8x16() ||
    924             qdutils::MDPVersion::getInstance().is8x26() ||
    925             qdutils::MDPVersion::getInstance().is8x39()) &&
    926            isYuvPresent(ctx, HWC_DISPLAY_VIRTUAL)) {
    927         ALOGD_IF(isDebug(), "%s: YUV layer present on secondary", __FUNCTION__);
    928         return false;
    929     }
    930 
    931     /* We cannot use this composition mode, if:
    932      1. A below layer needs scaling.
    933      2. Overlap is not peripheral to display.
    934      3. Overlap or a below layer has 90 degree transform.
    935      4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
    936      */
    937 
    938     int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
    939     hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
    940     memset(overlapRect, 0, sizeof(overlapRect));
    941     int layerPixelCount, minPixelCount = 0;
    942     int numPTORLayersFound = 0;
    943     for (int i = numAppLayers-1; (i >= 0 &&
    944                                   numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
    945         hwc_layer_1_t* layer = &list->hwLayers[i];
    946         hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    947         hwc_rect_t dispFrame = layer->displayFrame;
    948         layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
    949         // PTOR layer should be peripheral and cannot have transform
    950         if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
    951                                 has90Transform(layer)) {
    952             continue;
    953         }
    954         if((3 * (layerPixelCount + minPixelCount)) >
    955                 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
    956             // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
    957             continue;
    958         }
    959         bool found = false;
    960         for (int j = i-1; j >= 0; j--) {
    961             // Check if the layers below this layer qualifies for PTOR comp
    962             hwc_layer_1_t* layer = &list->hwLayers[j];
    963             hwc_rect_t disFrame = layer->displayFrame;
    964             // Layer below PTOR is intersecting and has 90 degree transform or
    965             // needs scaling cannot be supported.
    966             if (isValidRect(getIntersection(dispFrame, disFrame))) {
    967                 if (has90Transform(layer) || needsScaling(layer)) {
    968                     found = false;
    969                     break;
    970                 }
    971                 found = true;
    972             }
    973         }
    974         // Store the minLayer Index
    975         if(found) {
    976             minLayerIndex[numPTORLayersFound] = i;
    977             overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
    978             minPixelCount += layerPixelCount;
    979             numPTORLayersFound++;
    980         }
    981     }
    982 
    983     // No overlap layers
    984     if (!numPTORLayersFound)
    985         return false;
    986 
    987     // Store the displayFrame and the sourceCrops of the layers
    988     hwc_rect_t displayFrame[numAppLayers];
    989     hwc_rect_t sourceCrop[numAppLayers];
    990     for(int i = 0; i < numAppLayers; i++) {
    991         hwc_layer_1_t* layer = &list->hwLayers[i];
    992         displayFrame[i] = layer->displayFrame;
    993         sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
    994     }
    995 
    996     /**
    997      * It's possible that 2 PTOR layers might have overlapping.
    998      * In such case, remove the intersection(again if peripheral)
    999      * from the lower PTOR layer to avoid overlapping.
   1000      * If intersection is not on peripheral then compromise
   1001      * by reducing number of PTOR layers.
   1002      **/
   1003     hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
   1004     if(isValidRect(commonRect)) {
   1005         overlapRect[1] = deductRect(overlapRect[1], commonRect);
   1006         list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
   1007     }
   1008 
   1009     ctx->mPtorInfo.count = numPTORLayersFound;
   1010     for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
   1011         ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
   1012     }
   1013 
   1014     if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
   1015         // reset PTOR
   1016         ctx->mPtorInfo.count = 0;
   1017         if(isValidRect(commonRect)) {
   1018             // If PTORs are intersecting restore displayframe of PTOR[1]
   1019             // before returning, as we have modified it above.
   1020             list->hwLayers[minLayerIndex[1]].displayFrame =
   1021                     displayFrame[minLayerIndex[1]];
   1022         }
   1023         return false;
   1024     }
   1025     private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
   1026     Whf layerWhf[MAX_PTOR_LAYERS]; // To store w,h,f of PTOR layers
   1027 
   1028     // Store the blending mode, planeAlpha, and transform of PTOR layers
   1029     int32_t blending[numPTORLayersFound];
   1030     uint8_t planeAlpha[numPTORLayersFound];
   1031     uint32_t transform[numPTORLayersFound];
   1032 
   1033     for(int j = 0; j < numPTORLayersFound; j++) {
   1034         int index =  ctx->mPtorInfo.layerIndex[j];
   1035 
   1036         // Update src crop of PTOR layer
   1037         hwc_layer_1_t* layer = &list->hwLayers[index];
   1038         layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
   1039         layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
   1040         layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
   1041         layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
   1042 
   1043         // Store & update w, h, format of PTOR layer
   1044         private_handle_t *hnd = (private_handle_t *)layer->handle;
   1045         Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
   1046         layerWhf[j] = whf;
   1047         hnd->width = renderBuf->width;
   1048         hnd->height = renderBuf->height;
   1049         hnd->format = renderBuf->format;
   1050 
   1051         // Store & update blending mode, planeAlpha and transform of PTOR layer
   1052         blending[j] = layer->blending;
   1053         planeAlpha[j] = layer->planeAlpha;
   1054         transform[j] = layer->transform;
   1055         layer->blending = HWC_BLENDING_NONE;
   1056         layer->planeAlpha = 0xFF;
   1057         layer->transform = 0;
   1058 
   1059         // Remove overlap from crop & displayFrame of below layers
   1060         for (int i = 0; i < index && index !=-1; i++) {
   1061             layer = &list->hwLayers[i];
   1062             if(!isValidRect(getIntersection(layer->displayFrame,
   1063                                             overlapRect[j])))  {
   1064                 continue;
   1065             }
   1066             // Update layer attributes
   1067             hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
   1068             hwc_rect_t destRect = deductRect(layer->displayFrame,
   1069                         getIntersection(layer->displayFrame, overlapRect[j]));
   1070             qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
   1071                                        layer->transform);
   1072             layer->sourceCropf.left = (float)srcCrop.left;
   1073             layer->sourceCropf.top = (float)srcCrop.top;
   1074             layer->sourceCropf.right = (float)srcCrop.right;
   1075             layer->sourceCropf.bottom = (float)srcCrop.bottom;
   1076         }
   1077     }
   1078 
   1079     mCurrentFrame.mdpCount = numAppLayers;
   1080     mCurrentFrame.fbCount = 0;
   1081     mCurrentFrame.fbZ = -1;
   1082 
   1083     for (int j = 0; j < numAppLayers; j++) {
   1084         if(isValidRect(list->hwLayers[j].displayFrame)) {
   1085             mCurrentFrame.isFBComposed[j] = false;
   1086         } else {
   1087             mCurrentFrame.mdpCount--;
   1088             mCurrentFrame.drop[j] = true;
   1089         }
   1090     }
   1091 
   1092     bool result = postHeuristicsHandling(ctx, list);
   1093 
   1094     // Restore layer attributes
   1095     for(int i = 0; i < numAppLayers; i++) {
   1096         hwc_layer_1_t* layer = &list->hwLayers[i];
   1097         layer->displayFrame = displayFrame[i];
   1098         layer->sourceCropf.left = (float)sourceCrop[i].left;
   1099         layer->sourceCropf.top = (float)sourceCrop[i].top;
   1100         layer->sourceCropf.right = (float)sourceCrop[i].right;
   1101         layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
   1102     }
   1103 
   1104     // Restore w,h,f, blending attributes, and transform of PTOR layers
   1105     for (int i = 0; i < numPTORLayersFound; i++) {
   1106         int idx = ctx->mPtorInfo.layerIndex[i];
   1107         hwc_layer_1_t* layer = &list->hwLayers[idx];
   1108         private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
   1109         hnd->width = layerWhf[i].w;
   1110         hnd->height = layerWhf[i].h;
   1111         hnd->format = layerWhf[i].format;
   1112         layer->blending = blending[i];
   1113         layer->planeAlpha = planeAlpha[i];
   1114         layer->transform = transform[i];
   1115     }
   1116 
   1117     if (!result) {
   1118         // reset PTOR
   1119         ctx->mPtorInfo.count = 0;
   1120         reset(ctx);
   1121     } else {
   1122         ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
   1123                  ctx->mPtorInfo.layerIndex[0],  ctx->mPtorInfo.layerIndex[1]);
   1124     }
   1125 
   1126     ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
   1127              (result ? "successful" : "failed"));
   1128     return result;
   1129 }
   1130 
   1131 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
   1132 {
   1133     if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
   1134         //Mixed mode is disabled/can't be used. No need to even try caching.
   1135         return false;
   1136     }
   1137 
   1138     bool ret = false;
   1139     if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
   1140         //Try load based first
   1141         ret =   loadBasedComp(ctx, list) or
   1142                 cacheBasedComp(ctx, list);
   1143     } else {
   1144         ret =   cacheBasedComp(ctx, list) or
   1145                 loadBasedComp(ctx, list);
   1146     }
   1147 
   1148     return ret;
   1149 }
   1150 
   1151 bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
   1152         hwc_display_contents_1_t* list) {
   1153     if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
   1154         return false;
   1155 
   1156     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1157     mCurrentFrame.reset(numAppLayers);
   1158     updateLayerCache(ctx, list, mCurrentFrame);
   1159 
   1160     //If an MDP marked layer is unsupported cannot do partial MDP Comp
   1161     for(int i = 0; i < numAppLayers; i++) {
   1162         if(!mCurrentFrame.isFBComposed[i]) {
   1163             hwc_layer_1_t* layer = &list->hwLayers[i];
   1164             if(not isSupportedForMDPComp(ctx, layer)) {
   1165                 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
   1166                         __FUNCTION__);
   1167                 reset(ctx);
   1168                 return false;
   1169             }
   1170         }
   1171     }
   1172 
   1173     updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
   1174     /* mark secure RGB layers for MDP comp */
   1175     updateSecureRGB(ctx, list);
   1176     bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
   1177     if(!ret) {
   1178         ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
   1179         reset(ctx);
   1180         return false;
   1181     }
   1182 
   1183     int mdpCount = mCurrentFrame.mdpCount;
   1184 
   1185     if(sEnableYUVsplit){
   1186         adjustForSourceSplit(ctx, list);
   1187     }
   1188 
   1189     //Will benefit cases where a video has non-updating background.
   1190     if((mDpy > HWC_DISPLAY_PRIMARY) and
   1191             (mdpCount > MAX_SEC_LAYERS)) {
   1192         ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
   1193         reset(ctx);
   1194         return false;
   1195     }
   1196 
   1197     if(!postHeuristicsHandling(ctx, list)) {
   1198         ALOGD_IF(isDebug(), "post heuristic handling failed");
   1199         reset(ctx);
   1200         return false;
   1201     }
   1202     ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
   1203              __FUNCTION__);
   1204 
   1205     return true;
   1206 }
   1207 
   1208 bool MDPComp::loadBasedComp(hwc_context_t *ctx,
   1209         hwc_display_contents_1_t* list) {
   1210     if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
   1211         return false;
   1212 
   1213     if(not isLoadBasedCompDoable(ctx)) {
   1214         return false;
   1215     }
   1216 
   1217     const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1218     const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
   1219     const int stagesForMDP = min(sMaxPipesPerMixer,
   1220             ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
   1221 
   1222     int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
   1223     int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
   1224     int lastMDPSupportedIndex = numAppLayers;
   1225     int dropCount = 0;
   1226 
   1227     //Find the minimum MDP batch size
   1228     for(int i = 0; i < numAppLayers;i++) {
   1229         if(mCurrentFrame.drop[i]) {
   1230             dropCount++;
   1231             continue;
   1232         }
   1233         hwc_layer_1_t* layer = &list->hwLayers[i];
   1234         if(not isSupportedForMDPComp(ctx, layer)) {
   1235             lastMDPSupportedIndex = i;
   1236             mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
   1237             fbBatchSize = numNonDroppedLayers - mdpBatchSize;
   1238             break;
   1239         }
   1240     }
   1241 
   1242     ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
   1243             "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
   1244             mCurrentFrame.dropCount);
   1245 
   1246     //Start at a point where the fb batch should at least have 2 layers, for
   1247     //this mode to be justified.
   1248     while(fbBatchSize < 2) {
   1249         ++fbBatchSize;
   1250         --mdpBatchSize;
   1251     }
   1252 
   1253     //If there are no layers for MDP, this mode doesnt make sense.
   1254     if(mdpBatchSize < 1) {
   1255         ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
   1256                 __FUNCTION__);
   1257         return false;
   1258     }
   1259 
   1260     mCurrentFrame.reset(numAppLayers);
   1261 
   1262     //Try with successively smaller mdp batch sizes until we succeed or reach 1
   1263     while(mdpBatchSize > 0) {
   1264         //Mark layers for MDP comp
   1265         int mdpBatchLeft = mdpBatchSize;
   1266         for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
   1267             if(mCurrentFrame.drop[i]) {
   1268                 continue;
   1269             }
   1270             mCurrentFrame.isFBComposed[i] = false;
   1271             --mdpBatchLeft;
   1272         }
   1273 
   1274         mCurrentFrame.fbZ = mdpBatchSize;
   1275         mCurrentFrame.fbCount = fbBatchSize;
   1276         mCurrentFrame.mdpCount = mdpBatchSize;
   1277 
   1278         ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
   1279                 __FUNCTION__, mdpBatchSize, fbBatchSize,
   1280                 mCurrentFrame.dropCount);
   1281 
   1282         if(postHeuristicsHandling(ctx, list)) {
   1283             ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
   1284                      __FUNCTION__);
   1285             ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
   1286                      __FUNCTION__);
   1287             return true;
   1288         }
   1289 
   1290         reset(ctx);
   1291         --mdpBatchSize;
   1292         ++fbBatchSize;
   1293     }
   1294 
   1295     return false;
   1296 }
   1297 
   1298 bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
   1299     if(mDpy or isSecurePresent(ctx, mDpy) or
   1300             isYuvPresent(ctx, mDpy)) {
   1301         return false;
   1302     }
   1303     return true;
   1304 }
   1305 
   1306 bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
   1307         hwc_display_contents_1_t* list){
   1308     if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
   1309             isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
   1310             !sIsPartialUpdateActive || mDpy ) {
   1311         return false;
   1312     }
   1313     if(ctx->listStats[mDpy].secureUI)
   1314         return false;
   1315     return true;
   1316 }
   1317 
   1318 bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
   1319         hwc_display_contents_1_t* list) {
   1320     const bool secureOnly = true;
   1321     return videoOnlyComp(ctx, list, not secureOnly) or
   1322             videoOnlyComp(ctx, list, secureOnly);
   1323 }
   1324 
   1325 bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
   1326         hwc_display_contents_1_t* list, bool secureOnly) {
   1327     if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
   1328         return false;
   1329     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1330 
   1331     mCurrentFrame.reset(numAppLayers);
   1332     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
   1333     updateYUV(ctx, list, secureOnly, mCurrentFrame);
   1334     int mdpCount = mCurrentFrame.mdpCount;
   1335 
   1336     if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
   1337         reset(ctx);
   1338         return false;
   1339     }
   1340 
   1341     /* Bail out if we are processing only secured video layers
   1342      * and we dont have any */
   1343     if(!isSecurePresent(ctx, mDpy) && secureOnly){
   1344         reset(ctx);
   1345         return false;
   1346     }
   1347 
   1348     if(mCurrentFrame.fbCount)
   1349         mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
   1350 
   1351     if(sEnableYUVsplit){
   1352         adjustForSourceSplit(ctx, list);
   1353     }
   1354 
   1355     if(!postHeuristicsHandling(ctx, list)) {
   1356         ALOGD_IF(isDebug(), "post heuristic handling failed");
   1357         reset(ctx);
   1358         return false;
   1359     }
   1360 
   1361     ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
   1362              __FUNCTION__);
   1363     return true;
   1364 }
   1365 
   1366 /* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
   1367 bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
   1368         hwc_display_contents_1_t* list) {
   1369     // Fall back to video only composition, if AIV video mode is enabled
   1370     if(ctx->listStats[mDpy].mAIVVideoMode) {
   1371         ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
   1372             __FUNCTION__, mDpy);
   1373         return false;
   1374     }
   1375 
   1376     const bool secureOnly = true;
   1377     return mdpOnlyLayersComp(ctx, list, not secureOnly) or
   1378             mdpOnlyLayersComp(ctx, list, secureOnly);
   1379 
   1380 }
   1381 
   1382 bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
   1383         hwc_display_contents_1_t* list, bool secureOnly) {
   1384 
   1385     if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
   1386         return false;
   1387 
   1388     /* Bail out if we are processing only secured video layers
   1389      * and we dont have any */
   1390     if(!isSecurePresent(ctx, mDpy) && secureOnly){
   1391         reset(ctx);
   1392         return false;
   1393     }
   1394 
   1395     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1396     mCurrentFrame.reset(numAppLayers);
   1397     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
   1398 
   1399     updateYUV(ctx, list, secureOnly, mCurrentFrame);
   1400     /* mark secure RGB layers for MDP comp */
   1401     updateSecureRGB(ctx, list);
   1402 
   1403     if(mCurrentFrame.mdpCount == 0) {
   1404         reset(ctx);
   1405         return false;
   1406     }
   1407 
   1408     /* find the maximum batch of layers to be marked for framebuffer */
   1409     bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
   1410     if(!ret) {
   1411         ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
   1412         reset(ctx);
   1413         return false;
   1414     }
   1415 
   1416     if(sEnableYUVsplit){
   1417         adjustForSourceSplit(ctx, list);
   1418     }
   1419 
   1420     if(!postHeuristicsHandling(ctx, list)) {
   1421         ALOGD_IF(isDebug(), "post heuristic handling failed");
   1422         reset(ctx);
   1423         return false;
   1424     }
   1425 
   1426     ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
   1427              __FUNCTION__);
   1428     return true;
   1429 }
   1430 
   1431 /* Checks for conditions where YUV layers cannot be bypassed */
   1432 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
   1433     if(isSkipLayer(layer)) {
   1434         ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
   1435         return false;
   1436     }
   1437 
   1438     if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
   1439         ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
   1440         return false;
   1441     }
   1442 
   1443     if(isSecuring(ctx, layer)) {
   1444         ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
   1445         return false;
   1446     }
   1447 
   1448     if(!isValidDimension(ctx, layer)) {
   1449         ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
   1450             __FUNCTION__);
   1451         return false;
   1452     }
   1453 
   1454     if(layer->planeAlpha < 0xFF) {
   1455         ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
   1456                  in video only mode",
   1457                  __FUNCTION__);
   1458         return false;
   1459     }
   1460 
   1461     return true;
   1462 }
   1463 
   1464 /* Checks for conditions where Secure RGB layers cannot be bypassed */
   1465 bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
   1466     if(isSkipLayer(layer)) {
   1467         ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
   1468             __FUNCTION__, mDpy);
   1469         return false;
   1470     }
   1471 
   1472     if(isSecuring(ctx, layer)) {
   1473         ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
   1474         return false;
   1475     }
   1476 
   1477     if(not isSupportedForMDPComp(ctx, layer)) {
   1478         ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
   1479             __FUNCTION__);
   1480         return false;
   1481     }
   1482     return true;
   1483 }
   1484 
   1485 /* starts at fromIndex and check for each layer to find
   1486  * if it it has overlapping with any Updating layer above it in zorder
   1487  * till the end of the batch. returns true if it finds any intersection */
   1488 bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
   1489         int fromIndex, int toIndex) {
   1490     for(int i = fromIndex; i < toIndex; i++) {
   1491         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1492             if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
   1493                 return false;
   1494             }
   1495         }
   1496     }
   1497     return true;
   1498 }
   1499 
   1500 /* Checks if given layer at targetLayerIndex has any
   1501  * intersection with all the updating layers in beween
   1502  * fromIndex and toIndex. Returns true if it finds intersectiion */
   1503 bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
   1504         int fromIndex, int toIndex, int targetLayerIndex) {
   1505     for(int i = fromIndex; i <= toIndex; i++) {
   1506         if(!mCurrentFrame.isFBComposed[i]) {
   1507             if(areLayersIntersecting(&list->hwLayers[i],
   1508                         &list->hwLayers[targetLayerIndex]))  {
   1509                 return true;
   1510             }
   1511         }
   1512     }
   1513     return false;
   1514 }
   1515 
   1516 int MDPComp::getBatch(hwc_display_contents_1_t* list,
   1517         int& maxBatchStart, int& maxBatchEnd,
   1518         int& maxBatchCount) {
   1519     int i = 0;
   1520     int fbZOrder =-1;
   1521     int droppedLayerCt = 0;
   1522     while (i < mCurrentFrame.layerCount) {
   1523         int batchCount = 0;
   1524         int batchStart = i;
   1525         int batchEnd = i;
   1526         /* Adjust batch Z order with the dropped layers so far */
   1527         int fbZ = batchStart - droppedLayerCt;
   1528         int firstZReverseIndex = -1;
   1529         int updatingLayersAbove = 0;//Updating layer count in middle of batch
   1530         while(i < mCurrentFrame.layerCount) {
   1531             if(!mCurrentFrame.isFBComposed[i]) {
   1532                 if(!batchCount) {
   1533                     i++;
   1534                     break;
   1535                 }
   1536                 updatingLayersAbove++;
   1537                 i++;
   1538                 continue;
   1539             } else {
   1540                 if(mCurrentFrame.drop[i]) {
   1541                     i++;
   1542                     droppedLayerCt++;
   1543                     continue;
   1544                 } else if(updatingLayersAbove <= 0) {
   1545                     batchCount++;
   1546                     batchEnd = i;
   1547                     i++;
   1548                     continue;
   1549                 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
   1550 
   1551                     // We have a valid updating layer already. If layer-i not
   1552                     // have overlapping with all updating layers in between
   1553                     // batch-start and i, then we can add layer i to batch.
   1554                     if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
   1555                         batchCount++;
   1556                         batchEnd = i;
   1557                         i++;
   1558                         continue;
   1559                     } else if(canPushBatchToTop(list, batchStart, i)) {
   1560                         //If All the non-updating layers with in this batch
   1561                         //does not have intersection with the updating layers
   1562                         //above in z-order, then we can safely move the batch to
   1563                         //higher z-order. Increment fbZ as it is moving up.
   1564                         if( firstZReverseIndex < 0) {
   1565                             firstZReverseIndex = i;
   1566                         }
   1567                         batchCount++;
   1568                         batchEnd = i;
   1569                         fbZ += updatingLayersAbove;
   1570                         i++;
   1571                         updatingLayersAbove = 0;
   1572                         continue;
   1573                     } else {
   1574                         //both failed.start the loop again from here.
   1575                         if(firstZReverseIndex >= 0) {
   1576                             i = firstZReverseIndex;
   1577                         }
   1578                         break;
   1579                     }
   1580                 }
   1581             }
   1582         }
   1583         if(batchCount > maxBatchCount) {
   1584             maxBatchCount = batchCount;
   1585             maxBatchStart = batchStart;
   1586             maxBatchEnd = batchEnd;
   1587             fbZOrder = fbZ;
   1588         }
   1589     }
   1590     return fbZOrder;
   1591 }
   1592 
   1593 bool  MDPComp::markLayersForCaching(hwc_context_t* ctx,
   1594         hwc_display_contents_1_t* list) {
   1595     /* Idea is to keep as many non-updating(cached) layers in FB and
   1596      * send rest of them through MDP. This is done in 2 steps.
   1597      *   1. Find the maximum contiguous batch of non-updating layers.
   1598      *   2. See if we can improve this batch size for caching by adding
   1599      *      opaque layers around the batch, if they don't have
   1600      *      any overlapping with the updating layers in between.
   1601      * NEVER mark an updating layer for caching.
   1602      * But cached ones can be marked for MDP */
   1603 
   1604     int maxBatchStart = -1;
   1605     int maxBatchEnd = -1;
   1606     int maxBatchCount = 0;
   1607     int fbZ = -1;
   1608 
   1609     /* Nothing is cached. No batching needed */
   1610     if(mCurrentFrame.fbCount == 0) {
   1611         return true;
   1612     }
   1613 
   1614     /* No MDP comp layers, try to use other comp modes */
   1615     if(mCurrentFrame.mdpCount == 0) {
   1616         return false;
   1617     }
   1618 
   1619     fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
   1620 
   1621     /* reset rest of the layers lying inside ROI for MDP comp */
   1622     for(int i = 0; i < mCurrentFrame.layerCount; i++) {
   1623         hwc_layer_1_t* layer = &list->hwLayers[i];
   1624         if((i < maxBatchStart || i > maxBatchEnd) &&
   1625                 mCurrentFrame.isFBComposed[i]){
   1626             if(!mCurrentFrame.drop[i]){
   1627                 //If an unsupported layer is being attempted to
   1628                 //be pulled out we should fail
   1629                 if(not isSupportedForMDPComp(ctx, layer)) {
   1630                     return false;
   1631                 }
   1632                 mCurrentFrame.isFBComposed[i] = false;
   1633             }
   1634         }
   1635     }
   1636 
   1637     // update the frame data
   1638     mCurrentFrame.fbZ = fbZ;
   1639     mCurrentFrame.fbCount = maxBatchCount;
   1640     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1641             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1642 
   1643     ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
   1644             mCurrentFrame.fbCount);
   1645 
   1646     return true;
   1647 }
   1648 
   1649 void MDPComp::updateLayerCache(hwc_context_t* ctx,
   1650         hwc_display_contents_1_t* list, FrameInfo& frame) {
   1651     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
   1652     int fbCount = 0;
   1653 
   1654     for(int i = 0; i < numAppLayers; i++) {
   1655         hwc_layer_1_t * layer = &list->hwLayers[i];
   1656         if (!layerUpdating(layer)) {
   1657             if(!frame.drop[i])
   1658                 fbCount++;
   1659             frame.isFBComposed[i] = true;
   1660         } else {
   1661             frame.isFBComposed[i] = false;
   1662         }
   1663     }
   1664 
   1665     frame.fbCount = fbCount;
   1666     frame.mdpCount = frame.layerCount - frame.fbCount
   1667                                             - frame.dropCount;
   1668 
   1669     ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
   1670             __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
   1671 }
   1672 
   1673 // drop other non-AIV layers from external display list.
   1674 void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
   1675                               hwc_display_contents_1_t* list) {
   1676     for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
   1677         hwc_layer_1_t * layer = &list->hwLayers[i];
   1678          if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
   1679             mCurrentFrame.dropCount++;
   1680             mCurrentFrame.drop[i] = true;
   1681         }
   1682     }
   1683     mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
   1684     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1685             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1686     ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
   1687         __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
   1688         mCurrentFrame.dropCount);
   1689 }
   1690 
   1691 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
   1692         bool secureOnly, FrameInfo& frame) {
   1693     int nYuvCount = ctx->listStats[mDpy].yuvCount;
   1694     for(int index = 0;index < nYuvCount; index++){
   1695         int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
   1696         hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
   1697 
   1698         if(mCurrentFrame.drop[nYuvIndex]) {
   1699             continue;
   1700         }
   1701 
   1702         if(!isYUVDoable(ctx, layer)) {
   1703             if(!frame.isFBComposed[nYuvIndex]) {
   1704                 frame.isFBComposed[nYuvIndex] = true;
   1705                 frame.fbCount++;
   1706             }
   1707         } else {
   1708             if(frame.isFBComposed[nYuvIndex]) {
   1709                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   1710                 if(!secureOnly || isSecureBuffer(hnd)) {
   1711                     frame.isFBComposed[nYuvIndex] = false;
   1712                     frame.fbCount--;
   1713                 }
   1714             }
   1715         }
   1716     }
   1717 
   1718     frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
   1719     ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
   1720 }
   1721 
   1722 void MDPComp::updateSecureRGB(hwc_context_t* ctx,
   1723     hwc_display_contents_1_t* list) {
   1724     int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
   1725     for(int index = 0;index < nSecureRGBCount; index++){
   1726         int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
   1727         hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
   1728 
   1729         if(!isSecureRGBDoable(ctx, layer)) {
   1730             if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
   1731                 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
   1732                 mCurrentFrame.fbCount++;
   1733             }
   1734         } else {
   1735             if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
   1736                 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
   1737                 mCurrentFrame.fbCount--;
   1738             }
   1739         }
   1740     }
   1741 
   1742     mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
   1743             mCurrentFrame.fbCount - mCurrentFrame.dropCount;
   1744     ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
   1745              mCurrentFrame.fbCount);
   1746 }
   1747 
   1748 hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
   1749         hwc_display_contents_1_t* list){
   1750     hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
   1751 
   1752     /* Update only the region of FB needed for composition */
   1753     for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
   1754         if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
   1755             hwc_layer_1_t* layer = &list->hwLayers[i];
   1756             hwc_rect_t dst = layer->displayFrame;
   1757             fbRect = getUnion(fbRect, dst);
   1758         }
   1759     }
   1760     trimAgainstROI(ctx, fbRect);
   1761     return fbRect;
   1762 }
   1763 
   1764 bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
   1765         hwc_display_contents_1_t* list) {
   1766 
   1767     //Capability checks
   1768     if(!resourceCheck(ctx, list)) {
   1769         ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
   1770         return false;
   1771     }
   1772 
   1773     //Limitations checks
   1774     if(!hwLimitationsCheck(ctx, list)) {
   1775         ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
   1776         return false;
   1777     }
   1778 
   1779     //Configure framebuffer first if applicable
   1780     if(mCurrentFrame.fbZ >= 0) {
   1781         hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
   1782         if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
   1783         {
   1784             ALOGD_IF(isDebug(), "%s configure framebuffer failed",
   1785                     __FUNCTION__);
   1786             return false;
   1787         }
   1788     }
   1789 
   1790     mCurrentFrame.map();
   1791 
   1792     if(!allocLayerPipes(ctx, list)) {
   1793         ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
   1794         return false;
   1795     }
   1796 
   1797     for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   1798             index++) {
   1799         if(!mCurrentFrame.isFBComposed[index]) {
   1800             int mdpIndex = mCurrentFrame.layerToMDP[index];
   1801             hwc_layer_1_t* layer = &list->hwLayers[index];
   1802 
   1803             //Leave fbZ for framebuffer. CACHE/GLES layers go here.
   1804             if(mdpNextZOrder == mCurrentFrame.fbZ) {
   1805                 mdpNextZOrder++;
   1806             }
   1807             MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   1808             cur_pipe->zOrder = mdpNextZOrder++;
   1809 
   1810             private_handle_t *hnd = (private_handle_t *)layer->handle;
   1811             if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
   1812                 if(configure4k2kYuv(ctx, layer,
   1813                             mCurrentFrame.mdpToLayer[mdpIndex])
   1814                         != 0 ){
   1815                     ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
   1816                             for layer %d",__FUNCTION__, index);
   1817                     return false;
   1818                 }
   1819                 else{
   1820                     mdpNextZOrder++;
   1821                 }
   1822                 continue;
   1823             }
   1824             if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
   1825                 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
   1826                         layer %d",__FUNCTION__, index);
   1827                 return false;
   1828             }
   1829         }
   1830     }
   1831 
   1832     if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
   1833         ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
   1834                 ,__FUNCTION__, mDpy);
   1835         return false;
   1836     }
   1837 
   1838     setRedraw(ctx, list);
   1839     return true;
   1840 }
   1841 
   1842 bool MDPComp::resourceCheck(hwc_context_t* ctx,
   1843         hwc_display_contents_1_t* list) {
   1844     const bool fbUsed = mCurrentFrame.fbCount;
   1845     if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
   1846         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
   1847         return false;
   1848     }
   1849     // Init rotCount to number of rotate sessions used by other displays
   1850     int rotCount = ctx->mRotMgr->getNumActiveSessions();
   1851     // Count the number of rotator sessions required for current display
   1852     for (int index = 0; index < mCurrentFrame.layerCount; index++) {
   1853         if(!mCurrentFrame.isFBComposed[index]) {
   1854             hwc_layer_1_t* layer = &list->hwLayers[index];
   1855             private_handle_t *hnd = (private_handle_t *)layer->handle;
   1856             if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
   1857                 rotCount++;
   1858             }
   1859         }
   1860     }
   1861     // if number of layers to rotate exceeds max rotator sessions, bail out.
   1862     if(rotCount > RotMgr::MAX_ROT_SESS) {
   1863         ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions  %d",
   1864                                     __FUNCTION__, mDpy);
   1865         return false;
   1866     }
   1867     return true;
   1868 }
   1869 
   1870 bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
   1871         hwc_display_contents_1_t* list) {
   1872 
   1873     //A-family hw limitation:
   1874     //If a layer need alpha scaling, MDP can not support.
   1875     if(ctx->mMDP.version < qdutils::MDSS_V5) {
   1876         for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
   1877             if(!mCurrentFrame.isFBComposed[i] &&
   1878                     isAlphaScaled( &list->hwLayers[i])) {
   1879                 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
   1880                 return false;
   1881             }
   1882         }
   1883     }
   1884 
   1885     // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
   1886     //If multiple layers requires downscaling and also they are overlapping
   1887     //fall back to GPU since MDSS can not handle it.
   1888     if(qdutils::MDPVersion::getInstance().is8x74v2() ||
   1889             qdutils::MDPVersion::getInstance().is8x26()) {
   1890         for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
   1891             hwc_layer_1_t* botLayer = &list->hwLayers[i];
   1892             if(!mCurrentFrame.isFBComposed[i] &&
   1893                     isDownscaleRequired(botLayer)) {
   1894                 //if layer-i is marked for MDP and needs downscaling
   1895                 //check if any MDP layer on top of i & overlaps with layer-i
   1896                 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
   1897                     hwc_layer_1_t* topLayer = &list->hwLayers[j];
   1898                     if(!mCurrentFrame.isFBComposed[j] &&
   1899                             isDownscaleRequired(topLayer)) {
   1900                         hwc_rect_t r = getIntersection(botLayer->displayFrame,
   1901                                 topLayer->displayFrame);
   1902                         if(isValidRect(r))
   1903                             return false;
   1904                     }
   1905                 }
   1906             }
   1907         }
   1908     }
   1909     return true;
   1910 }
   1911 
   1912 void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1913     //For primary display, set the dynamic refreshrate
   1914     if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
   1915                                         ctx->mUseMetaDataRefreshRate) {
   1916         FrameInfo frame;
   1917         frame.reset(mCurrentFrame.layerCount);
   1918         memset(&frame.drop, 0, sizeof(frame.drop));
   1919         frame.dropCount = 0;
   1920         ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
   1921                  __FUNCTION__);
   1922         updateLayerCache(ctx, list, frame);
   1923         updateYUV(ctx, list, false /*secure only*/, frame);
   1924         uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
   1925         MDPVersion& mdpHw = MDPVersion::getInstance();
   1926         if(sIdleFallBack) {
   1927             //Set minimum panel refresh rate during idle timeout
   1928             refreshRate = mdpHw.getMinFpsSupported();
   1929         } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
   1930                                 (frame.layerCount == 1)) {
   1931             //Set the new fresh rate, if there is only one updating YUV layer
   1932             //or there is one single RGB layer with this request
   1933             refreshRate = ctx->listStats[mDpy].refreshRateRequest;
   1934         }
   1935         setRefreshRate(ctx, mDpy, refreshRate);
   1936     }
   1937 }
   1938 
   1939 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   1940     int ret = 0;
   1941     char property[PROPERTY_VALUE_MAX];
   1942 
   1943     if(!ctx || !list) {
   1944         ALOGE("%s: Invalid context or list",__FUNCTION__);
   1945         mCachedFrame.reset();
   1946         return -1;
   1947     }
   1948 
   1949     const int numLayers = ctx->listStats[mDpy].numAppLayers;
   1950     if(mDpy == HWC_DISPLAY_PRIMARY) {
   1951         sSimulationFlags = 0;
   1952         if(property_get("debug.hwc.simulate", property, NULL) > 0) {
   1953             int currentFlags = atoi(property);
   1954             if(currentFlags != sSimulationFlags) {
   1955                 sSimulationFlags = currentFlags;
   1956                 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
   1957                         sSimulationFlags, sSimulationFlags);
   1958             }
   1959         }
   1960     }
   1961     // reset PTOR
   1962     if(!mDpy)
   1963         memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
   1964 
   1965     //reset old data
   1966     mCurrentFrame.reset(numLayers);
   1967     memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   1968     mCurrentFrame.dropCount = 0;
   1969 
   1970     //Do not cache the information for next draw cycle.
   1971     if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
   1972         ALOGI("%s: Unsupported layer count for mdp composition",
   1973                 __FUNCTION__);
   1974         mCachedFrame.reset();
   1975 #ifdef DYNAMIC_FPS
   1976         // Reset refresh rate
   1977         setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
   1978 #endif
   1979         return -1;
   1980     }
   1981 
   1982     // Detect the start of animation and fall back to GPU only once to cache
   1983     // all the layers in FB and display FB content untill animation completes.
   1984     if(ctx->listStats[mDpy].isDisplayAnimating) {
   1985         mCurrentFrame.needsRedraw = false;
   1986         if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
   1987             mCurrentFrame.needsRedraw = true;
   1988             ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
   1989         }
   1990         setMDPCompLayerFlags(ctx, list);
   1991         mCachedFrame.updateCounts(mCurrentFrame);
   1992 #ifdef DYNAMIC_FPS
   1993         // Reset refresh rate
   1994         setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
   1995 #endif
   1996         ret = -1;
   1997         return ret;
   1998     } else {
   1999         ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
   2000     }
   2001 
   2002     if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
   2003        mCachedFrame.isSameFrame(ctx,mDpy,list)) {
   2004 
   2005         ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
   2006         mCurrentFrame.needsRedraw = false;
   2007         setMDPCompLayerFlags(ctx, list);
   2008         mCachedFrame.updateCounts(mCurrentFrame);
   2009         return -1;
   2010 
   2011     }
   2012 
   2013     //Hard conditions, if not met, cannot do MDP comp
   2014     if(isFrameDoable(ctx)) {
   2015         generateROI(ctx, list);
   2016         // if AIV Video mode is enabled, drop all non AIV layers from the
   2017         // external display list.
   2018         if(ctx->listStats[mDpy].mAIVVideoMode) {
   2019             dropNonAIVLayers(ctx, list);
   2020         }
   2021 
   2022         // if tryFullFrame fails, try to push all video and secure RGB layers
   2023         // to MDP for composition.
   2024         mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
   2025                   tryVideoOnly(ctx, list);
   2026         if(mModeOn) {
   2027             setMDPCompLayerFlags(ctx, list);
   2028         } else {
   2029             resetROI(ctx, mDpy);
   2030             reset(ctx);
   2031             memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
   2032             mCurrentFrame.dropCount = 0;
   2033             ret = -1;
   2034             ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
   2035                     "MDP Composition Strategies Failed");
   2036         }
   2037     } else {
   2038         if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
   2039                 enablePartialUpdateForMDP3) {
   2040             generateROI(ctx, list);
   2041             for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
   2042                 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
   2043             }
   2044         }
   2045         ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
   2046                 __FUNCTION__);
   2047         ret = -1;
   2048     }
   2049 
   2050     if(isDebug()) {
   2051         ALOGD("GEOMETRY change: %d",
   2052                 (list->flags & HWC_GEOMETRY_CHANGED));
   2053         android::String8 sDump("");
   2054         dump(sDump, ctx);
   2055         ALOGD("%s",sDump.string());
   2056     }
   2057 
   2058 #ifdef DYNAMIC_FPS
   2059     setDynRefreshRate(ctx, list);
   2060 #endif
   2061 
   2062     mCachedFrame.updateCounts(mCurrentFrame);
   2063     return ret;
   2064 }
   2065 
   2066 bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
   2067 
   2068     bool bRet = true;
   2069     int mdpIndex = mCurrentFrame.layerToMDP[index];
   2070     PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   2071     info.pipeInfo = new MdpYUVPipeInfo;
   2072     info.rot = NULL;
   2073     MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
   2074 
   2075     pipe_info.lIndex = ovutils::OV_INVALID;
   2076     pipe_info.rIndex = ovutils::OV_INVALID;
   2077 
   2078     Overlay::PipeSpecs pipeSpecs;
   2079     pipeSpecs.formatClass = Overlay::FORMAT_YUV;
   2080     pipeSpecs.needsScaling = true;
   2081     pipeSpecs.dpy = mDpy;
   2082     pipeSpecs.fb = false;
   2083 
   2084     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2085     if(pipe_info.lIndex == ovutils::OV_INVALID){
   2086         bRet = false;
   2087         ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
   2088                 __FUNCTION__);
   2089     }
   2090     pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2091     if(pipe_info.rIndex == ovutils::OV_INVALID){
   2092         bRet = false;
   2093         ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
   2094                 __FUNCTION__);
   2095     }
   2096     return bRet;
   2097 }
   2098 
   2099 int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   2100     int fd = -1;
   2101     if (ctx->mPtorInfo.isActive()) {
   2102         fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
   2103         if (fd < 0) {
   2104             ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
   2105         }
   2106     }
   2107     return fd;
   2108 }
   2109 //=============MDPCompNonSplit==================================================
   2110 
   2111 void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
   2112         hwc_display_contents_1_t* list) {
   2113     //If 4k2k Yuv layer split is possible,  and if
   2114     //fbz is above 4k2k layer, increment fb zorder by 1
   2115     //as we split 4k2k layer and increment zorder for right half
   2116     //of the layer
   2117     if(!ctx)
   2118         return;
   2119     if(mCurrentFrame.fbZ >= 0) {
   2120         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   2121                 index++) {
   2122             if(!mCurrentFrame.isFBComposed[index]) {
   2123                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   2124                     mdpNextZOrder++;
   2125                 }
   2126                 mdpNextZOrder++;
   2127                 hwc_layer_1_t* layer = &list->hwLayers[index];
   2128                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   2129                 if(isYUVSplitNeeded(hnd)) {
   2130                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   2131                         mCurrentFrame.fbZ += 1;
   2132                     mdpNextZOrder++;
   2133                     //As we split 4kx2k yuv layer and program to 2 VG pipes
   2134                     //(if available) increase mdpcount by 1.
   2135                     mCurrentFrame.mdpCount++;
   2136                 }
   2137             }
   2138         }
   2139     }
   2140 }
   2141 
   2142 /*
   2143  * Configures pipe(s) for MDP composition
   2144  */
   2145 int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2146                              PipeLayerPair& PipeLayerPair) {
   2147     MdpPipeInfoNonSplit& mdp_info =
   2148         *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
   2149     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   2150     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   2151     eDest dest = mdp_info.index;
   2152 
   2153     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
   2154              __FUNCTION__, layer, zOrder, dest);
   2155 
   2156     return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
   2157                            &PipeLayerPair.rot);
   2158 }
   2159 
   2160 bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
   2161         hwc_display_contents_1_t* list) {
   2162     for(int index = 0; index < mCurrentFrame.layerCount; index++) {
   2163 
   2164         if(mCurrentFrame.isFBComposed[index]) continue;
   2165 
   2166         hwc_layer_1_t* layer = &list->hwLayers[index];
   2167         private_handle_t *hnd = (private_handle_t *)layer->handle;
   2168         if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
   2169             if(allocSplitVGPipesfor4k2k(ctx, index)){
   2170                 continue;
   2171             }
   2172         }
   2173 
   2174         int mdpIndex = mCurrentFrame.layerToMDP[index];
   2175         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   2176         info.pipeInfo = new MdpPipeInfoNonSplit;
   2177         info.rot = NULL;
   2178         MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
   2179 
   2180         Overlay::PipeSpecs pipeSpecs;
   2181         pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   2182                 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   2183         pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
   2184                 (qdutils::MDPVersion::getInstance().is8x26() and
   2185                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
   2186         pipeSpecs.dpy = mDpy;
   2187         pipeSpecs.fb = false;
   2188         pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
   2189 
   2190         pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
   2191 
   2192         if(pipe_info.index == ovutils::OV_INVALID) {
   2193             ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
   2194             return false;
   2195         }
   2196     }
   2197     return true;
   2198 }
   2199 
   2200 int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2201         PipeLayerPair& PipeLayerPair) {
   2202     MdpYUVPipeInfo& mdp_info =
   2203             *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   2204     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   2205     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   2206     eDest lDest = mdp_info.lIndex;
   2207     eDest rDest = mdp_info.rIndex;
   2208 
   2209     return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
   2210             lDest, rDest, &PipeLayerPair.rot);
   2211 }
   2212 
   2213 bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   2214 
   2215     if(!isEnabled() or !mModeOn) {
   2216         ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
   2217         return true;
   2218     }
   2219 
   2220     overlay::Overlay& ov = *ctx->mOverlay;
   2221     LayerProp *layerProp = ctx->layerProp[mDpy];
   2222 
   2223     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   2224     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   2225     {
   2226         if(mCurrentFrame.isFBComposed[i]) continue;
   2227 
   2228         hwc_layer_1_t *layer = &list->hwLayers[i];
   2229         private_handle_t *hnd = (private_handle_t *)layer->handle;
   2230         if(!hnd) {
   2231             if (!(layer->flags & HWC_COLOR_FILL)) {
   2232                 ALOGE("%s handle null", __FUNCTION__);
   2233                 return false;
   2234             }
   2235             // No PLAY for Color layer
   2236             layerProp[i].mFlags &= ~HWC_MDPCOMP;
   2237             continue;
   2238         }
   2239 
   2240         int mdpIndex = mCurrentFrame.layerToMDP[i];
   2241 
   2242         if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
   2243         {
   2244             MdpYUVPipeInfo& pipe_info =
   2245                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   2246             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   2247             ovutils::eDest indexL = pipe_info.lIndex;
   2248             ovutils::eDest indexR = pipe_info.rIndex;
   2249             int fd = hnd->fd;
   2250             uint32_t offset = (uint32_t)hnd->offset;
   2251             if(rot) {
   2252                 rot->queueBuffer(fd, offset);
   2253                 fd = rot->getDstMemId();
   2254                 offset = rot->getDstOffset();
   2255             }
   2256             if(indexL != ovutils::OV_INVALID) {
   2257                 ovutils::eDest destL = (ovutils::eDest)indexL;
   2258                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2259                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   2260                 if (!ov.queueBuffer(fd, offset, destL)) {
   2261                     ALOGE("%s: queueBuffer failed for display:%d",
   2262                             __FUNCTION__, mDpy);
   2263                     return false;
   2264                 }
   2265             }
   2266 
   2267             if(indexR != ovutils::OV_INVALID) {
   2268                 ovutils::eDest destR = (ovutils::eDest)indexR;
   2269                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2270                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   2271                 if (!ov.queueBuffer(fd, offset, destR)) {
   2272                     ALOGE("%s: queueBuffer failed for display:%d",
   2273                             __FUNCTION__, mDpy);
   2274                     return false;
   2275                 }
   2276             }
   2277         }
   2278         else{
   2279             MdpPipeInfoNonSplit& pipe_info =
   2280             *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   2281             ovutils::eDest dest = pipe_info.index;
   2282             if(dest == ovutils::OV_INVALID) {
   2283                 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
   2284                 return false;
   2285             }
   2286 
   2287             if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   2288                 continue;
   2289             }
   2290 
   2291             int fd = hnd->fd;
   2292             uint32_t offset = (uint32_t)hnd->offset;
   2293             int index = ctx->mPtorInfo.getPTORArrayIndex(i);
   2294             if (!mDpy && (index != -1)) {
   2295                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
   2296                 fd = hnd->fd;
   2297                 offset = 0;
   2298             }
   2299 
   2300             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2301                     using  pipe: %d", __FUNCTION__, layer,
   2302                     hnd, dest );
   2303 
   2304             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   2305             if(rot) {
   2306                 if(!rot->queueBuffer(fd, offset))
   2307                     return false;
   2308                 fd = rot->getDstMemId();
   2309                 offset = rot->getDstOffset();
   2310             }
   2311 
   2312             if (!ov.queueBuffer(fd, offset, dest)) {
   2313                 ALOGE("%s: queueBuffer failed for display:%d ",
   2314                         __FUNCTION__, mDpy);
   2315                 return false;
   2316             }
   2317         }
   2318 
   2319         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   2320     }
   2321     return true;
   2322 }
   2323 
   2324 //=============MDPCompSplit===================================================
   2325 
   2326 void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
   2327          hwc_display_contents_1_t* list){
   2328     //if 4kx2k yuv layer is totally present in either in left half
   2329     //or right half then try splitting the yuv layer to avoid decimation
   2330     const int lSplit = getLeftSplit(ctx, mDpy);
   2331     if(mCurrentFrame.fbZ >= 0) {
   2332         for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
   2333                 index++) {
   2334             if(!mCurrentFrame.isFBComposed[index]) {
   2335                 if(mdpNextZOrder == mCurrentFrame.fbZ) {
   2336                     mdpNextZOrder++;
   2337                 }
   2338                 mdpNextZOrder++;
   2339                 hwc_layer_1_t* layer = &list->hwLayers[index];
   2340                 private_handle_t *hnd = (private_handle_t *)layer->handle;
   2341                 if(isYUVSplitNeeded(hnd)) {
   2342                     hwc_rect_t dst = layer->displayFrame;
   2343                     if((dst.left > lSplit) || (dst.right < lSplit)) {
   2344                         mCurrentFrame.mdpCount += 1;
   2345                     }
   2346                     if(mdpNextZOrder <= mCurrentFrame.fbZ)
   2347                         mCurrentFrame.fbZ += 1;
   2348                     mdpNextZOrder++;
   2349                 }
   2350             }
   2351         }
   2352     }
   2353 }
   2354 
   2355 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   2356         MdpPipeInfoSplit& pipe_info) {
   2357 
   2358     const int lSplit = getLeftSplit(ctx, mDpy);
   2359     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2360     hwc_rect_t dst = layer->displayFrame;
   2361     pipe_info.lIndex = ovutils::OV_INVALID;
   2362     pipe_info.rIndex = ovutils::OV_INVALID;
   2363 
   2364     Overlay::PipeSpecs pipeSpecs;
   2365     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   2366             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   2367     pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
   2368     pipeSpecs.dpy = mDpy;
   2369     pipeSpecs.mixer = Overlay::MIXER_LEFT;
   2370     pipeSpecs.fb = false;
   2371 
   2372     // Acquire pipe only for the updating half
   2373     hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
   2374     hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
   2375 
   2376     if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
   2377         pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2378         if(pipe_info.lIndex == ovutils::OV_INVALID)
   2379             return false;
   2380     }
   2381 
   2382     if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
   2383         pipeSpecs.mixer = Overlay::MIXER_RIGHT;
   2384         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2385         if(pipe_info.rIndex == ovutils::OV_INVALID)
   2386             return false;
   2387     }
   2388 
   2389     return true;
   2390 }
   2391 
   2392 bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
   2393         hwc_display_contents_1_t* list) {
   2394     for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
   2395 
   2396         if(mCurrentFrame.isFBComposed[index]) continue;
   2397 
   2398         hwc_layer_1_t* layer = &list->hwLayers[index];
   2399         private_handle_t *hnd = (private_handle_t *)layer->handle;
   2400         hwc_rect_t dst = layer->displayFrame;
   2401         const int lSplit = getLeftSplit(ctx, mDpy);
   2402         if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
   2403             if((dst.left > lSplit)||(dst.right < lSplit)){
   2404                 if(allocSplitVGPipesfor4k2k(ctx, index)){
   2405                     continue;
   2406                 }
   2407             }
   2408         }
   2409         int mdpIndex = mCurrentFrame.layerToMDP[index];
   2410         PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
   2411         info.pipeInfo = new MdpPipeInfoSplit;
   2412         info.rot = NULL;
   2413         MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
   2414 
   2415         if(!acquireMDPPipes(ctx, layer, pipe_info)) {
   2416             ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
   2417                     __FUNCTION__);
   2418             return false;
   2419         }
   2420     }
   2421     return true;
   2422 }
   2423 
   2424 int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2425         PipeLayerPair& PipeLayerPair) {
   2426     const int lSplit = getLeftSplit(ctx, mDpy);
   2427     hwc_rect_t dst = layer->displayFrame;
   2428     if((dst.left > lSplit)||(dst.right < lSplit)){
   2429         MdpYUVPipeInfo& mdp_info =
   2430                 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
   2431         eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   2432         eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   2433         eDest lDest = mdp_info.lIndex;
   2434         eDest rDest = mdp_info.rIndex;
   2435 
   2436         return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
   2437                 lDest, rDest, &PipeLayerPair.rot);
   2438     }
   2439     else{
   2440         return configure(ctx, layer, PipeLayerPair);
   2441     }
   2442 }
   2443 
   2444 /*
   2445  * Configures pipe(s) for MDP composition
   2446  */
   2447 int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2448         PipeLayerPair& PipeLayerPair) {
   2449     MdpPipeInfoSplit& mdp_info =
   2450         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   2451     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
   2452     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
   2453     eDest lDest = mdp_info.lIndex;
   2454     eDest rDest = mdp_info.rIndex;
   2455 
   2456     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   2457              "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
   2458 
   2459     return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
   2460                             rDest, &PipeLayerPair.rot);
   2461 }
   2462 
   2463 bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
   2464 
   2465     if(!isEnabled() or !mModeOn) {
   2466         ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
   2467         return true;
   2468     }
   2469 
   2470     overlay::Overlay& ov = *ctx->mOverlay;
   2471     LayerProp *layerProp = ctx->layerProp[mDpy];
   2472 
   2473     int numHwLayers = ctx->listStats[mDpy].numAppLayers;
   2474     for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
   2475     {
   2476         if(mCurrentFrame.isFBComposed[i]) continue;
   2477 
   2478         hwc_layer_1_t *layer = &list->hwLayers[i];
   2479         private_handle_t *hnd = (private_handle_t *)layer->handle;
   2480         if(!hnd) {
   2481             ALOGE("%s handle null", __FUNCTION__);
   2482             return false;
   2483         }
   2484 
   2485         if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
   2486             continue;
   2487         }
   2488 
   2489         int mdpIndex = mCurrentFrame.layerToMDP[i];
   2490 
   2491         if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
   2492         {
   2493             MdpYUVPipeInfo& pipe_info =
   2494                 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   2495             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   2496             ovutils::eDest indexL = pipe_info.lIndex;
   2497             ovutils::eDest indexR = pipe_info.rIndex;
   2498             int fd = hnd->fd;
   2499             uint32_t offset = (uint32_t)hnd->offset;
   2500             if(rot) {
   2501                 rot->queueBuffer(fd, offset);
   2502                 fd = rot->getDstMemId();
   2503                 offset = rot->getDstOffset();
   2504             }
   2505             if(indexL != ovutils::OV_INVALID) {
   2506                 ovutils::eDest destL = (ovutils::eDest)indexL;
   2507                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2508                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   2509                 if (!ov.queueBuffer(fd, offset, destL)) {
   2510                     ALOGE("%s: queueBuffer failed for display:%d",
   2511                             __FUNCTION__, mDpy);
   2512                     return false;
   2513                 }
   2514             }
   2515 
   2516             if(indexR != ovutils::OV_INVALID) {
   2517                 ovutils::eDest destR = (ovutils::eDest)indexR;
   2518                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2519                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   2520                 if (!ov.queueBuffer(fd, offset, destR)) {
   2521                     ALOGE("%s: queueBuffer failed for display:%d",
   2522                             __FUNCTION__, mDpy);
   2523                     return false;
   2524                 }
   2525             }
   2526         }
   2527         else{
   2528             MdpPipeInfoSplit& pipe_info =
   2529                 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
   2530             Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
   2531 
   2532             ovutils::eDest indexL = pipe_info.lIndex;
   2533             ovutils::eDest indexR = pipe_info.rIndex;
   2534 
   2535             int fd = hnd->fd;
   2536             uint32_t offset = (uint32_t)hnd->offset;
   2537             int index = ctx->mPtorInfo.getPTORArrayIndex(i);
   2538             if (!mDpy && (index != -1)) {
   2539                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
   2540                 fd = hnd->fd;
   2541                 offset = 0;
   2542             }
   2543 
   2544             if(ctx->mAD->draw(ctx, fd, offset)) {
   2545                 fd = ctx->mAD->getDstFd();
   2546                 offset = ctx->mAD->getDstOffset();
   2547             }
   2548 
   2549             if(rot) {
   2550                 rot->queueBuffer(fd, offset);
   2551                 fd = rot->getDstMemId();
   2552                 offset = rot->getDstOffset();
   2553             }
   2554 
   2555             //************* play left mixer **********
   2556             if(indexL != ovutils::OV_INVALID) {
   2557                 ovutils::eDest destL = (ovutils::eDest)indexL;
   2558                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2559                         using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
   2560                 if (!ov.queueBuffer(fd, offset, destL)) {
   2561                     ALOGE("%s: queueBuffer failed for left mixer",
   2562                             __FUNCTION__);
   2563                     return false;
   2564                 }
   2565             }
   2566 
   2567             //************* play right mixer **********
   2568             if(indexR != ovutils::OV_INVALID) {
   2569                 ovutils::eDest destR = (ovutils::eDest)indexR;
   2570                 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
   2571                         using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
   2572                 if (!ov.queueBuffer(fd, offset, destR)) {
   2573                     ALOGE("%s: queueBuffer failed for right mixer",
   2574                             __FUNCTION__);
   2575                     return false;
   2576                 }
   2577             }
   2578         }
   2579 
   2580         layerProp[i].mFlags &= ~HWC_MDPCOMP;
   2581     }
   2582 
   2583     return true;
   2584 }
   2585 
   2586 //================MDPCompSrcSplit==============================================
   2587 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
   2588         MdpPipeInfoSplit& pipe_info) {
   2589     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2590     hwc_rect_t dst = layer->displayFrame;
   2591     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2592     pipe_info.lIndex = ovutils::OV_INVALID;
   2593     pipe_info.rIndex = ovutils::OV_INVALID;
   2594 
   2595     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
   2596     //should have a higher priority than the right one. Pipe priorities are
   2597     //starting with VG0, VG1 ... , RGB0 ..., DMA1
   2598 
   2599     Overlay::PipeSpecs pipeSpecs;
   2600     pipeSpecs.formatClass = isYuvBuffer(hnd) ?
   2601             Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
   2602     pipeSpecs.needsScaling = qhwc::needsScaling(layer);
   2603     pipeSpecs.dpy = mDpy;
   2604     pipeSpecs.fb = false;
   2605 
   2606     //1 pipe by default for a layer
   2607     pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2608     if(pipe_info.lIndex == ovutils::OV_INVALID) {
   2609         return false;
   2610     }
   2611 
   2612     /* Use 2 pipes IF
   2613         a) Layer's crop width is > 2048 or
   2614         b) Layer's dest width > 2048 or
   2615         c) On primary, driver has indicated with caps to split always. This is
   2616            based on an empirically derived value of panel height. Applied only
   2617            if the layer's width is > mixer's width
   2618     */
   2619 
   2620     MDPVersion& mdpHw = MDPVersion::getInstance();
   2621     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
   2622             mdpHw.isSrcSplitAlways();
   2623     int lSplit = getLeftSplit(ctx, mDpy);
   2624     int dstWidth = dst.right - dst.left;
   2625     int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
   2626             crop.right - crop.left;
   2627 
   2628     //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
   2629     //pipe line length, we are still using 2 pipes. This is fine just because
   2630     //this is source split where destination doesn't matter. Evaluate later to
   2631     //see if going through all the calcs to save a pipe is worth it
   2632     if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
   2633             cropWidth > (int) mdpHw.getMaxMixerWidth() or
   2634             (primarySplitAlways and (cropWidth > lSplit))) {
   2635         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
   2636         if(pipe_info.rIndex == ovutils::OV_INVALID) {
   2637             return false;
   2638         }
   2639 
   2640         // Return values
   2641         // 1  Left pipe is higher priority, do nothing.
   2642         // 0  Pipes of same priority.
   2643         //-1  Right pipe is of higher priority, needs swap.
   2644         if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
   2645                 pipe_info.rIndex) == -1) {
   2646             qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
   2647         }
   2648     }
   2649 
   2650     return true;
   2651 }
   2652 
   2653 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
   2654         PipeLayerPair& PipeLayerPair) {
   2655     private_handle_t *hnd = (private_handle_t *)layer->handle;
   2656     if(!hnd) {
   2657         ALOGE("%s: layer handle is NULL", __FUNCTION__);
   2658         return -1;
   2659     }
   2660     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
   2661     MdpPipeInfoSplit& mdp_info =
   2662         *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
   2663     Rotator **rot = &PipeLayerPair.rot;
   2664     eZorder z = static_cast<eZorder>(mdp_info.zOrder);
   2665     eDest lDest = mdp_info.lIndex;
   2666     eDest rDest = mdp_info.rIndex;
   2667     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
   2668     hwc_rect_t dst = layer->displayFrame;
   2669     int transform = layer->transform;
   2670     eTransform orient = static_cast<eTransform>(transform);
   2671     int rotFlags = ROT_FLAGS_NONE;
   2672     uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
   2673     Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
   2674 
   2675     ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
   2676              "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
   2677 
   2678     // Handle R/B swap
   2679     if (layer->flags & HWC_FORMAT_RB_SWAP) {
   2680         if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
   2681             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
   2682         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
   2683             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
   2684     }
   2685     // update source crop and destination position of AIV video layer.
   2686     if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
   2687         updateCoordinates(ctx, crop, dst, mDpy);
   2688     }
   2689     /* Calculate the external display position based on MDP downscale,
   2690        ActionSafe, and extorientation features. */
   2691     calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
   2692 
   2693     int downscale = getRotDownscale(ctx, layer);
   2694     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
   2695     setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
   2696 
   2697     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2698         //Enable overfetch
   2699         setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
   2700     }
   2701 
   2702     if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
   2703         (*rot) = ctx->mRotMgr->getNext();
   2704         if((*rot) == NULL) return -1;
   2705         ctx->mLayerRotMap[mDpy]->add(layer, *rot);
   2706         //If the video is using a single pipe, enable BWC
   2707         if(rDest == OV_INVALID) {
   2708             BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
   2709         }
   2710         //Configure rotator for pre-rotation
   2711         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
   2712             ALOGE("%s: configRotator failed!", __FUNCTION__);
   2713             return -1;
   2714         }
   2715         updateSource(orient, whf, crop, *rot);
   2716         rotFlags |= ovutils::ROT_PREROTATED;
   2717     }
   2718 
   2719     //If 2 pipes being used, divide layer into half, crop and dst
   2720     hwc_rect_t cropL = crop;
   2721     hwc_rect_t cropR = crop;
   2722     hwc_rect_t dstL = dst;
   2723     hwc_rect_t dstR = dst;
   2724     if(lDest != OV_INVALID && rDest != OV_INVALID) {
   2725         cropL.right = (crop.right + crop.left) / 2;
   2726         cropR.left = cropL.right;
   2727         sanitizeSourceCrop(cropL, cropR, hnd);
   2728 
   2729         bool cropSwap = false;
   2730         //Swap crops on H flip since 2 pipes are being used
   2731         if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
   2732             hwc_rect_t tmp = cropL;
   2733             cropL = cropR;
   2734             cropR = tmp;
   2735             cropSwap = true;
   2736         }
   2737 
   2738         //cropSwap trick: If the src and dst widths are both odd, let us say
   2739         //2507, then splitting both into half would cause left width to be 1253
   2740         //and right 1254. If crop is swapped because of H flip, this will cause
   2741         //left crop width to be 1254, whereas left dst width remains 1253, thus
   2742         //inducing a scaling that is unaccounted for. To overcome that we add 1
   2743         //to the dst width if there is a cropSwap. So if the original width was
   2744         //2507, the left dst width will be 1254. Even if the original width was
   2745         //even for ex: 2508, the left dst width will still remain 1254.
   2746         dstL.right = (dst.right + dst.left + cropSwap) / 2;
   2747         dstR.left = dstL.right;
   2748     }
   2749 
   2750     //For the mdp, since either we are pre-rotating or MDP does flips
   2751     orient = OVERLAY_TRANSFORM_0;
   2752     transform = 0;
   2753 
   2754     //configure left pipe
   2755     if(lDest != OV_INVALID) {
   2756         PipeArgs pargL(mdpFlags, whf, z,
   2757                 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
   2758                 (ovutils::eBlending) getBlending(layer->blending));
   2759 
   2760         if(configMdp(ctx->mOverlay, pargL, orient,
   2761                     cropL, dstL, metadata, lDest) < 0) {
   2762             ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
   2763             return -1;
   2764         }
   2765     }
   2766 
   2767     //configure right pipe
   2768     if(rDest != OV_INVALID) {
   2769         PipeArgs pargR(mdpFlags, whf, z,
   2770                 static_cast<eRotFlags>(rotFlags),
   2771                 layer->planeAlpha,
   2772                 (ovutils::eBlending) getBlending(layer->blending));
   2773         if(configMdp(ctx->mOverlay, pargR, orient,
   2774                     cropR, dstR, metadata, rDest) < 0) {
   2775             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
   2776             return -1;
   2777         }
   2778     }
   2779 
   2780     return 0;
   2781 }
   2782 
   2783 int MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
   2784     Locker::Autolock _l(ctx->mDrawLock);
   2785     const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
   2786     char path[MAX_SYSFS_FILE_PATH];
   2787     snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
   2788     int fd = open(path, O_RDONLY);
   2789     if(fd < 0) {
   2790         ALOGE("%s: Failed to open sysfs node: %s", __FUNCTION__, path);
   2791         return -1;
   2792     }
   2793     char value[4];
   2794     ssize_t size_read = read(fd, value, sizeof(value)-1);
   2795     if(size_read <= 0) {
   2796         ALOGE("%s: Failed to read sysfs node: %s", __FUNCTION__, path);
   2797         close(fd);
   2798         return -1;
   2799     }
   2800     close(fd);
   2801     value[size_read] = '\0';
   2802     return atoi(value);
   2803 }
   2804 
   2805 int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
   2806     Locker::Autolock _l(ctx->mDrawLock);
   2807     const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
   2808     char path[MAX_SYSFS_FILE_PATH];
   2809     snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
   2810     int fd = open(path, O_WRONLY);
   2811     if(fd < 0) {
   2812         ALOGE("%s: Failed to open sysfs node: %s", __FUNCTION__, path);
   2813         return -1;
   2814     }
   2815     char value[4];
   2816     snprintf(value, sizeof(value), "%d", (int)enable);
   2817     ssize_t ret = write(fd, value, strlen(value));
   2818     if(ret <= 0) {
   2819         ALOGE("%s: Failed to write to sysfs nodes: %s", __FUNCTION__, path);
   2820         close(fd);
   2821         return -1;
   2822     }
   2823     close(fd);
   2824     return 0;
   2825 }
   2826 }; //namespace
   2827 
   2828