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