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