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(isDisplaySplit(ctx, dpy)) {
     42         if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
     43             return new FBSrcSplit(ctx, dpy);
     44         }
     45         return new FBUpdateSplit(ctx, dpy);
     46     }
     47     return new FBUpdateNonSplit(ctx, dpy);
     48 }
     49 
     50 IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
     51     size_t size = 0;
     52     getBufferAttributes(ctx->dpyAttr[mDpy].xres,
     53             ctx->dpyAttr[mDpy].yres,
     54             HAL_PIXEL_FORMAT_RGBA_8888,
     55             0,
     56             mAlignedFBWidth,
     57             mAlignedFBHeight,
     58             mTileEnabled, size);
     59 }
     60 
     61 void IFBUpdate::reset() {
     62     mModeOn = false;
     63     mRot = NULL;
     64 }
     65 
     66 bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
     67             hwc_display_contents_1 *list, int fbZorder) {
     68     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     69     return prepare(ctx, list, layer->displayFrame, fbZorder) &&
     70             ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
     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         // Composed FB content will have black bars, if the viewFrame of the
     95         // external is different from {0, 0, fbWidth, fbHeight}, so intersect
     96         // viewFrame with sourceCrop to avoid those black bars
     97         sourceCrop = getIntersection(sourceCrop, ctx->mViewFrame[mDpy]);
     98         //Configure rotator for pre-rotation
     99         if(configRotator(mRot, info, sourceCrop, mdpFlags, orient, 0) < 0) {
    100             ALOGE("%s: configRotator Failed!", __FUNCTION__);
    101             mRot = NULL;
    102             return false;
    103         }
    104         ctx->mLayerRotMap[mDpy]->add(layer, mRot);
    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         //Request a pipe
    142         ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
    143         if((qdutils::MDPVersion::getInstance().is8x26() ||
    144                    qdutils::MDPVersion::getInstance().is8x16()) && mDpy) {
    145             //For 8x26 external always use DMA pipe
    146             type = ovutils::OV_MDP_PIPE_DMA;
    147         }
    148         ovutils::eDest dest = ov.nextPipe(type, mDpy, Overlay::MIXER_DEFAULT);
    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             ctx->mOverlay->clear(mDpy);
    211             ctx->mLayerRotMap[mDpy]->clear();
    212             return false;
    213         }
    214         //For the mdp, since either we are pre-rotating or MDP does flips
    215         orient = ovutils::OVERLAY_TRANSFORM_0;
    216         transform = 0;
    217         ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
    218                                static_cast<ovutils::eRotFlags>(rotFlags),
    219                                ovutils::DEFAULT_PLANE_ALPHA,
    220                                (ovutils::eBlending)
    221                                getBlending(layer->blending));
    222         ret = true;
    223         if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
    224                     NULL, mDest) < 0) {
    225             ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
    226             ctx->mLayerRotMap[mDpy]->clear();
    227             ret = false;
    228         }
    229     }
    230     return ret;
    231 }
    232 
    233 bool FBUpdateNonSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
    234 {
    235     if(!mModeOn) {
    236         return true;
    237     }
    238     bool ret = true;
    239     overlay::Overlay& ov = *(ctx->mOverlay);
    240     ovutils::eDest dest = mDest;
    241     int fd = hnd->fd;
    242     uint32_t offset = hnd->offset;
    243     if(mRot) {
    244         if(!mRot->queueBuffer(fd, offset))
    245             return false;
    246         fd = mRot->getDstMemId();
    247         offset = mRot->getDstOffset();
    248     }
    249     if (!ov.queueBuffer(fd, offset, dest)) {
    250         ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
    251         ret = false;
    252     }
    253     return ret;
    254 }
    255 
    256 //================= High res====================================
    257 FBUpdateSplit::FBUpdateSplit(hwc_context_t *ctx, const int& dpy):
    258         IFBUpdate(ctx, dpy) {}
    259 
    260 void FBUpdateSplit::reset() {
    261     IFBUpdate::reset();
    262     mDestLeft = ovutils::OV_INVALID;
    263     mDestRight = ovutils::OV_INVALID;
    264     mRot = NULL;
    265 }
    266 
    267 bool FBUpdateSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
    268                               hwc_rect_t fbUpdatingRect, int fbZorder) {
    269     if(!ctx->mMDP.hasOverlay) {
    270         ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
    271                  __FUNCTION__);
    272         return false;
    273     }
    274     ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
    275     mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
    276     return mModeOn;
    277 }
    278 
    279 // Configure
    280 bool FBUpdateSplit::configure(hwc_context_t *ctx,
    281         hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
    282     bool ret = false;
    283     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    284     if (LIKELY(ctx->mOverlay)) {
    285         /*  External only layer present */
    286         int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
    287         if(extOnlyLayerIndex != -1) {
    288             layer = &list->hwLayers[extOnlyLayerIndex];
    289             layer->compositionType = HWC_OVERLAY;
    290         }
    291         ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
    292                           ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
    293                                                 mTileEnabled));
    294 
    295         overlay::Overlay& ov = *(ctx->mOverlay);
    296         ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
    297         ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
    298         ovutils::eTransform orient =
    299             static_cast<ovutils::eTransform>(layer->transform);
    300         const int hw_w = ctx->dpyAttr[mDpy].xres;
    301         const int hw_h = ctx->dpyAttr[mDpy].yres;
    302         const int lSplit = getLeftSplit(ctx, mDpy);
    303         mDestLeft = ovutils::OV_INVALID;
    304         mDestRight = ovutils::OV_INVALID;
    305 
    306         hwc_rect_t sourceCrop = fbUpdatingRect;
    307         hwc_rect_t displayFrame = fbUpdatingRect;
    308 
    309         ret = true;
    310         /* Configure left pipe */
    311         if(displayFrame.left < lSplit) {
    312             ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
    313                                                Overlay::MIXER_LEFT);
    314             if(destL == ovutils::OV_INVALID) { //None available
    315                 ALOGE("%s: No pipes available to configure fb for dpy %d's left"
    316                       " mixer", __FUNCTION__, mDpy);
    317                 return false;
    318             }
    319 
    320             mDestLeft = destL;
    321 
    322             //XXX: FB layer plane alpha is currently sent as zero from
    323             //surfaceflinger
    324             ovutils::PipeArgs pargL(mdpFlags,
    325                                     info,
    326                                     zOrder,
    327                                     ovutils::IS_FG_OFF,
    328                                     ovutils::ROT_FLAGS_NONE,
    329                                     ovutils::DEFAULT_PLANE_ALPHA,
    330                                     (ovutils::eBlending)
    331                                     getBlending(layer->blending));
    332             hwc_rect_t cropL = sourceCrop;
    333             hwc_rect_t dstL = displayFrame;
    334             hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
    335             qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
    336 
    337             if (configMdp(ctx->mOverlay, pargL, orient, cropL,
    338                            dstL, NULL, destL)< 0) {
    339                 ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
    340                 ret = false;
    341             }
    342         }
    343 
    344         /* Configure right pipe */
    345         if(displayFrame.right > lSplit) {
    346             ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
    347                                                Overlay::MIXER_RIGHT);
    348             if(destR == ovutils::OV_INVALID) { //None available
    349                 ALOGE("%s: No pipes available to configure fb for dpy %d's"
    350                       " right mixer", __FUNCTION__, mDpy);
    351                 return false;
    352             }
    353 
    354             mDestRight = destR;
    355             ovutils::eMdpFlags mdpFlagsR = mdpFlags;
    356             ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
    357 
    358             //XXX: FB layer plane alpha is currently sent as zero from
    359             //surfaceflinger
    360             ovutils::PipeArgs pargR(mdpFlagsR,
    361                                     info,
    362                                     zOrder,
    363                                     ovutils::IS_FG_OFF,
    364                                     ovutils::ROT_FLAGS_NONE,
    365                                     ovutils::DEFAULT_PLANE_ALPHA,
    366                                     (ovutils::eBlending)
    367                                     getBlending(layer->blending));
    368 
    369             hwc_rect_t cropR = sourceCrop;
    370             hwc_rect_t dstR = displayFrame;
    371             hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
    372             qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
    373 
    374             dstR.left -= lSplit;
    375             dstR.right -= lSplit;
    376 
    377             if (configMdp(ctx->mOverlay, pargR, orient, cropR,
    378                            dstR, NULL, destR) < 0) {
    379                 ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
    380                 ret = false;
    381             }
    382         }
    383 
    384         if(ret == false) {
    385             ctx->mLayerRotMap[mDpy]->clear();
    386         }
    387     }
    388     return ret;
    389 }
    390 
    391 bool FBUpdateSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
    392 {
    393     if(!mModeOn) {
    394         return true;
    395     }
    396     bool ret = true;
    397     overlay::Overlay& ov = *(ctx->mOverlay);
    398     if(mDestLeft != ovutils::OV_INVALID) {
    399         if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestLeft)) {
    400             ALOGE("%s: queue failed for left of dpy = %d",
    401                   __FUNCTION__, mDpy);
    402             ret = false;
    403         }
    404     }
    405     if(mDestRight != ovutils::OV_INVALID) {
    406         if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestRight)) {
    407             ALOGE("%s: queue failed for right of dpy = %d",
    408                   __FUNCTION__, mDpy);
    409             ret = false;
    410         }
    411     }
    412     return ret;
    413 }
    414 
    415 //=================FBSrcSplit====================================
    416 FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
    417         FBUpdateSplit(ctx, dpy) {}
    418 
    419 bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
    420         hwc_rect_t fbUpdatingRect, int fbZorder) {
    421     bool ret = false;
    422     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
    423     int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
    424     // ext only layer present..
    425     if(extOnlyLayerIndex != -1) {
    426         layer = &list->hwLayers[extOnlyLayerIndex];
    427         layer->compositionType = HWC_OVERLAY;
    428     }
    429     overlay::Overlay& ov = *(ctx->mOverlay);
    430 
    431     ovutils::Whf info(mAlignedFBWidth,
    432             mAlignedFBHeight,
    433             ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
    434                 mTileEnabled));
    435     //Request left pipe, VG first owing to higher prio
    436     ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy,
    437             Overlay::MIXER_DEFAULT);
    438     if(destL == ovutils::OV_INVALID) {
    439         destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
    440             Overlay::MIXER_DEFAULT);
    441         if(destL == ovutils::OV_INVALID) {
    442             ALOGE("%s: No pipes available to configure fb for dpy %d's left"
    443                     " mixer", __FUNCTION__, mDpy);
    444             return false;
    445         }
    446     }
    447     //Request right pipe
    448     ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
    449             Overlay::MIXER_DEFAULT);
    450     if(destR == ovutils::OV_INVALID) {
    451         ALOGE("%s: No pipes available to configure fb for dpy %d's right"
    452                 " mixer", __FUNCTION__, mDpy);
    453         return false;
    454     }
    455 
    456     mDestLeft = destL;
    457     mDestRight = destR;
    458 
    459     ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
    460     ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
    461 
    462     ovutils::PipeArgs parg(mdpFlags,
    463             info,
    464             zOrder,
    465             ovutils::IS_FG_OFF,
    466             ovutils::ROT_FLAGS_NONE,
    467             ovutils::DEFAULT_PLANE_ALPHA,
    468             (ovutils::eBlending)
    469             getBlending(layer->blending));
    470     ov.setSource(parg, destL);
    471     ov.setSource(parg, destR);
    472 
    473     //Crop and Position are same for FB
    474     ovutils::Dim cropPosL(
    475             fbUpdatingRect.left,
    476             fbUpdatingRect.top,
    477             (fbUpdatingRect.right - fbUpdatingRect.left) / 2,
    478             fbUpdatingRect.bottom - fbUpdatingRect.top);
    479 
    480     ovutils::Dim cropPosR(
    481             cropPosL.x + cropPosL.w,
    482             cropPosL.y,
    483             cropPosL.w,
    484             cropPosL.h);
    485 
    486     ov.setCrop(cropPosL, destL);
    487     ov.setCrop(cropPosR, destR);
    488     ov.setPosition(cropPosL, destL);
    489     ov.setPosition(cropPosR, destR);
    490 
    491     int transform = layer->transform;
    492     ovutils::eTransform orient =
    493             static_cast<ovutils::eTransform>(transform);
    494     ov.setTransform(orient, destL);
    495     ov.setTransform(orient, destR);
    496 
    497     ret = true;
    498     if (!ov.commit(destL)) {
    499         ALOGE("%s: commit fails for left", __FUNCTION__);
    500         ret = false;
    501     }
    502     if (!ov.commit(destR)) {
    503         ALOGE("%s: commit fails for right", __FUNCTION__);
    504         ret = false;
    505     }
    506     if(ret == false) {
    507         ctx->mLayerRotMap[mDpy]->clear();
    508     }
    509     return ret;
    510 }
    511 
    512 //---------------------------------------------------------------------
    513 }; //namespace qhwc
    514