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 
    109             if (mScalingBufferMap.size() >= MAX_SCALING_BUF_COUNT) {
    110                 while (!mScalingBufferMap.isEmpty()) {
    111                     uint32_t handle = mScalingBufferMap.valueAt(0);
    112                     bm->freeGrallocBuffer(handle);
    113                     mScalingBufferMap.removeItemsAt(0);
    114                 }
    115             }
    116 
    117             mScalingBufferMap.add(handle, mScalingTarget);
    118         } else {
    119             mScalingTarget = mScalingBufferMap.valueAt(index);
    120         }
    121         mScalingSource = handle;
    122         handle = mScalingTarget;
    123     }
    124 
    125     TngGrallocBuffer tmpBuf(handle);
    126     uint32_t usage;
    127     bool ret;
    128 
    129     ALOGTRACE("handle = %#x", handle);
    130 
    131     usage = tmpBuf.getUsage();
    132     if (GRALLOC_USAGE_HW_FB & usage) {
    133         setFramebufferTarget(handle);
    134         return true;
    135     }
    136 
    137     // use primary as a sprite
    138     ret = DisplayPlane::setDataBuffer(handle);
    139     if (ret == false) {
    140         ELOGTRACE("failed to set data buffer");
    141         return ret;
    142     }
    143 
    144     return true;
    145 }
    146 
    147 bool AnnRGBPlane::setDataBuffer(BufferMapper& mapper)
    148 {
    149     int bpp;
    150     int srcX, srcY, srcW, srcH;
    151     int dstX, dstY, dstW, dstH;
    152     uint32_t spriteFormat;
    153     uint32_t stride;
    154     uint32_t linoff;
    155     uint32_t planeAlpha;
    156     drmModeModeInfoPtr mode = &mModeInfo;
    157 
    158     CTRACE();
    159 
    160     // setup plane position
    161     dstX = mPosition.x;
    162     dstY = mPosition.y;
    163     dstW = mPosition.w;
    164     dstH = mPosition.h;
    165 
    166     checkPosition(dstX, dstY, dstW, dstH);
    167 
    168     // setup plane format
    169     if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) {
    170         ELOGTRACE("unsupported format %#x", mapper.getFormat());
    171         return false;
    172     }
    173 
    174     // setup stride and source buffer crop
    175     srcX = mapper.getCrop().x;
    176     srcY = mapper.getCrop().y;
    177     srcW = mapper.getWidth();
    178     srcH = mapper.getHeight();
    179     stride = mapper.getStride().rgb.stride;
    180 
    181     if (mPanelOrientation == PANEL_ORIENTATION_180)
    182         linoff = srcY * stride + srcX * bpp + (mapper.getCrop().h  - 1) * stride + (mapper.getCrop().w - 1) * bpp;
    183     else
    184         linoff = srcY * stride + srcX * bpp;
    185 
    186     // unlikely happen, but still we need make sure linoff is valid
    187     if (linoff > (stride * mapper.getHeight())) {
    188         ELOGTRACE("invalid source crop");
    189         return false;
    190     }
    191 
    192     // update context
    193     if (mType == PLANE_SPRITE)
    194         mContext.type = DC_SPRITE_PLANE;
    195     else
    196         mContext.type = DC_PRIMARY_PLANE;
    197 
    198     // setup plane alpha
    199     if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
    200        planeAlpha = mPlaneAlpha | 0x80000000;
    201     } else {
    202        // disable plane alpha to offload HW
    203        planeAlpha = 0xff;
    204     }
    205 
    206     mContext.ctx.sp_ctx.index = mIndex;
    207     mContext.ctx.sp_ctx.pipe = mDevice;
    208     mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000;
    209     mContext.ctx.sp_ctx.linoff = linoff;
    210     mContext.ctx.sp_ctx.stride = stride;
    211 
    212     // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    213     if (mBlending == HWC_BLENDING_COVERAGE) {
    214         mContext.ctx.sp_ctx.cntr |= (0x1 << 23);
    215     }
    216 
    217     if (mPanelOrientation == PANEL_ORIENTATION_180)
    218         mContext.ctx.sp_ctx.cntr |= (0x1 << 15);
    219 
    220     if (mapper.isCompression()) {
    221         mContext.ctx.sp_ctx.stride = align_to(srcW, 32) * 4;
    222         mContext.ctx.sp_ctx.linoff = (align_to(srcW, 32) * srcH / 64) - 1;
    223         mContext.ctx.sp_ctx.tileoff = (srcY & 0xfff) << 16 | (srcX & 0xfff);
    224         mContext.ctx.sp_ctx.cntr |= (0x1 << 11);
    225     }
    226 
    227     mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
    228 
    229     if (mPanelOrientation == PANEL_ORIENTATION_180) {
    230         if (mode->vdisplay && mode->hdisplay)
    231             mContext.ctx.sp_ctx.pos = ((mode->vdisplay - dstY - dstH) & 0xfff) << 16 | ((mode->hdisplay - dstX - dstW) & 0xfff);
    232         else
    233             mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    234     } else {
    235         mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    236     }
    237 
    238     mContext.ctx.sp_ctx.size =
    239         ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff);
    240     mContext.ctx.sp_ctx.contalpa = planeAlpha;
    241     mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL;
    242 
    243     VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
    244           "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
    245           mContext.ctx.sp_ctx.cntr,
    246           mContext.ctx.sp_ctx.linoff,
    247           mContext.ctx.sp_ctx.stride,
    248           mContext.ctx.sp_ctx.surf,
    249           mContext.ctx.sp_ctx.pos,
    250           mContext.ctx.sp_ctx.size,
    251           mContext.ctx.sp_ctx.contalpa);
    252     return true;
    253 }
    254 
    255 bool AnnRGBPlane::enablePlane(bool enabled)
    256 {
    257     RETURN_FALSE_IF_NOT_INIT();
    258 
    259     struct drm_psb_register_rw_arg arg;
    260     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    261     if (enabled) {
    262         arg.plane_enable_mask = 1;
    263     } else {
    264         arg.plane_disable_mask = 1;
    265     }
    266 
    267     if (mType == PLANE_SPRITE)
    268         arg.plane.type = DC_SPRITE_PLANE;
    269     else
    270         arg.plane.type = DC_PRIMARY_PLANE;
    271 
    272     arg.plane.index = mIndex;
    273     arg.plane.ctx = 0;
    274 
    275     // issue ioctl
    276     Drm *drm = Hwcomposer::getInstance().getDrm();
    277     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    278     if (ret == false) {
    279         WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
    280         return false;
    281     }
    282 
    283     return true;
    284 }
    285 
    286 bool AnnRGBPlane::isDisabled()
    287 {
    288     RETURN_FALSE_IF_NOT_INIT();
    289 
    290     struct drm_psb_register_rw_arg arg;
    291     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    292 
    293     if (mType == PLANE_SPRITE)
    294         arg.plane.type = DC_SPRITE_PLANE;
    295     else
    296         arg.plane.type = DC_PRIMARY_PLANE;
    297 
    298     arg.get_plane_state_mask = 1;
    299     arg.plane.index = mIndex;
    300     arg.plane.ctx = 0;
    301 
    302     // issue ioctl
    303     Drm *drm = Hwcomposer::getInstance().getDrm();
    304     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    305     if (ret == false) {
    306         WLOGTRACE("plane state query failed with error code %d", ret);
    307         return false;
    308     }
    309 
    310     return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
    311 }
    312 
    313 void AnnRGBPlane::postFlip()
    314 {
    315     // prevent mUpdateMasks from being reset
    316     // skipping flip may cause flicking
    317 }
    318 
    319 void AnnRGBPlane::setFramebufferTarget(uint32_t handle)
    320 {
    321     uint32_t stride;
    322     uint32_t planeAlpha;
    323 
    324     CTRACE();
    325 
    326     // do not need to update the buffer handle
    327     if (mCurrentDataBuffer != handle)
    328         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    329     else
    330         mUpdateMasks &= ~PLANE_BUFFER_CHANGED;
    331 
    332     // if no update then do Not need set data buffer
    333     if (!mUpdateMasks)
    334         return;
    335 
    336     // don't need to map data buffer for primary plane
    337     if (mType == PLANE_SPRITE)
    338         mContext.type = DC_SPRITE_PLANE;
    339     else
    340         mContext.type = DC_PRIMARY_PLANE;
    341 
    342     stride = align_to((4 * align_to(mPosition.w, 32)), 64);
    343 
    344     if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
    345        planeAlpha = mPlaneAlpha | 0x80000000;
    346     } else {
    347        // disable plane alpha to offload HW
    348        planeAlpha = 0xff;
    349     }
    350 
    351     // FIXME: use sprite context for sprite plane
    352     mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL;
    353     mContext.ctx.prim_ctx.index = mIndex;
    354     mContext.ctx.prim_ctx.pipe = mDevice;
    355 
    356     if (mPanelOrientation == PANEL_ORIENTATION_180)
    357         mContext.ctx.prim_ctx.linoff = (mPosition.h  - 1) * stride + (mPosition.w - 1) * 4;
    358     else
    359         mContext.ctx.prim_ctx.linoff = 0;
    360 
    361     mContext.ctx.prim_ctx.stride = stride;
    362     mContext.ctx.prim_ctx.tileoff = 0;
    363     mContext.ctx.prim_ctx.pos = 0;
    364     mContext.ctx.prim_ctx.size =
    365         ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff);
    366     mContext.ctx.prim_ctx.surf = 0;
    367     mContext.ctx.prim_ctx.contalpa = planeAlpha;
    368     mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888;
    369     mContext.ctx.prim_ctx.cntr |= 0x80000000;
    370 
    371     // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    372     if (mBlending == HWC_BLENDING_COVERAGE) {
    373         mContext.ctx.prim_ctx.cntr |= (0x1 << 23);
    374     }
    375 
    376     if (mPanelOrientation == PANEL_ORIENTATION_180)
    377         mContext.ctx.prim_ctx.cntr |= (0x1 << 15);
    378 
    379     VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
    380           "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
    381           mContext.ctx.prim_ctx.cntr,
    382           mContext.ctx.prim_ctx.linoff,
    383           mContext.ctx.prim_ctx.stride,
    384           mContext.ctx.prim_ctx.surf,
    385           mContext.ctx.prim_ctx.pos,
    386           mContext.ctx.prim_ctx.size,
    387           mContext.ctx.sp_ctx.contalpa);
    388 
    389     mCurrentDataBuffer = handle;
    390 }
    391 
    392 } // namespace intel
    393 } // namespace android
    394