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