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