Home | History | Annotate | Download | only in anniedale
      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 #include <common/utils/HwcTrace.h>
     17 #include <Hwcomposer.h>
     18 #include <BufferManager.h>
     19 #include <ips/anniedale/AnnRGBPlane.h>
     20 #include <ips/tangier/TngGrallocBuffer.h>
     21 #include <ips/common/PixelFormat.h>
     22 
     23 namespace android {
     24 namespace intel {
     25 
     26 AnnRGBPlane::AnnRGBPlane(int index, int type, int disp)
     27     : DisplayPlane(index, type, disp)
     28 {
     29     CTRACE();
     30     memset(&mContext, 0, sizeof(mContext));
     31 }
     32 
     33 AnnRGBPlane::~AnnRGBPlane()
     34 {
     35     CTRACE();
     36 }
     37 
     38 bool AnnRGBPlane::enable()
     39 {
     40     return enablePlane(true);
     41 }
     42 
     43 bool AnnRGBPlane::disable()
     44 {
     45     return enablePlane(false);
     46 }
     47 
     48 bool AnnRGBPlane::reset()
     49 {
     50     while (!mScalingBufferMap.isEmpty()) {
     51         uint32_t handle = mScalingBufferMap.valueAt(0);
     52         Hwcomposer::getInstance().getBufferManager()->freeGrallocBuffer(handle);
     53         mScalingBufferMap.removeItemsAt(0);
     54     }
     55 
     56     return DisplayPlane::reset();
     57 }
     58 
     59 bool AnnRGBPlane::flip(void*)
     60 {
     61     if (mForceScaling) {
     62         BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
     63         if (!bm->blitGrallocBuffer(mScalingSource, mScalingTarget, mDisplayCrop, 0)) {
     64             ELOGTRACE("Failed to blit RGB buffer.");
     65             return false;
     66         }
     67     }
     68 
     69     return true;
     70 }
     71 
     72 void* AnnRGBPlane::getContext() const
     73 {
     74     CTRACE();
     75     return (void *)&mContext;
     76 }
     77 
     78 void AnnRGBPlane::setZOrderConfig(ZOrderConfig& /* config */, void * /* nativeConfig */)
     79 {
     80     CTRACE();
     81 }
     82 
     83 bool AnnRGBPlane::setDataBuffer(uint32_t handle)
     84 {
     85     if (!handle) {
     86         if (!mForceScaling) {
     87             setFramebufferTarget(handle);
     88             return true;
     89         } else {
     90             ELOGTRACE("Invalid handle while scaling is required.");
     91             return false;
     92         }
     93     }
     94 
     95     if (mForceScaling) {
     96         BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
     97         ssize_t index = mScalingBufferMap.indexOfKey(handle);
     98         if (index < 0) {
     99             mScalingTarget = bm->allocGrallocBuffer(
    100                     mDisplayWidth,
    101                     mDisplayHeight,
    102                     HAL_PIXEL_FORMAT_RGBA_8888,
    103                     GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE);
    104             if (!mScalingTarget) {
    105                 ELOGTRACE("Failed to allocate gralloc buffer.");
    106                 return false;
    107             }
    108             mScalingBufferMap.add(handle, mScalingTarget);
    109         } else {
    110             mScalingTarget = mScalingBufferMap.valueAt(index);
    111         }
    112         mScalingSource = handle;
    113         handle = mScalingTarget;
    114     }
    115 
    116     TngGrallocBuffer tmpBuf(handle);
    117     uint32_t usage;
    118     bool ret;
    119 
    120     ALOGTRACE("handle = %#x", handle);
    121 
    122     usage = tmpBuf.getUsage();
    123     if (GRALLOC_USAGE_HW_FB & usage) {
    124         setFramebufferTarget(handle);
    125         return true;
    126     }
    127 
    128     // use primary as a sprite
    129     ret = DisplayPlane::setDataBuffer(handle);
    130     if (ret == false) {
    131         ELOGTRACE("failed to set data buffer");
    132         return ret;
    133     }
    134 
    135     return true;
    136 }
    137 
    138 bool AnnRGBPlane::setDataBuffer(BufferMapper& mapper)
    139 {
    140     int bpp;
    141     int srcX, srcY, srcW, srcH;
    142     int dstX, dstY, dstW, dstH;
    143     uint32_t spriteFormat;
    144     uint32_t stride;
    145     uint32_t linoff;
    146     uint32_t planeAlpha;
    147     drmModeModeInfoPtr mode = &mModeInfo;
    148 
    149     CTRACE();
    150 
    151     // setup plane position
    152     dstX = mPosition.x;
    153     dstY = mPosition.y;
    154     dstW = mPosition.w;
    155     dstH = mPosition.h;
    156 
    157     checkPosition(dstX, dstY, dstW, dstH);
    158 
    159     // setup plane format
    160     if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) {
    161         ELOGTRACE("unsupported format %#x", mapper.getFormat());
    162         return false;
    163     }
    164 
    165     // setup stride and source buffer crop
    166     srcX = mapper.getCrop().x;
    167     srcY = mapper.getCrop().y;
    168     srcW = mapper.getWidth();
    169     srcH = mapper.getHeight();
    170     stride = mapper.getStride().rgb.stride;
    171 
    172     if (mPanelOrientation == PANEL_ORIENTATION_180)
    173         linoff = srcY * stride + srcX * bpp + (mapper.getCrop().h  - 1) * stride + (mapper.getCrop().w - 1) * bpp;
    174     else
    175         linoff = srcY * stride + srcX * bpp;
    176 
    177     // unlikely happen, but still we need make sure linoff is valid
    178     if (linoff > (stride * mapper.getHeight())) {
    179         ELOGTRACE("invalid source crop");
    180         return false;
    181     }
    182 
    183     // update context
    184     if (mType == PLANE_SPRITE)
    185         mContext.type = DC_SPRITE_PLANE;
    186     else
    187         mContext.type = DC_PRIMARY_PLANE;
    188 
    189     // setup plane alpha
    190     if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
    191        planeAlpha = mPlaneAlpha | 0x80000000;
    192     } else {
    193        // disable plane alpha to offload HW
    194        planeAlpha = 0xff;
    195     }
    196 
    197     mContext.ctx.sp_ctx.index = mIndex;
    198     mContext.ctx.sp_ctx.pipe = mDevice;
    199     mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000;
    200     mContext.ctx.sp_ctx.linoff = linoff;
    201     mContext.ctx.sp_ctx.stride = stride;
    202 
    203     // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    204     if (mBlending == HWC_BLENDING_COVERAGE) {
    205         mContext.ctx.sp_ctx.cntr |= (0x1 << 23);
    206     }
    207 
    208     if (mPanelOrientation == PANEL_ORIENTATION_180)
    209         mContext.ctx.sp_ctx.cntr |= (0x1 << 15);
    210 
    211     if (mapper.isCompression()) {
    212         mContext.ctx.sp_ctx.stride = align_to(srcW, 32) * 4;
    213         mContext.ctx.sp_ctx.linoff = (align_to(srcW, 32) * srcH / 64) - 1;
    214         mContext.ctx.sp_ctx.tileoff = (srcY & 0xfff) << 16 | (srcX & 0xfff);
    215         mContext.ctx.sp_ctx.cntr |= (0x1 << 11);
    216     }
    217 
    218     mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
    219 
    220     if (mPanelOrientation == PANEL_ORIENTATION_180) {
    221         if (mode->vdisplay && mode->hdisplay)
    222             mContext.ctx.sp_ctx.pos = ((mode->vdisplay - dstY - dstH) & 0xfff) << 16 | ((mode->hdisplay - dstX - dstW) & 0xfff);
    223         else
    224             mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    225     } else {
    226         mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    227     }
    228 
    229     mContext.ctx.sp_ctx.size =
    230         ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff);
    231     mContext.ctx.sp_ctx.contalpa = planeAlpha;
    232     mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL;
    233 
    234     VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
    235           "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
    236           mContext.ctx.sp_ctx.cntr,
    237           mContext.ctx.sp_ctx.linoff,
    238           mContext.ctx.sp_ctx.stride,
    239           mContext.ctx.sp_ctx.surf,
    240           mContext.ctx.sp_ctx.pos,
    241           mContext.ctx.sp_ctx.size,
    242           mContext.ctx.sp_ctx.contalpa);
    243     return true;
    244 }
    245 
    246 bool AnnRGBPlane::enablePlane(bool enabled)
    247 {
    248     RETURN_FALSE_IF_NOT_INIT();
    249 
    250     struct drm_psb_register_rw_arg arg;
    251     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    252     if (enabled) {
    253         arg.plane_enable_mask = 1;
    254     } else {
    255         arg.plane_disable_mask = 1;
    256     }
    257 
    258     if (mType == PLANE_SPRITE)
    259         arg.plane.type = DC_SPRITE_PLANE;
    260     else
    261         arg.plane.type = DC_PRIMARY_PLANE;
    262 
    263     arg.plane.index = mIndex;
    264     arg.plane.ctx = 0;
    265 
    266     // issue ioctl
    267     Drm *drm = Hwcomposer::getInstance().getDrm();
    268     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    269     if (ret == false) {
    270         WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
    271         return false;
    272     }
    273 
    274     return true;
    275 }
    276 
    277 bool AnnRGBPlane::isDisabled()
    278 {
    279     RETURN_FALSE_IF_NOT_INIT();
    280 
    281     struct drm_psb_register_rw_arg arg;
    282     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    283 
    284     if (mType == PLANE_SPRITE)
    285         arg.plane.type = DC_SPRITE_PLANE;
    286     else
    287         arg.plane.type = DC_PRIMARY_PLANE;
    288 
    289     arg.get_plane_state_mask = 1;
    290     arg.plane.index = mIndex;
    291     arg.plane.ctx = 0;
    292 
    293     // issue ioctl
    294     Drm *drm = Hwcomposer::getInstance().getDrm();
    295     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    296     if (ret == false) {
    297         WLOGTRACE("plane state query failed with error code %d", ret);
    298         return false;
    299     }
    300 
    301     return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
    302 }
    303 
    304 void AnnRGBPlane::postFlip()
    305 {
    306     // prevent mUpdateMasks from being reset
    307     // skipping flip may cause flicking
    308 }
    309 
    310 void AnnRGBPlane::setFramebufferTarget(uint32_t handle)
    311 {
    312     uint32_t stride;
    313     uint32_t planeAlpha;
    314 
    315     CTRACE();
    316 
    317     // do not need to update the buffer handle
    318     if (mCurrentDataBuffer != handle)
    319         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    320     else
    321         mUpdateMasks &= ~PLANE_BUFFER_CHANGED;
    322 
    323     // if no update then do Not need set data buffer
    324     if (!mUpdateMasks)
    325         return;
    326 
    327     // don't need to map data buffer for primary plane
    328     if (mType == PLANE_SPRITE)
    329         mContext.type = DC_SPRITE_PLANE;
    330     else
    331         mContext.type = DC_PRIMARY_PLANE;
    332 
    333     stride = align_to((4 * align_to(mPosition.w, 32)), 64);
    334 
    335     if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
    336        planeAlpha = mPlaneAlpha | 0x80000000;
    337     } else {
    338        // disable plane alpha to offload HW
    339        planeAlpha = 0xff;
    340     }
    341 
    342     // FIXME: use sprite context for sprite plane
    343     mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL;
    344     mContext.ctx.prim_ctx.index = mIndex;
    345     mContext.ctx.prim_ctx.pipe = mDevice;
    346 
    347     if (mPanelOrientation == PANEL_ORIENTATION_180)
    348         mContext.ctx.prim_ctx.linoff = (mPosition.h  - 1) * stride + (mPosition.w - 1) * 4;
    349     else
    350         mContext.ctx.prim_ctx.linoff = 0;
    351 
    352     mContext.ctx.prim_ctx.stride = stride;
    353     mContext.ctx.prim_ctx.tileoff = 0;
    354     mContext.ctx.prim_ctx.pos = 0;
    355     mContext.ctx.prim_ctx.size =
    356         ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff);
    357     mContext.ctx.prim_ctx.surf = 0;
    358     mContext.ctx.prim_ctx.contalpa = planeAlpha;
    359     mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888;
    360     mContext.ctx.prim_ctx.cntr |= 0x80000000;
    361 
    362     // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    363     if (mBlending == HWC_BLENDING_COVERAGE) {
    364         mContext.ctx.prim_ctx.cntr |= (0x1 << 23);
    365     }
    366 
    367     if (mPanelOrientation == PANEL_ORIENTATION_180)
    368         mContext.ctx.prim_ctx.cntr |= (0x1 << 15);
    369 
    370     VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
    371           "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
    372           mContext.ctx.prim_ctx.cntr,
    373           mContext.ctx.prim_ctx.linoff,
    374           mContext.ctx.prim_ctx.stride,
    375           mContext.ctx.prim_ctx.surf,
    376           mContext.ctx.prim_ctx.pos,
    377           mContext.ctx.prim_ctx.size,
    378           mContext.ctx.sp_ctx.contalpa);
    379 
    380     mCurrentDataBuffer = handle;
    381 }
    382 
    383 } // namespace intel
    384 } // namespace android
    385