Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
      4  *
      5  * Not a Contribution, Apache license notifications and license are
      6  * retained for attribution purposes only.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  */
     20 
     21 #define DEBUG_FBUPDATE 0
     22 #include <cutils/properties.h>
     23 #include <gralloc_priv.h>
     24 #include <overlay.h>
     25 #include <overlayRotator.h>
     26 #include "hwc_fbupdate.h"
     27 #include "mdp_version.h"
     28 #include "external.h"
     29 #include "virtual.h"
     30 
     31 using namespace qdutils;
     32 using namespace overlay;
     33 using overlay::Rotator;
     34 using namespace overlay::utils;
     35 
     36 namespace qhwc {
     37 
     38 namespace ovutils = overlay::utils;
     39 
     40 IFBUpdate* IFBUpdate::getObject(hwc_context_t *ctx, const int& dpy) {
     41     if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
     42         return new FBSrcSplit(ctx, dpy);
     43     } else if(isDisplaySplit(ctx, dpy)) {
     44         return new FBUpdateSplit(ctx, dpy);
     45     }
     46     return new FBUpdateNonSplit(ctx, dpy);
     47 }
     48 
     49 IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
     50     unsigned int size = 0;
     51     uint32_t xres = ctx->dpyAttr[mDpy].xres;
     52     uint32_t yres = ctx->dpyAttr[mDpy].yres;
     53     if (ctx->dpyAttr[dpy].customFBSize) {
     54         //GPU will render and compose at new resolution
     55         //So need to have FB at new resolution
     56         xres = ctx->dpyAttr[mDpy].xres_new;
     57         yres = ctx->dpyAttr[mDpy].yres_new;
     58     }
     59     getBufferAttributes((int)xres, (int)yres,
     60             HAL_PIXEL_FORMAT_RGBA_8888,
     61             0,
     62             mAlignedFBWidth,
     63             mAlignedFBHeight,
     64             mTileEnabled, size);
     65 }
     66 
     67 void IFBUpdate::reset() {
     68     mModeOn = false;
     69     mRot = NULL;
     70 }
     71 
     72 bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
     73             hwc_display_contents_1 *list, int fbZorder) {
     74     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     75     mModeOn = prepare(ctx, list, layer->displayFrame, fbZorder) &&
     76             ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
     77     return mModeOn;
     78 }
     79 
     80 //================= Low res====================================
     81 FBUpdateNonSplit::FBUpdateNonSplit(hwc_context_t *ctx, const int& dpy):
     82         IFBUpdate(ctx, dpy) {}
     83 
     84 void FBUpdateNonSplit::reset() {
     85     IFBUpdate::reset();
     86     mDest = ovutils::OV_INVALID;
     87 }
     88 
     89 bool FBUpdateNonSplit::preRotateExtDisplay(hwc_context_t *ctx,
     90                                             hwc_layer_1_t *layer,
     91                                             ovutils::Whf &info,
     92                                             hwc_rect_t& sourceCrop,
     93                                             ovutils::eMdpFlags& mdpFlags,
     94                                             int& rotFlags)
     95 {
     96     int extOrient = getExtOrientation(ctx);
     97     ovutils::eTransform orient = static_cast<ovutils::eTransform >(extOrient);
     98     if(mDpy && (extOrient & HWC_TRANSFORM_ROT_90)) {
     99         mRot = ctx->mRotMgr->getNext();
    100         if(mRot == NULL) return false;
    101         ctx->mLayerRotMap[mDpy]->add(layer, mRot);
    102         // Composed FB content will have black bars, if the viewFrame of the
    103         // external is different from {0, 0, fbWidth, fbHeight}, so intersect
    104         // viewFrame with sourceCrop to avoid those black bars
    105         sourceCrop = getIntersection(sourceCrop, ctx->mViewFrame[mDpy]);
    106         //Configure rotator for pre-rotation
    107         if(configRotator(mRot, info, sourceCrop, mdpFlags, orient, 0) < 0) {
    108             ALOGE("%s: configRotator Failed!", __FUNCTION__);
    109             mRot = NULL;
    110             return false;
    111         }
    112         updateSource(orient, info, sourceCrop, mRot);
    113         rotFlags |= ovutils::ROT_PREROTATED;
    114     }
    115     return true;
    116 }
    117 
    118 bool FBUpdateNonSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
    119                              hwc_rect_t fbUpdatingRect, int fbZorder) {
    120     if(!ctx->mMDP.hasOverlay) {
    121         ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
    122                  __FUNCTION__);
    123         return false;
    124     }
    125     mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
    126     return mModeOn;
    127 }
    128 
    129 // Configure
    130 bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
    131                                hwc_rect_t fbUpdatingRect, int fbZorder) {
    132     bool ret = false;
    133     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    134     if (LIKELY(ctx->mOverlay)) {
    135         int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
    136         // ext only layer present..
    137         if(extOnlyLayerIndex != -1) {
    138             layer = &list->hwLayers[extOnlyLayerIndex];
    139             layer->compositionType = HWC_OVERLAY;
    140         }
    141         overlay::Overlay& ov = *(ctx->mOverlay);
    142 
    143         ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
    144                 ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
    145                     mTileEnabled));
    146 
    147         Overlay::PipeSpecs pipeSpecs;
    148         pipeSpecs.formatClass = Overlay::FORMAT_RGB;
    149         pipeSpecs.needsScaling = qhwc::needsScaling(layer);
    150         pipeSpecs.dpy = mDpy;
    151         pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
    152         pipeSpecs.fb = true;
    153 
    154         ovutils::eDest dest = ov.getPipe(pipeSpecs);
    155         if(dest == ovutils::OV_INVALID) { //None available
    156             ALOGE("%s: No pipes available to configure fb for dpy %d",
    157                 __FUNCTION__, mDpy);
    158             return false;
    159         }
    160         mDest = dest;
    161 
    162         if((mDpy && ctx->deviceOrientation) &&
    163             ctx->listStats[mDpy].isDisplayAnimating) {
    164             fbZorder = 0;
    165         }
    166 
    167         ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
    168         ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
    169         ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
    170 
    171         hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    172         hwc_rect_t displayFrame = layer->displayFrame;
    173 
    174         // No FB update optimization on (1) Custom FB resolution,
    175         // (2) External Mirror mode, (3) External orientation
    176         if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
    177            && !ctx->mExtOrientation) {
    178             sourceCrop = fbUpdatingRect;
    179             displayFrame = fbUpdatingRect;
    180         }
    181 
    182         int transform = layer->transform;
    183         int rotFlags = ovutils::ROT_FLAGS_NONE;
    184 
    185         ovutils::eTransform orient =
    186                     static_cast<ovutils::eTransform>(transform);
    187         // use ext orientation if any
    188         int extOrient = getExtOrientation(ctx);
    189 
    190         // Do not use getNonWormholeRegion() function to calculate the
    191         // sourceCrop during animation on external display and
    192         // Dont do wormhole calculation when extorientation is set on External
    193         // Dont do wormhole calculation when extDownscale is enabled on External
    194         if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
    195             sourceCrop = layer->displayFrame;
    196         } else if((!mDpy ||
    197                   (mDpy && !extOrient
    198                   && !ctx->dpyAttr[mDpy].mDownScaleMode))
    199                   && (extOnlyLayerIndex == -1)) {
    200             if(ctx->mOverlay->isUIScalingOnExternalSupported() &&
    201                 !ctx->dpyAttr[mDpy].customFBSize) {
    202                 getNonWormholeRegion(list, sourceCrop);
    203                 displayFrame = sourceCrop;
    204             }
    205         }
    206         calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
    207                                    transform, orient);
    208         //Store the displayFrame, will be used in getDisplayViewFrame
    209         ctx->dpyAttr[mDpy].mDstRect = displayFrame;
    210         setMdpFlags(ctx, layer, mdpFlags, 0, transform);
    211         // For External use rotator if there is a rotation value set
    212         ret = preRotateExtDisplay(ctx, layer, info,
    213                 sourceCrop, mdpFlags, rotFlags);
    214         if(!ret) {
    215             ALOGE("%s: preRotate for external Failed!", __FUNCTION__);
    216             return false;
    217         }
    218         //For the mdp, since either we are pre-rotating or MDP does flips
    219         orient = ovutils::OVERLAY_TRANSFORM_0;
    220         transform = 0;
    221         ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
    222                                static_cast<ovutils::eRotFlags>(rotFlags),
    223                                ovutils::DEFAULT_PLANE_ALPHA,
    224                                (ovutils::eBlending)
    225                                getBlending(layer->blending));
    226         ret = true;
    227         if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
    228                     NULL, mDest) < 0) {
    229             ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
    230             ret = false;
    231         }
    232     }
    233     return ret;
    234 }
    235 
    236 bool FBUpdateNonSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
    237 {
    238     if(!mModeOn) {
    239         return true;
    240     }
    241     bool ret = true;
    242     overlay::Overlay& ov = *(ctx->mOverlay);
    243     ovutils::eDest dest = mDest;
    244     int fd = hnd->fd;
    245     uint32_t offset = (uint32_t)hnd->offset;
    246     if(mRot) {
    247         if(!mRot->queueBuffer(fd, offset))
    248             return false;
    249         fd = mRot->getDstMemId();
    250         offset = mRot->getDstOffset();
    251     }
    252     if (!ov.queueBuffer(fd, offset, dest)) {
    253         ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
    254         ret = false;
    255     }
    256     return ret;
    257 }
    258 
    259 //================= High res====================================
    260 FBUpdateSplit::FBUpdateSplit(hwc_context_t *ctx, const int& dpy):
    261         IFBUpdate(ctx, dpy) {}
    262 
    263 void FBUpdateSplit::reset() {
    264     IFBUpdate::reset();
    265     mDestLeft = ovutils::OV_INVALID;
    266     mDestRight = ovutils::OV_INVALID;
    267     mRot = NULL;
    268 }
    269 
    270 bool FBUpdateSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
    271                               hwc_rect_t fbUpdatingRect, int fbZorder) {
    272     if(!ctx->mMDP.hasOverlay) {
    273         ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
    274                  __FUNCTION__);
    275         return false;
    276     }
    277     mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
    278     ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
    279     return mModeOn;
    280 }
    281 
    282 // Configure
    283 bool FBUpdateSplit::configure(hwc_context_t *ctx,
    284         hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
    285     bool ret = false;
    286     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    287     if (LIKELY(ctx->mOverlay)) {
    288         /*  External only layer present */
    289         int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
    290         if(extOnlyLayerIndex != -1) {
    291             layer = &list->hwLayers[extOnlyLayerIndex];
    292             layer->compositionType = HWC_OVERLAY;
    293         }
    294         ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
    295                           ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
    296                                                 mTileEnabled));
    297 
    298         overlay::Overlay& ov = *(ctx->mOverlay);
    299         ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
    300         ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
    301         ovutils::eTransform orient =
    302             static_cast<ovutils::eTransform>(layer->transform);
    303         const int hw_w = ctx->dpyAttr[mDpy].xres;
    304         const int hw_h = ctx->dpyAttr[mDpy].yres;
    305         const int lSplit = getLeftSplit(ctx, mDpy);
    306         mDestLeft = ovutils::OV_INVALID;
    307         mDestRight = ovutils::OV_INVALID;
    308 
    309         hwc_rect_t sourceCrop = fbUpdatingRect;
    310         hwc_rect_t displayFrame = fbUpdatingRect;
    311 
    312         ret = true;
    313         Overlay::PipeSpecs pipeSpecs;
    314         pipeSpecs.formatClass = Overlay::FORMAT_RGB;
    315         pipeSpecs.needsScaling = qhwc::needsScaling(layer);
    316         pipeSpecs.dpy = mDpy;
    317         pipeSpecs.fb = true;
    318 
    319         /* Configure left pipe */
    320         if(displayFrame.left < lSplit) {
    321             pipeSpecs.mixer = Overlay::MIXER_LEFT;
    322             ovutils::eDest destL = ov.getPipe(pipeSpecs);
    323             if(destL == ovutils::OV_INVALID) { //None available
    324                 ALOGE("%s: No pipes available to configure fb for dpy %d's left"
    325                       " mixer", __FUNCTION__, mDpy);
    326                 return false;
    327             }
    328 
    329             mDestLeft = destL;
    330 
    331             //XXX: FB layer plane alpha is currently sent as zero from
    332             //surfaceflinger
    333             ovutils::PipeArgs pargL(mdpFlags,
    334                                     info,
    335                                     zOrder,
    336                                     ovutils::IS_FG_OFF,
    337                                     ovutils::ROT_FLAGS_NONE,
    338                                     ovutils::DEFAULT_PLANE_ALPHA,
    339                                     (ovutils::eBlending)
    340                                     getBlending(layer->blending));
    341             hwc_rect_t cropL = sourceCrop;
    342             hwc_rect_t dstL = displayFrame;
    343             hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
    344             qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
    345 
    346             if (configMdp(ctx->mOverlay, pargL, orient, cropL,
    347                            dstL, NULL, destL)< 0) {
    348                 ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
    349                 ret = false;
    350             }
    351         }
    352 
    353         /* Configure right pipe */
    354         if(displayFrame.right > lSplit) {
    355             pipeSpecs.mixer = Overlay::MIXER_RIGHT;
    356             ovutils::eDest destR = ov.getPipe(pipeSpecs);
    357             if(destR == ovutils::OV_INVALID) { //None available
    358                 ALOGE("%s: No pipes available to configure fb for dpy %d's"
    359                       " right mixer", __FUNCTION__, mDpy);
    360                 return false;
    361             }
    362 
    363             mDestRight = destR;
    364             ovutils::eMdpFlags mdpFlagsR = mdpFlags;
    365             ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
    366 
    367             //XXX: FB layer plane alpha is currently sent as zero from
    368             //surfaceflinger
    369             ovutils::PipeArgs pargR(mdpFlagsR,
    370                                     info,
    371                                     zOrder,
    372                                     ovutils::IS_FG_OFF,
    373                                     ovutils::ROT_FLAGS_NONE,
    374                                     ovutils::DEFAULT_PLANE_ALPHA,
    375                                     (ovutils::eBlending)
    376                                     getBlending(layer->blending));
    377 
    378             hwc_rect_t cropR = sourceCrop;
    379             hwc_rect_t dstR = displayFrame;
    380             hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
    381             qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
    382 
    383             dstR.left -= lSplit;
    384             dstR.right -= lSplit;
    385 
    386             if (configMdp(ctx->mOverlay, pargR, orient, cropR,
    387                            dstR, NULL, destR) < 0) {
    388                 ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
    389                 ret = false;
    390             }
    391         }
    392     }
    393     return ret;
    394 }
    395 
    396 bool FBUpdateSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
    397 {
    398     if(!mModeOn) {
    399         return true;
    400     }
    401     bool ret = true;
    402     overlay::Overlay& ov = *(ctx->mOverlay);
    403     if(mDestLeft != ovutils::OV_INVALID) {
    404         if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestLeft)) {
    405             ALOGE("%s: queue failed for left of dpy = %d",
    406                   __FUNCTION__, mDpy);
    407             ret = false;
    408         }
    409     }
    410     if(mDestRight != ovutils::OV_INVALID) {
    411         if (!ov.queueBuffer(hnd->fd, (uint32_t)hnd->offset, mDestRight)) {
    412             ALOGE("%s: queue failed for right of dpy = %d",
    413                   __FUNCTION__, mDpy);
    414             ret = false;
    415         }
    416     }
    417     return ret;
    418 }
    419 
    420 //=================FBSrcSplit====================================
    421 FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
    422         FBUpdateSplit(ctx, dpy) {}
    423 
    424 bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
    425         hwc_rect_t fbUpdatingRect, int fbZorder) {
    426     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    427     int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
    428     // ext only layer present..
    429     if(extOnlyLayerIndex != -1) {
    430         layer = &list->hwLayers[extOnlyLayerIndex];
    431         layer->compositionType = HWC_OVERLAY;
    432     }
    433 
    434     overlay::Overlay& ov = *(ctx->mOverlay);
    435 
    436     ovutils::Whf info(mAlignedFBWidth,
    437             mAlignedFBHeight,
    438             ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
    439                 mTileEnabled));
    440 
    441     ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
    442     ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
    443 
    444     ovutils::PipeArgs parg(mdpFlags,
    445             info,
    446             zOrder,
    447             ovutils::IS_FG_OFF,
    448             ovutils::ROT_FLAGS_NONE,
    449             ovutils::DEFAULT_PLANE_ALPHA,
    450             (ovutils::eBlending)
    451             getBlending(layer->blending));
    452 
    453     int transform = layer->transform;
    454     ovutils::eTransform orient =
    455             static_cast<ovutils::eTransform>(transform);
    456 
    457     hwc_rect_t cropL = fbUpdatingRect;
    458     hwc_rect_t cropR = fbUpdatingRect;
    459 
    460     //Request left pipe (or 1 by default)
    461     Overlay::PipeSpecs pipeSpecs;
    462     pipeSpecs.formatClass = Overlay::FORMAT_RGB;
    463     pipeSpecs.needsScaling = qhwc::needsScaling(layer);
    464     pipeSpecs.dpy = mDpy;
    465     pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
    466     pipeSpecs.fb = true;
    467     ovutils::eDest destL = ov.getPipe(pipeSpecs);
    468     if(destL == ovutils::OV_INVALID) {
    469         ALOGE("%s: No pipes available to configure fb for dpy %d's left"
    470                 " mixer", __FUNCTION__, mDpy);
    471         return false;
    472     }
    473 
    474     ovutils::eDest destR = ovutils::OV_INVALID;
    475 
    476     /*  Use 2 pipes IF
    477         a) FB's width is > 2048 or
    478         b) On primary, driver has indicated with caps to split always. This is
    479            based on an empirically derived value of panel height.
    480     */
    481 
    482     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
    483             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
    484 
    485     if(((fbUpdatingRect.right - fbUpdatingRect.left) >
    486             qdutils::MAX_DISPLAY_DIM) or
    487             primarySplitAlways) {
    488         destR = ov.getPipe(pipeSpecs);
    489         if(destR == ovutils::OV_INVALID) {
    490             ALOGE("%s: No pipes available to configure fb for dpy %d's right"
    491                     " mixer", __FUNCTION__, mDpy);
    492             return false;
    493         }
    494 
    495         if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
    496             qhwc::swap(destL, destR);
    497         }
    498 
    499         //Split crop equally when using 2 pipes
    500         cropL.right = (fbUpdatingRect.right + fbUpdatingRect.left) / 2;
    501         cropR.left = cropL.right;
    502     }
    503 
    504     mDestLeft = destL;
    505     mDestRight = destR;
    506 
    507     if(destL != OV_INVALID) {
    508         if(configMdp(ctx->mOverlay, parg, orient,
    509                     cropL, cropL, NULL /*metadata*/, destL) < 0) {
    510             ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
    511             return false;
    512         }
    513     }
    514 
    515     //configure right pipe
    516     if(destR != OV_INVALID) {
    517         if(configMdp(ctx->mOverlay, parg, orient,
    518                     cropR, cropR, NULL /*metadata*/, destR) < 0) {
    519             ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
    520             return false;
    521         }
    522     }
    523 
    524     return true;
    525 }
    526 
    527 //---------------------------------------------------------------------
    528 }; //namespace qhwc
    529