Home | History | Annotate | Download | only in common
      1 /*
      2 // Copyright(c)2014 IntelCorporation
      3 //
      4 // LicensedundertheApacheLicense,Version2.0(the"License");
      5 // youmaynotusethisfileexceptincompliancewiththeLicense.
      6 // YoumayobtainacopyoftheLicenseat
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software
     11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS,
     12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
     13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand
     14 // limitationsundertheLicense.
     15 */
     16 
     17 #include <math.h>
     18 #include <HwcTrace.h>
     19 #include <Drm.h>
     20 #include <Hwcomposer.h>
     21 #include <PhysicalDevice.h>
     22 #include <common/OverlayPlaneBase.h>
     23 #include <common/TTMBufferMapper.h>
     24 #include <common/GrallocSubBuffer.h>
     25 #include <DisplayQuery.h>
     26 
     27 
     28 // FIXME: remove it
     29 #include <OMX_IVCommon.h>
     30 #include <OMX_IntelVideoExt.h>
     31 
     32 namespace android {
     33 namespace intel {
     34 
     35 OverlayPlaneBase::OverlayPlaneBase(int index, int disp)
     36     : DisplayPlane(index, PLANE_OVERLAY, disp),
     37       mTTMBuffers(),
     38       mActiveTTMBuffers(),
     39       mCurrent(0),
     40       mWsbm(0),
     41       mPipeConfig(0),
     42       mBobDeinterlace(0),
     43       mUseScaledBuffer(0)
     44 {
     45     CTRACE();
     46     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
     47         mBackBuffer[i] = 0;
     48     }
     49 }
     50 
     51 OverlayPlaneBase::~OverlayPlaneBase()
     52 {
     53     CTRACE();
     54 }
     55 
     56 bool OverlayPlaneBase::initialize(uint32_t bufferCount)
     57 {
     58     Drm *drm = Hwcomposer::getInstance().getDrm();
     59     CTRACE();
     60 
     61     // NOTE: use overlay's data buffer count for the overlay plane
     62     if (bufferCount < OVERLAY_DATA_BUFFER_COUNT) {
     63         ITRACE("override overlay buffer count from %d to %d",
     64              bufferCount, OVERLAY_DATA_BUFFER_COUNT);
     65         bufferCount = OVERLAY_DATA_BUFFER_COUNT;
     66     }
     67     if (!DisplayPlane::initialize(bufferCount)) {
     68         DEINIT_AND_RETURN_FALSE("failed to initialize display plane");
     69     }
     70 
     71     mTTMBuffers.setCapacity(bufferCount);
     72     mActiveTTMBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
     73 
     74     // init wsbm
     75     mWsbm = new Wsbm(drm->getDrmFd());
     76     if (!mWsbm || !mWsbm->initialize()) {
     77         DEINIT_AND_RETURN_FALSE("failed to create wsbm");
     78     }
     79 
     80     // create overlay back buffer
     81     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
     82         mBackBuffer[i] = createBackBuffer();
     83         if (!mBackBuffer[i]) {
     84             DEINIT_AND_RETURN_FALSE("failed to create overlay back buffer");
     85         }
     86         // reset back buffer
     87         resetBackBuffer(i);
     88     }
     89 
     90     // disable overlay when created
     91     flush(PLANE_DISABLE);
     92 
     93     return true;
     94 }
     95 
     96 bool OverlayPlaneBase::isDisabled()
     97 {
     98     RETURN_FALSE_IF_NOT_INIT();
     99 
    100     struct drm_psb_register_rw_arg arg;
    101     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    102 
    103     arg.get_plane_state_mask = 1;
    104     arg.plane.type = DC_OVERLAY_PLANE;
    105     arg.plane.index = mIndex;
    106     // pass the pipe index to check its enabled status
    107     // now we can pass the device id directly since
    108     // their values are just equal
    109     arg.plane.ctx = mDevice; // not used in kernel
    110 
    111     Drm *drm = Hwcomposer::getInstance().getDrm();
    112     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    113     if (ret == false) {
    114         WTRACE("overlay plane query failed with error code %d", ret);
    115         return false;
    116     }
    117 
    118     DTRACE("overlay %d status %s on device %d, current device %d",
    119         mIndex, arg.plane.ctx ? "DISABLED" : "ENABLED", mDevice, mDevice);
    120 
    121     return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
    122 }
    123 
    124 void OverlayPlaneBase::deinitialize()
    125 {
    126     if (mTTMBuffers.size()) {
    127         invalidateBufferCache();
    128     }
    129 
    130     if (mActiveTTMBuffers.size() > 0) {
    131         invalidateActiveTTMBuffers();
    132     }
    133 
    134     // delete back buffer
    135     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
    136         if (mBackBuffer[i]) {
    137             deleteBackBuffer(i);
    138             mBackBuffer[i] = NULL;
    139         }
    140     }
    141     DEINIT_AND_DELETE_OBJ(mWsbm);
    142 
    143     DisplayPlane::deinitialize();
    144 }
    145 
    146 void OverlayPlaneBase::invalidateBufferCache()
    147 {
    148     // clear plane buffer cache
    149     DisplayPlane::invalidateBufferCache();
    150     invalidateTTMBuffers();
    151 }
    152 
    153 bool OverlayPlaneBase::assignToDevice(int disp)
    154 {
    155     uint32_t pipeConfig = 0;
    156 
    157     RETURN_FALSE_IF_NOT_INIT();
    158     VTRACE("overlay %d assigned to disp %d", mIndex, disp);
    159 
    160     switch (disp) {
    161     case IDisplayDevice::DEVICE_EXTERNAL:
    162         pipeConfig = (0x2 << 6);
    163         break;
    164     case IDisplayDevice::DEVICE_PRIMARY:
    165     default:
    166         pipeConfig = 0;
    167         break;
    168     }
    169 
    170     // if pipe switching happened, then disable overlay first
    171     if (mPipeConfig != pipeConfig) {
    172         DTRACE("overlay %d switched from %d to %d", mIndex, mDevice, disp);
    173         disable();
    174     }
    175 
    176     mPipeConfig = pipeConfig;
    177     DisplayPlane::assignToDevice(disp);
    178 
    179     enable();
    180 
    181     return true;
    182 }
    183 
    184 void OverlayPlaneBase::setZOrderConfig(ZOrderConfig& zorderConfig,
    185                                             void *nativeConfig)
    186 {
    187     CTRACE();
    188 
    189     // setup overlay z order
    190     int ovaZOrder = -1;
    191     int ovcZOrder = -1;
    192     for (size_t i = 0; i < zorderConfig.size(); i++) {
    193         DisplayPlane *plane = zorderConfig[i]->plane;
    194         if (plane->getType() == DisplayPlane::PLANE_OVERLAY) {
    195             if (plane->getIndex() == 0) {
    196                 ovaZOrder = i;
    197             } else if (plane->getIndex() == 1) {
    198                 ovcZOrder = i;
    199             }
    200         }
    201     }
    202 
    203     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
    204         OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
    205         if (!backBuffer)
    206             return;
    207 
    208         // force overlay c above overlay a
    209         if ((ovaZOrder >= 0) && (ovaZOrder < ovcZOrder)) {
    210             backBuffer->OCONFIG |= (1 << 15);
    211         } else {
    212             backBuffer->OCONFIG &= ~(1 << 15);
    213         }
    214     }
    215 }
    216 
    217 bool OverlayPlaneBase::reset()
    218 {
    219     RETURN_FALSE_IF_NOT_INIT();
    220 
    221     DisplayPlane::reset();
    222 
    223     // invalidate active TTM buffers
    224     if (mActiveTTMBuffers.size() > 0) {
    225         invalidateActiveTTMBuffers();
    226     }
    227 
    228     // reset back buffers
    229     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
    230         resetBackBuffer(i);
    231     }
    232     return true;
    233 }
    234 
    235 bool OverlayPlaneBase::enable()
    236 {
    237     RETURN_FALSE_IF_NOT_INIT();
    238     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
    239         OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
    240         if (!backBuffer)
    241             return false;
    242 
    243         if (backBuffer->OCMD & 0x1)
    244             return true;
    245 
    246         backBuffer->OCMD |= 0x1;
    247     }
    248 
    249     // flush
    250     flush(PLANE_ENABLE);
    251     return true;
    252 }
    253 
    254 bool OverlayPlaneBase::disable()
    255 {
    256     RETURN_FALSE_IF_NOT_INIT();
    257     for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
    258         OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
    259         if (!backBuffer)
    260             return false;
    261 
    262         if (!(backBuffer->OCMD & 0x1))
    263             return true;
    264 
    265         backBuffer->OCMD &= ~0x1;
    266     }
    267 
    268     // flush
    269     flush(PLANE_DISABLE);
    270     return true;
    271 }
    272 
    273 OverlayBackBuffer* OverlayPlaneBase::createBackBuffer()
    274 {
    275     CTRACE();
    276 
    277     // create back buffer
    278     OverlayBackBuffer *backBuffer = (OverlayBackBuffer *)malloc(sizeof(OverlayBackBuffer));
    279     if (!backBuffer) {
    280         ETRACE("failed to allocate back buffer");
    281         return 0;
    282     }
    283 
    284 
    285     int size = sizeof(OverlayBackBufferBlk);
    286     int alignment = 64 * 1024;
    287     void *wsbmBufferObject = 0;
    288     bool ret = mWsbm->allocateTTMBuffer(size, alignment, &wsbmBufferObject);
    289     if (ret == false) {
    290         ETRACE("failed to allocate TTM buffer");
    291         return 0;
    292     }
    293 
    294     void *virtAddr = mWsbm->getCPUAddress(wsbmBufferObject);
    295     uint32_t gttOffsetInPage = mWsbm->getGttOffset(wsbmBufferObject);
    296 
    297     backBuffer->buf = (OverlayBackBufferBlk *)virtAddr;
    298     backBuffer->gttOffsetInPage = gttOffsetInPage;
    299     backBuffer->bufObject = wsbmBufferObject;
    300 
    301     VTRACE("cpu %p, gtt %d", virtAddr, gttOffsetInPage);
    302 
    303     return backBuffer;
    304 }
    305 
    306 void OverlayPlaneBase::deleteBackBuffer(int buf)
    307 {
    308     if (!mBackBuffer[buf])
    309         return;
    310 
    311     void *wsbmBufferObject = mBackBuffer[buf]->bufObject;
    312     bool ret = mWsbm->destroyTTMBuffer(wsbmBufferObject);
    313     if (ret == false) {
    314         WTRACE("failed to destroy TTM buffer");
    315     }
    316     // free back buffer
    317     free(mBackBuffer[buf]);
    318     mBackBuffer[buf] = 0;
    319 }
    320 
    321 void OverlayPlaneBase::resetBackBuffer(int buf)
    322 {
    323     CTRACE();
    324 
    325     if (!mBackBuffer[buf] || !mBackBuffer[buf]->buf)
    326         return;
    327 
    328     OverlayBackBufferBlk *backBuffer = mBackBuffer[buf]->buf;
    329 
    330     memset(backBuffer, 0, sizeof(OverlayBackBufferBlk));
    331 
    332     // reset overlay
    333     backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
    334                          (OVERLAY_INIT_BRIGHTNESS & 0xff);
    335     backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
    336     backBuffer->DCLRKV = OVERLAY_INIT_COLORKEY;
    337     backBuffer->DCLRKM = OVERLAY_INIT_COLORKEYMASK;
    338     backBuffer->OCONFIG = 0;
    339     backBuffer->OCONFIG |= (0x1 << 3);
    340     backBuffer->OCONFIG |= (0x1 << 27);
    341     backBuffer->SCHRKEN &= ~(0x7 << 24);
    342     backBuffer->SCHRKEN |= 0xff;
    343 }
    344 
    345 BufferMapper* OverlayPlaneBase::getTTMMapper(BufferMapper& grallocMapper, struct VideoPayloadBuffer *payload)
    346 {
    347     buffer_handle_t khandle;
    348     uint32_t w, h;
    349     uint32_t yStride, uvStride;
    350     stride_t stride;
    351     int srcX, srcY, srcW, srcH;
    352     int tmp;
    353 
    354     DataBuffer *buf;
    355     ssize_t index;
    356     TTMBufferMapper *mapper;
    357     bool ret;
    358 
    359     if (!payload) {
    360         ETRACE("invalid payload buffer");
    361         return 0;
    362     }
    363 
    364     srcX = grallocMapper.getCrop().x;
    365     srcY = grallocMapper.getCrop().y;
    366     srcW = grallocMapper.getCrop().w;
    367     srcH = grallocMapper.getCrop().h;
    368 
    369     // init ttm buffer
    370     if (mUseScaledBuffer) {
    371         khandle = payload->scaling_khandle;
    372     } else {
    373         khandle = payload->rotated_buffer_handle;
    374     }
    375     index = mTTMBuffers.indexOfKey(khandle);
    376     if (index < 0) {
    377         VTRACE("unmapped TTM buffer, will map it");
    378 
    379         if (mUseScaledBuffer) {
    380             w = payload->scaling_width;
    381             h = payload->scaling_height;
    382         } else {
    383             w = payload->rotated_width;
    384             h = payload->rotated_height;
    385 
    386             checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height);
    387         }
    388 
    389         uint32_t format = grallocMapper.getFormat();
    390         // this is for sw decode with tiled buffer in landscape mode
    391         if (payload->tiling)
    392             format = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled;
    393 
    394         // calculate stride
    395         switch (format) {
    396         case HAL_PIXEL_FORMAT_YV12:
    397         case HAL_PIXEL_FORMAT_I420:
    398             uint32_t yStride_align;
    399             yStride_align = DisplayQuery::getOverlayLumaStrideAlignment(grallocMapper.getFormat());
    400             if (yStride_align > 0)
    401             {
    402                 yStride = align_to(align_to(w, 32), yStride_align);
    403             }
    404             else
    405             {
    406                 yStride = align_to(align_to(w, 32), 64);
    407             }
    408             uvStride = align_to(yStride >> 1, 64);
    409             stride.yuv.yStride = yStride;
    410             stride.yuv.uvStride = uvStride;
    411             break;
    412         case HAL_PIXEL_FORMAT_NV12:
    413             yStride = align_to(align_to(w, 32), 64);
    414             uvStride = yStride;
    415             stride.yuv.yStride = yStride;
    416             stride.yuv.uvStride = uvStride;
    417             break;
    418         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
    419         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
    420             if (mUseScaledBuffer) {
    421                 stride.yuv.yStride = payload->scaling_luma_stride;
    422                 stride.yuv.uvStride = payload->scaling_chroma_u_stride;
    423             } else {
    424                yStride = align_to(align_to(w, 32), 64);
    425                uvStride = yStride;
    426                stride.yuv.yStride = yStride;
    427                stride.yuv.uvStride = uvStride;
    428             }
    429             break;
    430         case HAL_PIXEL_FORMAT_YUY2:
    431         case HAL_PIXEL_FORMAT_UYVY:
    432             yStride = align_to((align_to(w, 32) << 1), 64);
    433             uvStride = 0;
    434             stride.yuv.yStride = yStride;
    435             stride.yuv.uvStride = uvStride;
    436             break;
    437         }
    438 
    439         DataBuffer buf(khandle);
    440         // update buffer
    441         buf.setStride(stride);
    442         buf.setWidth(w);
    443         buf.setHeight(h);
    444         buf.setCrop(srcX, srcY, srcW, srcH);
    445         buf.setFormat(format);
    446 
    447         // create buffer mapper
    448         bool res = false;
    449         do {
    450             mapper = new TTMBufferMapper(*mWsbm, buf);
    451             if (!mapper) {
    452                 ETRACE("failed to allocate mapper");
    453                 break;
    454             }
    455             // map ttm buffer
    456             ret = mapper->map();
    457             if (!ret) {
    458                 ETRACE("failed to map");
    459                 invalidateTTMBuffers();
    460                 ret = mapper->map();
    461                 if (!ret) {
    462                     ETRACE("failed to remap");
    463                     break;
    464                 }
    465             }
    466 
    467             if (mTTMBuffers.size() >= OVERLAY_DATA_BUFFER_COUNT) {
    468                 invalidateTTMBuffers();
    469             }
    470 
    471             // add mapper
    472             index = mTTMBuffers.add(khandle, mapper);
    473             if (index < 0) {
    474                 ETRACE("failed to add TTMMapper");
    475                 break;
    476             }
    477 
    478             // increase mapper refCount since it is added to mTTMBuffers
    479             mapper->incRef();
    480             res = true;
    481         } while (0);
    482 
    483         if (!res) {
    484             // error handling
    485             if (mapper) {
    486                 mapper->unmap();
    487                 delete mapper;
    488                 mapper = NULL;
    489             }
    490             return 0;
    491         }
    492     } else {
    493         VTRACE("got mapper in saved ttm buffers");
    494         mapper = reinterpret_cast<TTMBufferMapper *>(mTTMBuffers.valueAt(index));
    495         if (mapper->getCrop().x != srcX || mapper->getCrop().y != srcY ||
    496             mapper->getCrop().w != srcW || mapper->getCrop().h != srcH) {
    497             if(!mUseScaledBuffer)
    498                checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height);
    499             mapper->setCrop(srcX, srcY, srcW, srcH);
    500         }
    501     }
    502 
    503     XTRACE();
    504     return mapper;
    505 }
    506 
    507 void OverlayPlaneBase::putTTMMapper(BufferMapper* mapper)
    508 {
    509     if (!mapper)
    510         return;
    511 
    512     if (!mapper->decRef()) {
    513         // unmap it
    514         mapper->unmap();
    515 
    516         // destroy this mapper
    517         delete mapper;
    518     }
    519 }
    520 
    521 bool OverlayPlaneBase::isActiveTTMBuffer(BufferMapper *mapper)
    522 {
    523     for (size_t i = 0; i < mActiveTTMBuffers.size(); i++) {
    524         BufferMapper *activeMapper = mActiveTTMBuffers.itemAt(i);
    525         if (!activeMapper)
    526             continue;
    527         if (activeMapper->getKey() == mapper->getKey())
    528             return true;
    529     }
    530 
    531     return false;
    532 }
    533 
    534 void OverlayPlaneBase::updateActiveTTMBuffers(BufferMapper *mapper)
    535 {
    536     // unmap the first entry (oldest buffer)
    537     if (mActiveTTMBuffers.size() >= MAX_ACTIVE_TTM_BUFFERS) {
    538         BufferMapper *oldest = mActiveTTMBuffers.itemAt(0);
    539         putTTMMapper(oldest);
    540         mActiveTTMBuffers.removeAt(0);
    541     }
    542 
    543     // queue it to cached buffers
    544     if (!isActiveTTMBuffer(mapper)) {
    545         mapper->incRef();
    546         mActiveTTMBuffers.push_back(mapper);
    547     }
    548 }
    549 
    550 void OverlayPlaneBase::invalidateActiveTTMBuffers()
    551 {
    552     BufferMapper* mapper;
    553 
    554     RETURN_VOID_IF_NOT_INIT();
    555 
    556     for (size_t i = 0; i < mActiveTTMBuffers.size(); i++) {
    557         mapper = mActiveTTMBuffers.itemAt(i);
    558         // unmap it
    559         putTTMMapper(mapper);
    560     }
    561 
    562     // clear recorded data buffers
    563     mActiveTTMBuffers.clear();
    564 }
    565 
    566 void OverlayPlaneBase::invalidateTTMBuffers()
    567 {
    568     BufferMapper* mapper;
    569     for (size_t i = 0; i < mTTMBuffers.size(); i++) {
    570         mapper = mTTMBuffers.valueAt(i);
    571         // putTTMMapper removes mapper from cache
    572         putTTMMapper(mapper);
    573     }
    574     mTTMBuffers.clear();
    575 }
    576 
    577 
    578 bool OverlayPlaneBase::rotatedBufferReady(BufferMapper& mapper, BufferMapper* &rotatedMapper)
    579 {
    580     struct VideoPayloadBuffer *payload;
    581     uint32_t format;
    582 
    583     // only NV12_VED has rotated buffer
    584     format = mapper.getFormat();
    585     if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
    586         format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled)
    587         return false;
    588 
    589     payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
    590     // check payload
    591     if (!payload) {
    592         ETRACE("no payload found");
    593         return false;
    594     }
    595 
    596     if (payload->force_output_method == FORCE_OUTPUT_GPU)
    597         return false;
    598 
    599     if (payload->client_transform != mTransform) {
    600         if (payload->surface_protected) {
    601             payload->hwc_timestamp = systemTime();
    602             payload->layer_transform = mTransform;
    603         }
    604         WTRACE("client is not ready");
    605         return false;
    606     }
    607 
    608     rotatedMapper = getTTMMapper(mapper, payload);
    609     return true;
    610 }
    611 
    612 
    613 bool OverlayPlaneBase::useOverlayRotation(BufferMapper& mapper)
    614 {
    615     // by default overlay plane does not support rotation.
    616     return false;
    617 }
    618 
    619 bool OverlayPlaneBase::scaledBufferReady(BufferMapper& mapper, BufferMapper* &scaledMapper, VideoPayloadBuffer *payload)
    620 {
    621     return false;
    622 }
    623 
    624 void OverlayPlaneBase::checkPosition(int& x, int& y, int& w, int& h)
    625 {
    626     drmModeModeInfoPtr mode = &mModeInfo;
    627 
    628     if (mode->hdisplay == 0 || mode->vdisplay == 0)
    629         return;
    630 
    631     if (x < 0)
    632         x = 0;
    633     if (y < 0)
    634         y = 0;
    635     if ((x + w) > mode->hdisplay)
    636         w = mode->hdisplay - x;
    637     if ((y + h) > mode->vdisplay)
    638         h = mode->vdisplay - y;
    639 }
    640 
    641 void OverlayPlaneBase::checkCrop(int& srcX, int& srcY, int& srcW, int& srcH,
    642                                int coded_width, int coded_height)
    643 {
    644     int tmp;
    645 
    646     if (mTransform)
    647         srcH >>= mBobDeinterlace;
    648 
    649     if (mTransform == HWC_TRANSFORM_ROT_90 || mTransform == HWC_TRANSFORM_ROT_270) {
    650         tmp = srcH;
    651         srcH = srcW;
    652         srcW = tmp;
    653 
    654         tmp = srcX;
    655         srcX = srcY;
    656         srcY = tmp;
    657 
    658         tmp = coded_width;
    659         coded_width = coded_height;
    660         coded_height = tmp;
    661     }
    662 
    663     // skip pading bytes in rotate buffer
    664     switch(mTransform) {
    665     case HWC_TRANSFORM_ROT_90:
    666         srcX = (coded_width >> mBobDeinterlace) - srcW - srcX;
    667         break;
    668     case HWC_TRANSFORM_ROT_180:
    669         srcX = coded_width - srcW - srcX;
    670         srcY = (coded_height >> mBobDeinterlace) - srcH - srcY;
    671         break;
    672     case HWC_TRANSFORM_ROT_270:
    673         srcY = coded_height - srcH - srcY;
    674         break;
    675     default:
    676         break;
    677     }
    678 }
    679 
    680 
    681 bool OverlayPlaneBase::bufferOffsetSetup(BufferMapper& mapper)
    682 {
    683     CTRACE();
    684 
    685     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
    686     if (!backBuffer) {
    687         ETRACE("invalid back buffer");
    688         return false;
    689     }
    690 
    691     uint32_t format = mapper.getFormat();
    692     uint32_t gttOffsetInBytes = (mapper.getGttOffsetInPage(0) << 12);
    693     uint32_t yStride = mapper.getStride().yuv.yStride;
    694     uint32_t uvStride = mapper.getStride().yuv.uvStride;
    695     uint32_t w = mapper.getWidth();
    696     uint32_t h = mapper.getHeight();
    697     uint32_t srcX= mapper.getCrop().x;
    698     uint32_t srcY= mapper.getCrop().y;
    699 
    700     // clear original format setting
    701     backBuffer->OCMD &= ~(0xf << 10);
    702     backBuffer->OCMD &= ~OVERLAY_MEMORY_LAYOUT_TILED;
    703 
    704     // Y/U/V plane must be 4k bytes aligned.
    705     backBuffer->OSTART_0Y = gttOffsetInBytes;
    706     if (mIsProtectedBuffer) {
    707         // temporary workaround until vsync event logic is corrected.
    708         // it seems that overlay buffer update and renderring can be overlapped,
    709         // as such encryption bit may be cleared during HW rendering
    710         backBuffer->OSTART_0Y |= 0x01;
    711     }
    712 
    713     backBuffer->OSTART_0U = gttOffsetInBytes;
    714     backBuffer->OSTART_0V = gttOffsetInBytes;
    715 
    716     backBuffer->OSTART_1Y = backBuffer->OSTART_0Y;
    717     backBuffer->OSTART_1U = backBuffer->OSTART_0U;
    718     backBuffer->OSTART_1V = backBuffer->OSTART_0V;
    719 
    720     switch(format) {
    721     case HAL_PIXEL_FORMAT_YV12:    // YV12
    722         backBuffer->OBUF_0Y = 0;
    723         backBuffer->OBUF_0V = yStride * h;
    724         backBuffer->OBUF_0U = backBuffer->OBUF_0V + (uvStride * (h / 2));
    725         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
    726         break;
    727     case HAL_PIXEL_FORMAT_I420:    // I420
    728         backBuffer->OBUF_0Y = 0;
    729         backBuffer->OBUF_0U = yStride * h;
    730         backBuffer->OBUF_0V = backBuffer->OBUF_0U + (uvStride * (h / 2));
    731         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
    732         break;
    733     case HAL_PIXEL_FORMAT_NV12:    // NV12
    734         backBuffer->OBUF_0Y = 0;
    735         backBuffer->OBUF_0U = yStride * h;
    736         backBuffer->OBUF_0V = 0;
    737         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    738         break;
    739     // NOTE: this is the decoded video format, align the height to 32B
    740     //as it's defined by video driver
    741     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:    // Intel codec NV12
    742         backBuffer->OBUF_0Y = 0;
    743         backBuffer->OBUF_0U = yStride * align_to(h, 32);
    744         backBuffer->OBUF_0V = 0;
    745         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    746         break;
    747     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:  //NV12_tiled
    748         backBuffer->OBUF_0Y = 0;
    749         backBuffer->OBUF_0U = yStride * align_to(h, 32);
    750         backBuffer->OBUF_0V = 0;
    751         backBuffer->OSTART_0U += yStride * align_to(h, 32);
    752         backBuffer->OSTART_0V += yStride * align_to(h, 32);
    753         backBuffer->OSTART_1U = backBuffer->OSTART_0U;
    754         backBuffer->OSTART_1V = backBuffer->OSTART_0V;
    755         backBuffer->OTILEOFF_0Y = srcX + (srcY << 16);
    756         backBuffer->OTILEOFF_1Y = backBuffer->OTILEOFF_0Y;
    757         backBuffer->OTILEOFF_0U = srcX + ((srcY / 2) << 16);
    758         backBuffer->OTILEOFF_1U = backBuffer->OTILEOFF_0U;
    759         backBuffer->OTILEOFF_0V = backBuffer->OTILEOFF_0U;
    760         backBuffer->OTILEOFF_1V = backBuffer->OTILEOFF_0U;
    761         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    762         backBuffer->OCMD |= OVERLAY_MEMORY_LAYOUT_TILED;
    763         break;
    764     case HAL_PIXEL_FORMAT_YUY2:    // YUY2
    765         backBuffer->OBUF_0Y = 0;
    766         backBuffer->OBUF_0U = 0;
    767         backBuffer->OBUF_0V = 0;
    768         backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
    769         backBuffer->OCMD |= OVERLAY_PACKED_ORDER_YUY2;
    770         break;
    771     case HAL_PIXEL_FORMAT_UYVY:    // UYVY
    772         backBuffer->OBUF_0Y = 0;
    773         backBuffer->OBUF_0U = 0;
    774         backBuffer->OBUF_0V = 0;
    775         backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
    776         backBuffer->OCMD |= OVERLAY_PACKED_ORDER_UYVY;
    777         break;
    778     default:
    779         ETRACE("unsupported format %d", format);
    780         return false;
    781     }
    782 
    783     backBuffer->OBUF_0Y += srcY * yStride + srcX;
    784     backBuffer->OBUF_0V += (srcY / 2) * uvStride + srcX;
    785     backBuffer->OBUF_0U += (srcY / 2) * uvStride + srcX;
    786     backBuffer->OBUF_1Y = backBuffer->OBUF_0Y;
    787     backBuffer->OBUF_1U = backBuffer->OBUF_0U;
    788     backBuffer->OBUF_1V = backBuffer->OBUF_0V;
    789 
    790     VTRACE("done. offset (%d, %d, %d)",
    791           backBuffer->OBUF_0Y,
    792           backBuffer->OBUF_0U,
    793           backBuffer->OBUF_0V);
    794     return true;
    795 }
    796 
    797 uint32_t OverlayPlaneBase::calculateSWidthSW(uint32_t offset, uint32_t width)
    798 {
    799     ATRACE("offset = %d, width = %d", offset, width);
    800 
    801     uint32_t swidth = ((offset + width + 0x3F) >> 6) - (offset >> 6);
    802 
    803     swidth <<= 1;
    804     swidth -= 1;
    805 
    806     return swidth;
    807 }
    808 
    809 bool OverlayPlaneBase::coordinateSetup(BufferMapper& mapper)
    810 {
    811     CTRACE();
    812 
    813     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
    814     if (!backBuffer) {
    815         ETRACE("invalid back buffer");
    816         return false;
    817     }
    818 
    819     uint32_t swidthy = 0;
    820     uint32_t swidthuv = 0;
    821     uint32_t format = mapper.getFormat();
    822     uint32_t width = mapper.getCrop().w;
    823     uint32_t height = mapper.getCrop().h;
    824     uint32_t yStride = mapper.getStride().yuv.yStride;
    825     uint32_t uvStride = mapper.getStride().yuv.uvStride;
    826     uint32_t offsety = backBuffer->OBUF_0Y;
    827     uint32_t offsetu = backBuffer->OBUF_0U;
    828 
    829     switch (format) {
    830     case HAL_PIXEL_FORMAT_YV12:              // YV12
    831     case HAL_PIXEL_FORMAT_I420:              // I420
    832     case HAL_PIXEL_FORMAT_NV12:              // NV12
    833     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:          // NV12
    834     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:    // NV12_tiled
    835         break;
    836     case HAL_PIXEL_FORMAT_YUY2:              // YUY2
    837     case HAL_PIXEL_FORMAT_UYVY:              // UYVY
    838         width <<= 1;
    839         break;
    840     default:
    841         ETRACE("unsupported format %d", format);
    842         return false;
    843     }
    844 
    845     if (width <= 0 || height <= 0) {
    846         ETRACE("invalid src dim");
    847         return false;
    848     }
    849 
    850     if (yStride <=0 && uvStride <= 0) {
    851         ETRACE("invalid source stride");
    852         return false;
    853     }
    854 
    855     backBuffer->SWIDTH = width | ((width / 2) << 16);
    856     swidthy = calculateSWidthSW(offsety, width);
    857     swidthuv = calculateSWidthSW(offsetu, width / 2);
    858     backBuffer->SWIDTHSW = (swidthy << 2) | (swidthuv << 18);
    859     backBuffer->SHEIGHT = height | ((height / 2) << 16);
    860     backBuffer->OSTRIDE = (yStride & (~0x3f)) | ((uvStride & (~0x3f)) << 16);
    861 
    862     XTRACE();
    863 
    864     return true;
    865 }
    866 
    867 bool OverlayPlaneBase::setCoeffRegs(double *coeff, int mantSize,
    868                                   coeffPtr pCoeff, int pos)
    869 {
    870     int maxVal, icoeff, res;
    871     int sign;
    872     double c;
    873 
    874     sign = 0;
    875     maxVal = 1 << mantSize;
    876     c = *coeff;
    877     if (c < 0.0) {
    878         sign = 1;
    879         c = -c;
    880     }
    881 
    882     res = 12 - mantSize;
    883     if ((icoeff = (int)(c * 4 * maxVal + 0.5)) < maxVal) {
    884         pCoeff[pos].exponent = 3;
    885         pCoeff[pos].mantissa = icoeff << res;
    886         *coeff = (double)icoeff / (double)(4 * maxVal);
    887     } else if ((icoeff = (int)(c * 2 * maxVal + 0.5)) < maxVal) {
    888         pCoeff[pos].exponent = 2;
    889         pCoeff[pos].mantissa = icoeff << res;
    890         *coeff = (double)icoeff / (double)(2 * maxVal);
    891     } else if ((icoeff = (int)(c * maxVal + 0.5)) < maxVal) {
    892         pCoeff[pos].exponent = 1;
    893         pCoeff[pos].mantissa = icoeff << res;
    894         *coeff = (double)icoeff / (double)(maxVal);
    895     } else if ((icoeff = (int)(c * maxVal * 0.5 + 0.5)) < maxVal) {
    896         pCoeff[pos].exponent = 0;
    897         pCoeff[pos].mantissa = icoeff << res;
    898         *coeff = (double)icoeff / (double)(maxVal / 2);
    899     } else {
    900         // Coeff out of range
    901         return false;
    902     }
    903 
    904     pCoeff[pos].sign = sign;
    905     if (sign)
    906         *coeff = -(*coeff);
    907     return true;
    908 }
    909 
    910 void OverlayPlaneBase::updateCoeff(int taps, double fCutoff,
    911                                  bool isHoriz, bool isY,
    912                                  coeffPtr pCoeff)
    913 {
    914     int i, j, j1, num, pos, mantSize;
    915     double pi = 3.1415926535, val, sinc, window, sum;
    916     double rawCoeff[MAX_TAPS * 32], coeffs[N_PHASES][MAX_TAPS];
    917     double diff;
    918     int tapAdjust[MAX_TAPS], tap2Fix;
    919     bool isVertAndUV;
    920 
    921     if (isHoriz)
    922         mantSize = 7;
    923     else
    924         mantSize = 6;
    925 
    926     isVertAndUV = !isHoriz && !isY;
    927     num = taps * 16;
    928     for (i = 0; i < num  * 2; i++) {
    929         val = (1.0 / fCutoff) * taps * pi * (i - num) / (2 * num);
    930         if (val == 0.0)
    931             sinc = 1.0;
    932         else
    933             sinc = sin(val) / val;
    934 
    935         // Hamming window
    936         window = (0.54 - 0.46 * cos(2 * i * pi / (2 * num - 1)));
    937         rawCoeff[i] = sinc * window;
    938     }
    939 
    940     for (i = 0; i < N_PHASES; i++) {
    941         // Normalise the coefficients
    942         sum = 0.0;
    943         for (j = 0; j < taps; j++) {
    944             pos = i + j * 32;
    945             sum += rawCoeff[pos];
    946         }
    947         for (j = 0; j < taps; j++) {
    948             pos = i + j * 32;
    949             coeffs[i][j] = rawCoeff[pos] / sum;
    950         }
    951 
    952         // Set the register values
    953         for (j = 0; j < taps; j++) {
    954             pos = j + i * taps;
    955             if ((j == (taps - 1) / 2) && !isVertAndUV)
    956                 setCoeffRegs(&coeffs[i][j], mantSize + 2, pCoeff, pos);
    957             else
    958                 setCoeffRegs(&coeffs[i][j], mantSize, pCoeff, pos);
    959         }
    960 
    961         tapAdjust[0] = (taps - 1) / 2;
    962         for (j = 1, j1 = 1; j <= tapAdjust[0]; j++, j1++) {
    963             tapAdjust[j1] = tapAdjust[0] - j;
    964             tapAdjust[++j1] = tapAdjust[0] + j;
    965         }
    966 
    967         // Adjust the coefficients
    968         sum = 0.0;
    969         for (j = 0; j < taps; j++)
    970             sum += coeffs[i][j];
    971         if (sum != 1.0) {
    972             for (j1 = 0; j1 < taps; j1++) {
    973                 tap2Fix = tapAdjust[j1];
    974                 diff = 1.0 - sum;
    975                 coeffs[i][tap2Fix] += diff;
    976                 pos = tap2Fix + i * taps;
    977                 if ((tap2Fix == (taps - 1) / 2) && !isVertAndUV)
    978                     setCoeffRegs(&coeffs[i][tap2Fix], mantSize + 2, pCoeff, pos);
    979                 else
    980                     setCoeffRegs(&coeffs[i][tap2Fix], mantSize, pCoeff, pos);
    981 
    982                 sum = 0.0;
    983                 for (j = 0; j < taps; j++)
    984                     sum += coeffs[i][j];
    985                 if (sum == 1.0)
    986                     break;
    987             }
    988         }
    989     }
    990 }
    991 
    992 bool OverlayPlaneBase::scalingSetup(BufferMapper& mapper)
    993 {
    994     int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
    995     int xscaleIntUV, xscaleFractUV;
    996     int yscaleIntUV, yscaleFractUV;
    997     int deinterlace_factor = 1;
    998     // UV is half the size of Y -- YUV420
    999     int uvratio = 2;
   1000     uint32_t newval;
   1001     coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES];
   1002     coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES];
   1003     int i, j, pos;
   1004     bool scaleChanged = false;
   1005     int x, y, w, h;
   1006 
   1007     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
   1008     if (!backBuffer) {
   1009         ETRACE("invalid back buffer");
   1010         return false;
   1011     }
   1012 
   1013     x = mPosition.x;
   1014     y = mPosition.y;
   1015     w = mPosition.w;
   1016     h = mPosition.h;
   1017 
   1018     // check position
   1019     checkPosition(x, y, w, h);
   1020     VTRACE("final position (%d, %d, %d, %d)", x, y, w, h);
   1021 
   1022     if ((w <= 0) || (h <= 0)) {
   1023          ETRACE("invalid dst width/height");
   1024          return false;
   1025     }
   1026 
   1027     // setup dst position
   1028     backBuffer->DWINPOS = (y << 16) | x;
   1029     backBuffer->DWINSZ = (h << 16) | w;
   1030 
   1031     uint32_t srcWidth = mapper.getCrop().w;
   1032     uint32_t srcHeight = mapper.getCrop().h;
   1033     uint32_t dstWidth = w;
   1034     uint32_t dstHeight = h;
   1035 
   1036     if (mBobDeinterlace && !mTransform)
   1037         deinterlace_factor = 2;
   1038 
   1039     VTRACE("src (%dx%d), dst (%dx%d)",
   1040           srcWidth, srcHeight,
   1041           dstWidth, dstHeight);
   1042 
   1043      // Y down-scale factor as a multiple of 4096
   1044     if (srcWidth == dstWidth && srcHeight == dstHeight) {
   1045         xscaleFract = (1 << 12);
   1046         yscaleFract = (1 << 12)/deinterlace_factor;
   1047     } else {
   1048         xscaleFract = ((srcWidth - 1) << 12) / dstWidth;
   1049         yscaleFract = ((srcHeight - 1) << 12) / (dstHeight * deinterlace_factor);
   1050     }
   1051 
   1052     // Calculate the UV scaling factor
   1053     xscaleFractUV = xscaleFract / uvratio;
   1054     yscaleFractUV = yscaleFract / uvratio;
   1055 
   1056     // To keep the relative Y and UV ratios exact, round the Y scales
   1057     // to a multiple of the Y/UV ratio.
   1058     xscaleFract = xscaleFractUV * uvratio;
   1059     yscaleFract = yscaleFractUV * uvratio;
   1060 
   1061     // Integer (un-multiplied) values
   1062     xscaleInt = xscaleFract >> 12;
   1063     yscaleInt = yscaleFract >> 12;
   1064 
   1065     xscaleIntUV = xscaleFractUV >> 12;
   1066     yscaleIntUV = yscaleFractUV >> 12;
   1067 
   1068     // Check scaling ratio
   1069     if (xscaleInt > INTEL_OVERLAY_MAX_SCALING_RATIO) {
   1070         ETRACE("xscaleInt > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
   1071         return false;
   1072     }
   1073 
   1074     // shouldn't get here
   1075     if (xscaleIntUV > INTEL_OVERLAY_MAX_SCALING_RATIO) {
   1076         ETRACE("xscaleIntUV > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
   1077         return false;
   1078     }
   1079 
   1080     newval = (xscaleInt << 15) |
   1081     ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
   1082     if (newval != backBuffer->YRGBSCALE) {
   1083         scaleChanged = true;
   1084         backBuffer->YRGBSCALE = newval;
   1085     }
   1086 
   1087     newval = (xscaleIntUV << 15) | ((xscaleFractUV & 0xFFF) << 3) |
   1088     ((yscaleFractUV & 0xFFF) << 20);
   1089     if (newval != backBuffer->UVSCALE) {
   1090         scaleChanged = true;
   1091         backBuffer->UVSCALE = newval;
   1092     }
   1093 
   1094     newval = yscaleInt << 16 | yscaleIntUV;
   1095     if (newval != backBuffer->UVSCALEV) {
   1096         scaleChanged = true;
   1097         backBuffer->UVSCALEV = newval;
   1098     }
   1099 
   1100     // Recalculate coefficients if the scaling changed
   1101     // Only Horizontal coefficients so far.
   1102     if (scaleChanged) {
   1103         double fCutoffY;
   1104         double fCutoffUV;
   1105 
   1106         fCutoffY = xscaleFract / 4096.0;
   1107         fCutoffUV = xscaleFractUV / 4096.0;
   1108 
   1109         // Limit to between 1.0 and 3.0
   1110         if (fCutoffY < MIN_CUTOFF_FREQ)
   1111             fCutoffY = MIN_CUTOFF_FREQ;
   1112         if (fCutoffY > MAX_CUTOFF_FREQ)
   1113             fCutoffY = MAX_CUTOFF_FREQ;
   1114         if (fCutoffUV < MIN_CUTOFF_FREQ)
   1115             fCutoffUV = MIN_CUTOFF_FREQ;
   1116         if (fCutoffUV > MAX_CUTOFF_FREQ)
   1117             fCutoffUV = MAX_CUTOFF_FREQ;
   1118 
   1119         updateCoeff(N_HORIZ_Y_TAPS, fCutoffY, true, true, xcoeffY);
   1120         updateCoeff(N_HORIZ_UV_TAPS, fCutoffUV, true, false, xcoeffUV);
   1121 
   1122         for (i = 0; i < N_PHASES; i++) {
   1123             for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
   1124                 pos = i * N_HORIZ_Y_TAPS + j;
   1125                 backBuffer->Y_HCOEFS[pos] =
   1126                         (xcoeffY[pos].sign << 15 |
   1127                          xcoeffY[pos].exponent << 12 |
   1128                          xcoeffY[pos].mantissa);
   1129             }
   1130         }
   1131         for (i = 0; i < N_PHASES; i++) {
   1132             for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
   1133                 pos = i * N_HORIZ_UV_TAPS + j;
   1134                 backBuffer->UV_HCOEFS[pos] =
   1135                          (xcoeffUV[pos].sign << 15 |
   1136                           xcoeffUV[pos].exponent << 12 |
   1137                           xcoeffUV[pos].mantissa);
   1138             }
   1139         }
   1140     }
   1141 
   1142     XTRACE();
   1143     return true;
   1144 }
   1145 
   1146 bool OverlayPlaneBase::colorSetup(BufferMapper& mapper)
   1147 {
   1148     CTRACE();
   1149 
   1150     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
   1151     if (!backBuffer) {
   1152         ETRACE("invalid back buffer");
   1153         return false;
   1154     }
   1155 
   1156     uint32_t format = mapper.getFormat();
   1157     if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
   1158         format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
   1159 
   1160         VTRACE("Not video layer, use default color setting");
   1161         backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
   1162                          (OVERLAY_INIT_BRIGHTNESS & 0xff);
   1163         backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
   1164         backBuffer->OCONFIG &= ~(1 << 5);
   1165 
   1166         return true;
   1167     }
   1168 
   1169     struct VideoPayloadBuffer *payload;
   1170     payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
   1171     // check payload
   1172     if (!payload) {
   1173         ETRACE("no payload found");
   1174         return false;
   1175     }
   1176 
   1177     // BT.601 or BT.709
   1178     backBuffer->OCONFIG &= ~(1 << 5);
   1179     backBuffer->OCONFIG |= ((payload->csc_mode & 1) << 5);
   1180 
   1181     // no level expansion for video on HDMI
   1182     if (payload->video_range || mPipeConfig == (0x2 << 6)) {
   1183         // full range, no need to do level expansion
   1184         backBuffer->OCLRC0 = 0x1000000;
   1185         backBuffer->OCLRC1 = 0x80;
   1186     } else {
   1187         // level expansion for limited range
   1188         backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
   1189                          (OVERLAY_INIT_BRIGHTNESS & 0xff);
   1190         backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
   1191     }
   1192 
   1193     return true;
   1194 }
   1195 
   1196 bool OverlayPlaneBase::setDataBuffer(BufferMapper& grallocMapper)
   1197 {
   1198     BufferMapper *mapper;
   1199     BufferMapper *videoBufferMapper = 0;
   1200     bool ret;
   1201     uint32_t format;
   1202 
   1203     RETURN_FALSE_IF_NOT_INIT();
   1204 
   1205     // get gralloc mapper
   1206     mapper = &grallocMapper;
   1207     format = grallocMapper.getFormat();
   1208     if (format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar ||
   1209         format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
   1210         struct VideoPayloadBuffer *payload;
   1211         payload = (struct VideoPayloadBuffer *)grallocMapper.getCpuAddress(SUB_BUFFER1);
   1212         if (!payload) {
   1213             ETRACE("invalid payload buffer");
   1214             return 0;
   1215         }
   1216 
   1217         mBobDeinterlace = payload->bob_deinterlace;
   1218 
   1219         int srcW, srcH;
   1220         srcW = grallocMapper.getCrop().w - grallocMapper.getCrop().x;
   1221         srcH = grallocMapper.getCrop().h - grallocMapper.getCrop().y;
   1222         if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) {
   1223             if (mTransform) {
   1224                 int x, y, w, h;
   1225                 x = mSrcCrop.x;
   1226                 y = mSrcCrop.y;
   1227                 w = mSrcCrop.w;
   1228                 h = mSrcCrop.h;
   1229                 setSourceCrop(0, 0, payload->scaling_width, payload->scaling_height);
   1230                 if (!useOverlayRotation(grallocMapper)) {
   1231                     DTRACE("The scaled buffer will hit overlay rotation limitation, fall back to GLES");
   1232                     setSourceCrop(x, y, w, h);
   1233                     return false;
   1234                 }
   1235             }
   1236 
   1237             if (!scaledBufferReady(grallocMapper, videoBufferMapper, payload)) {
   1238                 DTRACE("scaled buffer is not ready, fall back to GLES");
   1239                 return false;
   1240             } else {
   1241                 videoBufferMapper->setFormat(OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar);
   1242                 mapper = videoBufferMapper;
   1243             }
   1244         }
   1245     }
   1246 
   1247     if (!mUseScaledBuffer && mTransform && !useOverlayRotation(grallocMapper)) {
   1248         if (!rotatedBufferReady(grallocMapper, videoBufferMapper)) {
   1249             DTRACE("rotated buffer is not ready");
   1250             return false;
   1251         }
   1252 
   1253         if (!videoBufferMapper) {
   1254             ETRACE("failed to get rotated buffer");
   1255             return false;
   1256         }
   1257         mapper = videoBufferMapper;
   1258     }
   1259 
   1260     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
   1261     if (!backBuffer) {
   1262         ETRACE("invalid back buffer");
   1263         return false;
   1264     }
   1265 
   1266     ret = bufferOffsetSetup(*mapper);
   1267     if (ret == false) {
   1268         ETRACE("failed to set up buffer offsets");
   1269         return false;
   1270     }
   1271 
   1272     ret = coordinateSetup(*mapper);
   1273     if (ret == false) {
   1274         ETRACE("failed to set up overlay coordinates");
   1275         return false;
   1276     }
   1277 
   1278     ret = scalingSetup(*mapper);
   1279     if (ret == false) {
   1280         ETRACE("failed to set up scaling parameters");
   1281         return false;
   1282     }
   1283 
   1284     backBuffer->OCMD |= 0x1;
   1285 
   1286     ret = colorSetup(grallocMapper);
   1287     if (ret == false) {
   1288         ETRACE("failed to set up color parameters");
   1289         return false;
   1290     }
   1291     if (mBobDeinterlace && !mTransform) {
   1292         backBuffer->OCMD |= BUF_TYPE_FIELD;
   1293         backBuffer->OCMD &= ~FIELD_SELECT;
   1294         backBuffer->OCMD |= FIELD0;
   1295         backBuffer->OCMD &= ~(BUFFER_SELECT);
   1296         backBuffer->OCMD |= BUFFER0;
   1297     }
   1298 
   1299     // add to active ttm buffers if it's a rotated buffer
   1300     if (videoBufferMapper) {
   1301         updateActiveTTMBuffers(mapper);
   1302     }
   1303 
   1304     mUseScaledBuffer = 0;
   1305     return true;
   1306 }
   1307 
   1308 } // namespace intel
   1309 } // namespace android
   1310 
   1311