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