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 
     17 #include <math.h>
     18 #include <common/utils/HwcTrace.h>
     19 #include <common/base/Drm.h>
     20 #include <Hwcomposer.h>
     21 #include <ips/anniedale/AnnOverlayPlane.h>
     22 #include <ips/tangier/TngGrallocBuffer.h>
     23 #include <khronos/openmax/OMX_IntelVideoExt.h>
     24 #include <DisplayQuery.h>
     25 
     26 namespace android {
     27 namespace intel {
     28 
     29 AnnOverlayPlane::AnnOverlayPlane(int index, int disp)
     30     : OverlayPlaneBase(index, disp),
     31       mRotationBufProvider(NULL),
     32       mRotationConfig(0),
     33       mZOrderConfig(0),
     34       mUseOverlayRotation(true)
     35 {
     36     CTRACE();
     37 
     38     memset(&mContext, 0, sizeof(mContext));
     39 }
     40 
     41 AnnOverlayPlane::~AnnOverlayPlane()
     42 {
     43     CTRACE();
     44 }
     45 
     46 bool AnnOverlayPlane::setDataBuffer(uint32_t handle)
     47 {
     48     if (handle == 0) {
     49         ELOGTRACE("handle == 0");
     50         return true;
     51     }
     52 
     53     return DisplayPlane::setDataBuffer(handle);
     54 }
     55 
     56 void AnnOverlayPlane::setZOrderConfig(ZOrderConfig& /* zorderConfig */,
     57         void *nativeConfig)
     58 {
     59     int slot = (int)nativeConfig;
     60 
     61     CTRACE();
     62 
     63     switch (slot) {
     64     case 0:
     65         mZOrderConfig = 0;
     66         break;
     67     case 1:
     68         mZOrderConfig = (1 << 8);
     69         break;
     70     case 2:
     71         mZOrderConfig = (2 << 8);
     72         break;
     73     case 3:
     74         mZOrderConfig = (3 << 8);
     75         break;
     76     default:
     77         ELOGTRACE("Invalid overlay plane zorder %d", slot);
     78         return;
     79     }
     80 }
     81 
     82 bool AnnOverlayPlane::reset()
     83 {
     84     OverlayPlaneBase::reset();
     85     if (mRotationBufProvider) {
     86         mRotationBufProvider->reset();
     87     }
     88     return true;
     89 }
     90 
     91 bool AnnOverlayPlane::enable()
     92 {
     93     RETURN_FALSE_IF_NOT_INIT();
     94 
     95     // by default always use overlay rotation
     96     mUseOverlayRotation = true;
     97 
     98     if (mContext.ctx.ov_ctx.ovadd & (0x1 << 15))
     99         return true;
    100 
    101     mContext.ctx.ov_ctx.ovadd |= (0x1 << 15);
    102 
    103     // flush
    104     flush(PLANE_ENABLE);
    105 
    106     return true;
    107 }
    108 
    109 bool AnnOverlayPlane::disable()
    110 {
    111     RETURN_FALSE_IF_NOT_INIT();
    112 
    113     if (!(mContext.ctx.ov_ctx.ovadd & (0x1 << 15)))
    114         return true;
    115 
    116     mContext.ctx.ov_ctx.ovadd &= ~(0x1 << 15);
    117 
    118     mContext.ctx.ov_ctx.ovadd &= ~(0x300);
    119 
    120     mContext.ctx.ov_ctx.ovadd |= mPipeConfig;
    121 
    122     // flush
    123     flush(PLANE_DISABLE);
    124 
    125     return true;
    126 }
    127 
    128 void AnnOverlayPlane::postFlip()
    129 {
    130     // when using AnnOverlayPlane through AnnDisplayPlane as proxy, postFlip is never
    131     // called so mUpdateMasks is never reset.
    132     // When using AnnOverlayPlane directly, postFlip is invoked and mUpdateMasks is reset
    133     // post-flip.
    134 
    135     // need to check why mUpdateMasks = 0 causes video freeze.
    136 
    137     //DisplayPlane::postFlip();
    138 }
    139 
    140 
    141 void AnnOverlayPlane::resetBackBuffer(int buf)
    142 {
    143     CTRACE();
    144 
    145     if (!mBackBuffer[buf] || !mBackBuffer[buf]->buf)
    146         return;
    147 
    148     OverlayBackBufferBlk *backBuffer = mBackBuffer[buf]->buf;
    149 
    150     memset(backBuffer, 0, sizeof(OverlayBackBufferBlk));
    151 
    152     // reset overlay
    153     backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
    154                          (OVERLAY_INIT_BRIGHTNESS & 0xff);
    155     backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
    156     backBuffer->DCLRKV = OVERLAY_INIT_COLORKEY;
    157     backBuffer->DCLRKM = OVERLAY_INIT_COLORKEYMASK;
    158     backBuffer->OCONFIG = 0;
    159     backBuffer->OCONFIG |= (0x1 << 27);
    160     // use 3 line buffers
    161     backBuffer->OCONFIG |= 0x1;
    162     backBuffer->SCHRKEN &= ~(0x7 << 24);
    163     backBuffer->SCHRKEN |= 0xff;
    164 }
    165 
    166 bool AnnOverlayPlane::bufferOffsetSetup(BufferMapper& mapper)
    167 {
    168     CTRACE();
    169 
    170     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
    171     if (!backBuffer) {
    172         ELOGTRACE("invalid back buffer");
    173         return false;
    174     }
    175 
    176     uint32_t format = mapper.getFormat();
    177     uint32_t gttOffsetInBytes = (mapper.getGttOffsetInPage(0) << 12);
    178     uint32_t yStride = mapper.getStride().yuv.yStride;
    179     uint32_t uvStride = mapper.getStride().yuv.uvStride;
    180     uint32_t h = mapper.getHeight();
    181     uint32_t srcX= mapper.getCrop().x;
    182     uint32_t srcY= mapper.getCrop().y;
    183     uint32_t ySurface, uSurface, vSurface;
    184     uint32_t yTileOffsetX, yTileOffsetY;
    185     uint32_t uTileOffsetX, uTileOffsetY;
    186     uint32_t vTileOffsetX, vTileOffsetY;
    187 
    188     if (format == HAL_PIXEL_FORMAT_BGRX_8888 ||
    189         format == HAL_PIXEL_FORMAT_BGRA_8888) {
    190         // set source format XRGB
    191         backBuffer->OCMD = OVERLAY_FORMAT_PLANAR_XRGB;
    192         // by pass YUV->RGB conversion, 8-bit output
    193         backBuffer->OCONFIG |= OVERLAY_CONFIG_BYPASS_DISABLE;
    194         backBuffer->OSTART_0Y = gttOffsetInBytes;
    195         backBuffer->OBUF_0Y = srcX * XRGB_BPP + srcY *
    196             mapper.getStride().rgb.stride;
    197         return true;
    198     }
    199 
    200     // clear original format setting
    201     backBuffer->OCMD &= ~(0xf << 10);
    202     backBuffer->OCMD &= ~OVERLAY_MEMORY_LAYOUT_TILED;
    203 
    204     backBuffer->OBUF_0Y = 0;
    205     backBuffer->OBUF_0V = 0;
    206     backBuffer->OBUF_0U = 0;
    207     // Y/U/V plane must be 4k bytes aligned.
    208     ySurface = gttOffsetInBytes;
    209     if (mIsProtectedBuffer) {
    210         // temporary workaround until vsync event logic is corrected.
    211         // it seems that overlay buffer update and renderring can be overlapped,
    212         // as such encryption bit may be cleared during HW rendering
    213         ySurface |= 0x01;
    214     }
    215 
    216     switch(format) {
    217     case HAL_PIXEL_FORMAT_YV12:    // YV12
    218         vSurface = ySurface + yStride * h;
    219         uSurface = vSurface + uvStride * (h / 2);
    220         yTileOffsetX = srcX;
    221         yTileOffsetY = srcY;
    222         uTileOffsetX = srcX / 2;
    223         uTileOffsetY = srcY / 2;
    224         vTileOffsetX = uTileOffsetX;
    225         vTileOffsetY = uTileOffsetY;
    226         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
    227         break;
    228     case HAL_PIXEL_FORMAT_INTEL_YV12:    // INTEL_YV12
    229         // The height of HAL_PIXEL_FORMAT_INTEL_YV12 gralloc buffer has been aligned with 32 pixels.
    230         vSurface = ySurface + yStride * align_to(h, 32);
    231         uSurface = vSurface + uvStride * (align_to(h, 32) / 2);
    232         yTileOffsetX = srcX;
    233         yTileOffsetY = srcY;
    234         uTileOffsetX = srcX / 2;
    235         uTileOffsetY = srcY / 2;
    236         vTileOffsetX = uTileOffsetX;
    237         vTileOffsetY = uTileOffsetY;
    238         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
    239         break;
    240     case HAL_PIXEL_FORMAT_I420:    // I420
    241         uSurface = ySurface + yStride * h;
    242         vSurface = uSurface + uvStride * (h / 2);
    243         yTileOffsetX = srcX;
    244         yTileOffsetY = srcY;
    245         uTileOffsetX = srcX / 2;
    246         uTileOffsetY = srcY / 2;
    247         vTileOffsetX = uTileOffsetX;
    248         vTileOffsetY = uTileOffsetY;
    249         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
    250         break;
    251     case HAL_PIXEL_FORMAT_NV12:    // NV12
    252         uSurface = ySurface;
    253         vSurface = ySurface;
    254         backBuffer->OBUF_0U = yStride * h;
    255         yTileOffsetX = srcX;
    256         yTileOffsetY = srcY;
    257         uTileOffsetX = srcX / 2;
    258         uTileOffsetY = srcY / 2 + h;
    259         vTileOffsetX = uTileOffsetX;
    260         vTileOffsetY = uTileOffsetY;
    261         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    262         break;
    263     // NOTE: this is the decoded video format, align the height to 32B
    264     //as it's defined by video driver
    265     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:    // NV12
    266         uSurface = ySurface + yStride * align_to(h, 32);
    267         vSurface = ySurface + yStride * align_to(h, 32);
    268         yTileOffsetX = srcX;
    269         yTileOffsetY = srcY;
    270         uTileOffsetX = srcX;
    271         uTileOffsetY = srcY / 2;
    272         vTileOffsetX = uTileOffsetX;
    273         vTileOffsetY = uTileOffsetY;
    274         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    275         break;
    276     case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:  //NV12_tiled
    277         uSurface = ySurface + yStride * align_to(h, 32);
    278         vSurface = ySurface + yStride * align_to(h, 32);
    279         yTileOffsetX = srcX;
    280         yTileOffsetY = srcY;
    281         uTileOffsetX = srcX;
    282         uTileOffsetY = srcY / 2;
    283         vTileOffsetX = uTileOffsetX;
    284         vTileOffsetY = uTileOffsetY;
    285         backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
    286         backBuffer->OCMD |= OVERLAY_MEMORY_LAYOUT_TILED;
    287         break;
    288     case HAL_PIXEL_FORMAT_YUY2:    // YUY2
    289         uSurface = ySurface;
    290         vSurface = ySurface;
    291         yTileOffsetX = srcX;
    292         yTileOffsetY = srcY;
    293         uTileOffsetX = yTileOffsetX;
    294         uTileOffsetY = yTileOffsetY;
    295         vTileOffsetX = yTileOffsetX;
    296         vTileOffsetY = yTileOffsetY;
    297         backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
    298         backBuffer->OCMD |= OVERLAY_PACKED_ORDER_YUY2;
    299         break;
    300     case HAL_PIXEL_FORMAT_UYVY:    // UYVY
    301         uSurface = ySurface;
    302         vSurface = ySurface;
    303         yTileOffsetX = srcX;
    304         yTileOffsetY = srcY;
    305         uTileOffsetX = yTileOffsetX;
    306         uTileOffsetY = yTileOffsetY;
    307         vTileOffsetX = yTileOffsetX;
    308         vTileOffsetY = yTileOffsetY;
    309         backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
    310         backBuffer->OCMD |= OVERLAY_PACKED_ORDER_UYVY;
    311         break;
    312     default:
    313         ELOGTRACE("unsupported format %d", format);
    314         return false;
    315     }
    316 
    317     backBuffer->OSTART_0Y = ySurface;
    318     backBuffer->OSTART_0U = uSurface;
    319     backBuffer->OSTART_0V = vSurface;
    320     backBuffer->OBUF_0Y += srcY * yStride + srcX;
    321     backBuffer->OBUF_0V += (srcY / 2) * uvStride + srcX;
    322     backBuffer->OBUF_0U += (srcY / 2) * uvStride + srcX;
    323     backBuffer->OTILEOFF_0Y = yTileOffsetY << 16 | yTileOffsetX;
    324     backBuffer->OTILEOFF_0U = uTileOffsetY << 16 | uTileOffsetX;
    325     backBuffer->OTILEOFF_0V = vTileOffsetY << 16 | vTileOffsetX;
    326 
    327     VLOGTRACE("done. offset (%d, %d, %d)",
    328           backBuffer->OBUF_0Y,
    329           backBuffer->OBUF_0U,
    330           backBuffer->OBUF_0V);
    331 
    332     return true;
    333 }
    334 
    335 bool AnnOverlayPlane::coordinateSetup(BufferMapper& mapper)
    336 {
    337     CTRACE();
    338 
    339     uint32_t format = mapper.getFormat();
    340     if (format != HAL_PIXEL_FORMAT_BGRX_8888 &&
    341         format != HAL_PIXEL_FORMAT_BGRA_8888) {
    342         return OverlayPlaneBase::coordinateSetup(mapper);
    343     }
    344 
    345     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
    346     if (!backBuffer) {
    347         ELOGTRACE("invalid back buffer");
    348         return false;
    349     }
    350 
    351     backBuffer->SWIDTH = mapper.getCrop().w;
    352     backBuffer->SHEIGHT = mapper.getCrop().h;
    353     backBuffer->OSTRIDE = mapper.getStride().rgb.stride;
    354     backBuffer->SWIDTHSW = calculateSWidthSW(backBuffer->OBUF_0Y,
    355             backBuffer->OSTRIDE) << 2;
    356     return true;
    357 };
    358 
    359 bool AnnOverlayPlane::scalingSetup(BufferMapper& mapper)
    360 {
    361     int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
    362     int xscaleIntUV, xscaleFractUV;
    363     int yscaleIntUV, yscaleFractUV;
    364     // UV is half the size of Y -- YUV420
    365     int uvratio = 2;
    366     uint32_t newval;
    367     coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES];
    368     coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES];
    369     coeffRec ycoeffY[N_VERT_Y_TAPS * N_PHASES];
    370     coeffRec ycoeffUV[N_VERT_UV_TAPS * N_PHASES];
    371     int i, j, pos;
    372     bool scaleChanged = false;
    373     int x, y, w, h;
    374     int deinterlace_factor = 1;
    375     drmModeModeInfoPtr mode = &mModeInfo;
    376 
    377     OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
    378     if (!backBuffer) {
    379         ELOGTRACE("invalid back buffer");
    380         return false;
    381     }
    382 
    383     if (mPanelOrientation == PANEL_ORIENTATION_180) {
    384         if (mode->hdisplay)
    385             x = mode->hdisplay - mPosition.x - mPosition.w;
    386         else
    387             x = mPosition.x;
    388         if (mode->vdisplay)
    389             y = mode->vdisplay - mPosition.y - mPosition.h;
    390         else
    391             y = mPosition.y;
    392     } else {
    393         x = mPosition.x;
    394         y = mPosition.y;
    395     }
    396 
    397     w = mPosition.w;
    398     h = mPosition.h;
    399 
    400     // check position
    401     checkPosition(x, y, w, h);
    402     VLOGTRACE("final position (%d, %d, %d, %d)", x, y, w, h);
    403 
    404     if ((w <= 0) || (h <= 0)) {
    405          ELOGTRACE("invalid dst width/height");
    406          return false;
    407     }
    408 
    409     // setup dst position
    410     backBuffer->DWINPOS = (y << 16) | x;
    411     backBuffer->DWINSZ = (h << 16) | w;
    412 
    413     uint32_t srcWidth = mapper.getCrop().w;
    414     uint32_t srcHeight = mapper.getCrop().h;
    415     uint32_t dstWidth = w;
    416     uint32_t dstHeight = h;
    417     uint32_t format = mapper.getFormat();
    418 
    419     if (mBobDeinterlace && !mTransform)
    420         deinterlace_factor = 2;
    421 
    422     VLOGTRACE("src (%dx%d), dst (%dx%d), transform %d",
    423           srcWidth, srcHeight,
    424           dstWidth, dstHeight,
    425           mTransform);
    426 
    427     if (mBobDeinterlace) {
    428         float scaleY = (float)(srcHeight >> 1) / dstHeight;
    429         if (scaleY > 4 || scaleY < 0.25) {
    430             VLOGTRACE("Exceed scale limit for interlace, return false");
    431             return false;
    432         }
    433     }
    434 
    435     // switch destination width/height for scale factor calculation
    436     // for 90/270 transformation
    437     if (mUseOverlayRotation && ((mTransform == HWC_TRANSFORM_ROT_90) ||
    438         (mTransform == HWC_TRANSFORM_ROT_270))) {
    439         uint32_t tmp = srcHeight;
    440         srcHeight = srcWidth;
    441         srcWidth = tmp;
    442     }
    443 
    444     if (format == HAL_PIXEL_FORMAT_BGRX_8888 ||
    445             format == HAL_PIXEL_FORMAT_BGRA_8888)
    446         uvratio = 1;
    447 
    448      // Y down-scale factor as a multiple of 4096
    449     if (srcWidth == dstWidth && srcHeight == dstHeight) {
    450         xscaleFract = (1 << 12);
    451         yscaleFract = (1 << 12) / deinterlace_factor;
    452     } else {
    453         xscaleFract = ((srcWidth - 1) << 12) / dstWidth;
    454         yscaleFract = ((srcHeight - 1) << 12) / (dstHeight * deinterlace_factor);
    455     }
    456 
    457     // Calculate the UV scaling factor
    458     xscaleFractUV = xscaleFract / uvratio;
    459     yscaleFractUV = yscaleFract / uvratio;
    460 
    461 
    462     // To keep the relative Y and UV ratios exact, round the Y scales
    463     // to a multiple of the Y/UV ratio.
    464     xscaleFract = xscaleFractUV * uvratio;
    465     yscaleFract = yscaleFractUV * uvratio;
    466 
    467     // Integer (un-multiplied) values
    468     xscaleInt = xscaleFract >> 12;
    469     yscaleInt = yscaleFract >> 12;
    470 
    471     xscaleIntUV = xscaleFractUV >> 12;
    472     yscaleIntUV = yscaleFractUV >> 12;
    473 
    474     // Check scaling ratio
    475     if (xscaleInt > INTEL_OVERLAY_MAX_SCALING_RATIO) {
    476         ELOGTRACE("xscaleInt > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
    477         return false;
    478     }
    479 
    480     // shouldn't get here
    481     if (xscaleIntUV > INTEL_OVERLAY_MAX_SCALING_RATIO) {
    482         ELOGTRACE("xscaleIntUV > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
    483         return false;
    484     }
    485 
    486     newval = (xscaleInt << 15) |
    487     ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
    488     if (newval != backBuffer->YRGBSCALE) {
    489         scaleChanged = true;
    490         backBuffer->YRGBSCALE = newval;
    491     }
    492 
    493     newval = (xscaleIntUV << 15) | ((xscaleFractUV & 0xFFF) << 3) |
    494     ((yscaleFractUV & 0xFFF) << 20);
    495     if (newval != backBuffer->UVSCALE) {
    496         scaleChanged = true;
    497         backBuffer->UVSCALE = newval;
    498     }
    499 
    500     newval = yscaleInt << 16 | yscaleIntUV;
    501     if (newval != backBuffer->UVSCALEV) {
    502         scaleChanged = true;
    503         backBuffer->UVSCALEV = newval;
    504     }
    505 
    506     // Recalculate coefficients if the scaling changed
    507     // Only Horizontal coefficients so far.
    508     if (scaleChanged) {
    509         double fHCutoffY;
    510         double fHCutoffUV;
    511         double fVCutoffY;
    512         double fVCutoffUV;
    513 
    514         fHCutoffY = xscaleFract / 4096.0;
    515         fHCutoffUV = xscaleFractUV / 4096.0;
    516         fVCutoffY = yscaleFract / 4096.0;
    517         fVCutoffUV = yscaleFractUV / 4096.0;
    518 
    519         // Limit to between 1.0 and 3.0
    520         if (fHCutoffY < MIN_CUTOFF_FREQ)
    521             fHCutoffY = MIN_CUTOFF_FREQ;
    522         if (fHCutoffY > MAX_CUTOFF_FREQ)
    523             fHCutoffY = MAX_CUTOFF_FREQ;
    524         if (fHCutoffUV < MIN_CUTOFF_FREQ)
    525             fHCutoffUV = MIN_CUTOFF_FREQ;
    526         if (fHCutoffUV > MAX_CUTOFF_FREQ)
    527             fHCutoffUV = MAX_CUTOFF_FREQ;
    528 
    529         if (fVCutoffY < MIN_CUTOFF_FREQ)
    530             fVCutoffY = MIN_CUTOFF_FREQ;
    531         if (fVCutoffY > MAX_CUTOFF_FREQ)
    532             fVCutoffY = MAX_CUTOFF_FREQ;
    533         if (fVCutoffUV < MIN_CUTOFF_FREQ)
    534             fVCutoffUV = MIN_CUTOFF_FREQ;
    535         if (fVCutoffUV > MAX_CUTOFF_FREQ)
    536             fVCutoffUV = MAX_CUTOFF_FREQ;
    537 
    538         updateCoeff(N_HORIZ_Y_TAPS, fHCutoffY, true, true, xcoeffY);
    539         updateCoeff(N_HORIZ_UV_TAPS, fHCutoffUV, true, false, xcoeffUV);
    540         updateCoeff(N_VERT_Y_TAPS, fVCutoffY, false, true, ycoeffY);
    541         updateCoeff(N_VERT_UV_TAPS, fVCutoffUV, false, false, ycoeffUV);
    542 
    543         for (i = 0; i < N_PHASES; i++) {
    544             for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
    545                 pos = i * N_HORIZ_Y_TAPS + j;
    546                 backBuffer->Y_HCOEFS[pos] =
    547                         (xcoeffY[pos].sign << 15 |
    548                          xcoeffY[pos].exponent << 12 |
    549                          xcoeffY[pos].mantissa);
    550             }
    551         }
    552         for (i = 0; i < N_PHASES; i++) {
    553             for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
    554                 pos = i * N_HORIZ_UV_TAPS + j;
    555                 backBuffer->UV_HCOEFS[pos] =
    556                          (xcoeffUV[pos].sign << 15 |
    557                           xcoeffUV[pos].exponent << 12 |
    558                           xcoeffUV[pos].mantissa);
    559             }
    560         }
    561 
    562         for (i = 0; i < N_PHASES; i++) {
    563             for (j = 0; j < N_VERT_Y_TAPS; j++) {
    564                 pos = i * N_VERT_Y_TAPS + j;
    565                 backBuffer->Y_VCOEFS[pos] =
    566                         (ycoeffY[pos].sign << 15 |
    567                          ycoeffY[pos].exponent << 12 |
    568                          ycoeffY[pos].mantissa);
    569             }
    570         }
    571         for (i = 0; i < N_PHASES; i++) {
    572             for (j = 0; j < N_VERT_UV_TAPS; j++) {
    573                 pos = i * N_VERT_UV_TAPS + j;
    574                 backBuffer->UV_VCOEFS[pos] =
    575                          (ycoeffUV[pos].sign << 15 |
    576                           ycoeffUV[pos].exponent << 12 |
    577                           ycoeffUV[pos].mantissa);
    578             }
    579         }
    580     }
    581 
    582     XLOGTRACE();
    583     return true;
    584 }
    585 
    586 void AnnOverlayPlane::setTransform(int transform)
    587 {
    588     RETURN_VOID_IF_NOT_INIT();
    589 
    590     if (mPanelOrientation == PANEL_ORIENTATION_180)
    591        transform ^=  HWC_TRANSFORM_ROT_180;
    592 
    593     DisplayPlane::setTransform(transform);
    594 
    595     // setup transform config
    596     switch (mTransform) {
    597     case HWC_TRANSFORM_ROT_90:
    598         mRotationConfig = (0x1 << 10);
    599         break;
    600     case HWC_TRANSFORM_ROT_180:
    601         mRotationConfig = (0x2 << 10);
    602         break;
    603     case HWC_TRANSFORM_ROT_270:
    604         mRotationConfig = (0x3 << 10);
    605         break;
    606     case 0:
    607         mRotationConfig = 0;
    608         break;
    609     default:
    610         ELOGTRACE("Invalid transform %d", mTransform);
    611         mRotationConfig = 0;
    612         break;
    613     }
    614 }
    615 
    616 // HSD 4645510:
    617 // This is a SOC limition, that when source buffer width range is
    618 // in (960, 1024] - one cache line length, and rotation bit is set
    619 // in portrait mode, video will show distortion.
    620 bool AnnOverlayPlane::isSettingRotBitAllowed()
    621 {
    622     uint32_t width = mSrcCrop.w;
    623 
    624     if ((width > 960 && width <= 1024) &&
    625             (mTransform == 0 || mTransform == HAL_TRANSFORM_ROT_180))
    626         return false;
    627     return true;
    628 }
    629 
    630 bool AnnOverlayPlane::flip(void *ctx)
    631 {
    632     uint32_t ovadd = 0;
    633 
    634     RETURN_FALSE_IF_NOT_INIT();
    635 
    636     if (!DisplayPlane::flip(ctx)) {
    637         ELOGTRACE("failed to flip display plane.");
    638         return false;
    639     }
    640 
    641     // update back buffer address
    642     ovadd = (mBackBuffer[mCurrent]->gttOffsetInPage << 12);
    643 
    644     // enable rotation mode and setup rotation config
    645     if (mIndex == 0 && mRotationConfig != 0) {
    646         if (isSettingRotBitAllowed())
    647             ovadd |= (1 << 12);
    648         ovadd |= mRotationConfig;
    649     }
    650 
    651     // setup z-order config
    652     ovadd |= mZOrderConfig;
    653 
    654     // load coefficients
    655     ovadd |= 0x1;
    656 
    657     // enable overlay
    658     ovadd |= (1 << 15);
    659 
    660     mContext.type = DC_OVERLAY_PLANE;
    661     mContext.ctx.ov_ctx.ovadd = ovadd;
    662     mContext.ctx.ov_ctx.index = mIndex;
    663     mContext.ctx.ov_ctx.pipe = mDevice;
    664     mContext.ctx.ov_ctx.ovadd |= mPipeConfig;
    665 
    666     // move to next back buffer
    667     mCurrent = (mCurrent + 1) % OVERLAY_BACK_BUFFER_COUNT;
    668 
    669     VLOGTRACE("ovadd = %#x, index = %d, device = %d",
    670           mContext.ctx.ov_ctx.ovadd,
    671           mIndex,
    672           mDevice);
    673 
    674     return true;
    675 }
    676 
    677 void* AnnOverlayPlane::getContext() const
    678 {
    679     CTRACE();
    680     return (void *)&mContext;
    681 }
    682 
    683 bool AnnOverlayPlane::setDataBuffer(BufferMapper& mapper)
    684 {
    685     if (mIsProtectedBuffer) {
    686         // workaround overlay scaling limitation
    687         float scaleX = (float)mSrcCrop.w/mPosition.w;
    688         float scaleY = (float)mSrcCrop.h/mPosition.h;
    689         if (scaleX > 4.0) {
    690             int crop = (mSrcCrop.w - 4 * mPosition.w)/2 + 1;
    691             mSrcCrop.x += crop;
    692             mSrcCrop.w -= 2 * crop;
    693         }
    694 
    695         if (scaleY > 4.0) {
    696             int crop = (mSrcCrop.h - 4 * mPosition.h)/2 + 1;
    697             mSrcCrop.y += crop;
    698             mSrcCrop.h -= 2 * crop;
    699         }
    700 
    701         if (scaleX > 4.0 || scaleY > 4.0) {
    702             mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
    703             mapper.setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
    704         }
    705     }
    706 
    707 
    708     if (OverlayPlaneBase::setDataBuffer(mapper) == false) {
    709         return false;
    710     }
    711 
    712     signalVideoRotation(mapper);
    713 
    714     if (mIsProtectedBuffer) {
    715         // Bit 0: Decryption request, only allowed to change on a synchronous flip
    716         // This request will be qualified with the separate decryption enable bit for OV
    717         mBackBuffer[mCurrent]->buf->OSTART_0Y |= 0x1;
    718         mBackBuffer[mCurrent]->buf->OSTART_1Y |= 0x1;
    719     }
    720     return true;
    721 }
    722 
    723 bool AnnOverlayPlane::initialize(uint32_t bufferCount)
    724 {
    725     if (!OverlayPlaneBase::initialize(bufferCount)) {
    726         ELOGTRACE("failed to initialize OverlayPlaneBase");
    727         return false;
    728     }
    729 
    730     // setup rotation buffer
    731     mRotationBufProvider = new RotationBufferProvider(mWsbm);
    732     if (!mRotationBufProvider || !mRotationBufProvider->initialize()) {
    733         DEINIT_AND_RETURN_FALSE("failed to initialize RotationBufferProvider");
    734     }
    735     return true;
    736 }
    737 
    738 void AnnOverlayPlane::deinitialize()
    739 {
    740     DEINIT_AND_DELETE_OBJ(mRotationBufProvider);
    741     OverlayPlaneBase::deinitialize();
    742 }
    743 
    744 bool AnnOverlayPlane::rotatedBufferReady(BufferMapper& mapper, BufferMapper* &rotatedMapper)
    745 {
    746     struct VideoPayloadBuffer *payload;
    747     uint32_t format;
    748     // only NV12_VED has rotated buffer
    749     format = mapper.getFormat();
    750     if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
    751         format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
    752         ELOGTRACE("invalid video format %#x", format);
    753         return false;
    754     }
    755 
    756     payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
    757     // check payload
    758     if (!payload) {
    759         ELOGTRACE("no payload found");
    760         return false;
    761     }
    762 
    763     if (payload->force_output_method == FORCE_OUTPUT_GPU) {
    764         ELOGTRACE("Output method is not supported!");
    765         return false;
    766     }
    767 
    768     if (payload->client_transform != mTransform ||
    769         mBobDeinterlace) {
    770         if (!mRotationBufProvider->setupRotationBuffer(payload, mTransform)) {
    771             DLOGTRACE("failed to setup rotation buffer");
    772             return false;
    773         }
    774     }
    775 
    776     rotatedMapper = getTTMMapper(mapper, payload);
    777     return true;
    778 }
    779 
    780 void AnnOverlayPlane::signalVideoRotation(BufferMapper& mapper)
    781 {
    782     struct VideoPayloadBuffer *payload;
    783     uint32_t format;
    784 
    785     // check if it's video layer
    786     format = mapper.getFormat();
    787     if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
    788         format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
    789         return;
    790     }
    791 
    792     payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
    793     if (!payload) {
    794         ELOGTRACE("no payload found");
    795         return;
    796     }
    797 
    798     /* if use overlay rotation, signal decoder to stop rotation */
    799     if (mUseOverlayRotation) {
    800         if (payload->client_transform) {
    801             WLOGTRACE("signal decoder to stop generate rotation buffer");
    802             payload->hwc_timestamp = systemTime();
    803             payload->layer_transform = 0;
    804         }
    805     } else {
    806         /* if overlay rotation cannot be used, signal decoder to start rotation */
    807         if (payload->client_transform != mTransform) {
    808             WLOGTRACE("signal decoder to generate rotation buffer with transform %d", mTransform);
    809             payload->hwc_timestamp = systemTime();
    810             payload->layer_transform = mTransform;
    811         }
    812     }
    813 }
    814 
    815 bool AnnOverlayPlane::useOverlayRotation(BufferMapper& /* mapper */)
    816 {
    817     if (mTransform == 0)
    818         return true;
    819 
    820     if (!isSettingRotBitAllowed()) {
    821         mUseOverlayRotation = false;
    822         mRotationConfig = 0;
    823         return false;
    824     }
    825 
    826     // workaround limitation of overlay rotation by falling back to use VA rotated buffer
    827     bool fallback = false;
    828     float scaleX = (float)mSrcCrop.w / mPosition.w;
    829     float scaleY = (float)mSrcCrop.h / mPosition.h;
    830     if (mTransform == HAL_TRANSFORM_ROT_270 || mTransform == HAL_TRANSFORM_ROT_90) {
    831         scaleX = (float)mSrcCrop.w / mPosition.h;
    832         scaleY = (float)mSrcCrop.h / mPosition.w;
    833     }
    834     if (scaleX >= 3 || scaleY >= 3 || scaleX < 1.0/3 || scaleY < 1.0/3) {
    835         if (mUseOverlayRotation) {
    836             DLOGTRACE("overlay rotation with scaling >= 3, use VA rotated buffer");
    837         }
    838         fallback = true;
    839     } else if ((int)mSrcCrop.x & 63) {
    840         if (mUseOverlayRotation) {
    841             DLOGTRACE("offset is not 64 bytes aligned, use VA rotated buffer");
    842         }
    843         fallback = true;
    844     }
    845 #if 0
    846     else if (mTransform != HAL_TRANSFORM_ROT_180 && scaleX != scaleY) {
    847         if (mUseOverlayRotation) {
    848             DLOGTRACE("overlay rotation with uneven scaling, use VA rotated buffer");
    849         }
    850         fallback = true;
    851     }
    852 #endif
    853 
    854     // per DC spec, if video is 1080(H)x1920(V), the buffer
    855     // need 1920 of 64-pixel strip if using hw rotation.
    856     // fallback to video ration buffer in such case.
    857     if (mSrcCrop.w == 1080 && mSrcCrop.h == 1920 && mTransform != 0) {
    858         DLOGTRACE("1080(H)x1920(V) cannot use hw rotation, use VA rotated buffer");
    859         fallback = true;
    860     }
    861 
    862     if (fallback || mBobDeinterlace) {
    863         mUseOverlayRotation = false;
    864         mRotationConfig = 0;
    865     } else {
    866         mUseOverlayRotation = true;
    867     }
    868     return mUseOverlayRotation;
    869 }
    870 
    871 bool AnnOverlayPlane::flush(uint32_t flags)
    872 {
    873     RETURN_FALSE_IF_NOT_INIT();
    874     ALOGTRACE("flags = %#x, type = %d, index = %d", flags, mType, mIndex);
    875 
    876     if (!(flags & PLANE_ENABLE) && !(flags & PLANE_DISABLE)) {
    877         ELOGTRACE("invalid flush flags.");
    878         return false;
    879     }
    880 
    881     struct drm_psb_register_rw_arg arg;
    882     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    883 
    884     if (flags & PLANE_DISABLE)
    885         arg.plane_disable_mask = 1;
    886     else if (flags & PLANE_ENABLE)
    887         arg.plane_enable_mask = 1;
    888 
    889     arg.plane.type = DC_OVERLAY_PLANE;
    890     arg.plane.index = mIndex;
    891     arg.plane.ctx = mContext.ctx.ov_ctx.ovadd;
    892     if (flags & PLANE_DISABLE) {
    893         DLOGTRACE("disabling overlay %d on device %d", mIndex, mDevice);
    894     }
    895 
    896     // issue ioctl
    897     Drm *drm = Hwcomposer::getInstance().getDrm();
    898     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    899     if (ret == false) {
    900         WLOGTRACE("overlay update failed with error code %d", ret);
    901         return false;
    902     }
    903 
    904     return true;
    905 }
    906 
    907 } // namespace intel
    908 } // namespace android
    909