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 <HwcTrace.h>
     18 #include <DisplayPlane.h>
     19 #include <hal_public.h>
     20 #include <OMX_IVCommon.h>
     21 #include <OMX_IntelVideoExt.h>
     22 #include <PlaneCapabilities.h>
     23 #include <common/OverlayHardware.h>
     24 #include <HwcLayer.h>
     25 #include <BufferManager.h>
     26 #include <Hwcomposer.h>
     27 
     28 
     29 #define SPRITE_PLANE_MAX_STRIDE_TILED      16384
     30 #define SPRITE_PLANE_MAX_STRIDE_LINEAR     16384
     31 
     32 #define OVERLAY_PLANE_MAX_STRIDE_PACKED    4096
     33 #define OVERLAY_PLANE_MAX_STRIDE_LINEAR    8192
     34 
     35 namespace android {
     36 namespace intel {
     37 
     38 bool PlaneCapabilities::isFormatSupported(int planeType, HwcLayer *hwcLayer)
     39 {
     40     uint32_t format = hwcLayer->getFormat();
     41     uint32_t trans = hwcLayer->getLayer()->transform;
     42 
     43     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
     44         switch (format) {
     45         case HAL_PIXEL_FORMAT_BGRA_8888:
     46         case HAL_PIXEL_FORMAT_BGRX_8888:
     47         case HAL_PIXEL_FORMAT_RGBA_8888:
     48         case HAL_PIXEL_FORMAT_RGBX_8888:
     49         case HAL_PIXEL_FORMAT_RGB_565:
     50             return trans ? false : true;
     51         default:
     52             VTRACE("unsupported format %#x", format);
     53             return false;
     54         }
     55     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
     56         switch (format) {
     57         case HAL_PIXEL_FORMAT_I420:
     58         case HAL_PIXEL_FORMAT_YUY2:
     59         case HAL_PIXEL_FORMAT_UYVY:
     60             // TODO: overlay supports 180 degree rotation
     61             if (trans == HAL_TRANSFORM_ROT_180) {
     62                 WTRACE("180 degree rotation is not supported yet");
     63             }
     64             return trans ? false : true;
     65         case HAL_PIXEL_FORMAT_YV12:
     66         case HAL_PIXEL_FORMAT_NV12:
     67         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
     68         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
     69             return true;
     70         default:
     71             VTRACE("unsupported format %#x", format);
     72             return false;
     73         }
     74     } else {
     75         ETRACE("invalid plane type %d", planeType);
     76         return false;
     77     }
     78 }
     79 
     80 bool PlaneCapabilities::isSizeSupported(int planeType, HwcLayer *hwcLayer)
     81 {
     82     uint32_t format = hwcLayer->getFormat();
     83     uint32_t w = hwcLayer->getBufferWidth();
     84     uint32_t h = hwcLayer->getBufferHeight();
     85     const stride_t& stride = hwcLayer->getBufferStride();
     86 
     87     bool isYUVPacked;
     88     uint32_t maxStride;
     89 
     90     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
     91         switch (format) {
     92         case HAL_PIXEL_FORMAT_BGRA_8888:
     93         case HAL_PIXEL_FORMAT_BGRX_8888:
     94         case HAL_PIXEL_FORMAT_RGBA_8888:
     95         case HAL_PIXEL_FORMAT_RGBX_8888:
     96         case HAL_PIXEL_FORMAT_RGB_565:
     97             VTRACE("stride %d", stride.rgb.stride);
     98             if (stride.rgb.stride > SPRITE_PLANE_MAX_STRIDE_LINEAR) {
     99                 VTRACE("too large stride %d", stride.rgb.stride);
    100                 return false;
    101             }
    102             return true;
    103         default:
    104             VTRACE("unsupported format %#x", format);
    105             return false;
    106         }
    107     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
    108         switch (format) {
    109         case HAL_PIXEL_FORMAT_YV12:
    110         case HAL_PIXEL_FORMAT_I420:
    111         case HAL_PIXEL_FORMAT_NV12:
    112         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
    113         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
    114             isYUVPacked = false;
    115             break;
    116         case HAL_PIXEL_FORMAT_YUY2:
    117         case HAL_PIXEL_FORMAT_UYVY:
    118             isYUVPacked = true;
    119             break;
    120         default:
    121             VTRACE("unsupported format %#x", format);
    122             return false;
    123         }
    124         // don't use overlay plane if stride is too big
    125         maxStride = OVERLAY_PLANE_MAX_STRIDE_LINEAR;
    126         if (isYUVPacked) {
    127             maxStride = OVERLAY_PLANE_MAX_STRIDE_PACKED;
    128         }
    129 
    130         if (stride.yuv.yStride > maxStride) {
    131             VTRACE("stride %d is too large", stride.yuv.yStride);
    132             return false;
    133         }
    134 
    135         hwc_frect_t& srcCrop = hwcLayer->getLayer()->sourceCropf;
    136         uint32_t width = srcCrop.right - srcCrop.left;
    137         uint32_t height = srcCrop.bottom - srcCrop.top;
    138 
    139         if (width <= 64 || height <= 64) {
    140             DTRACE("width or height of source crop is less than 64, fallback to GLES");
    141             return false;
    142         }
    143 
    144         if ((height & 0x1) || (width & 0x1)){
    145             if (!hwcLayer->isProtected()) {
    146                  DTRACE("unprotected video content, height or width of source crop is not even, fallback to GLES ");
    147                  return false;
    148             }
    149         }
    150 
    151         return true;
    152     } else {
    153         ETRACE("invalid plane type %d", planeType);
    154         return false;
    155     }
    156 }
    157 
    158 bool PlaneCapabilities::isBlendingSupported(int planeType, HwcLayer *hwcLayer)
    159 {
    160     uint32_t blending = (uint32_t)hwcLayer->getLayer()->blending;
    161     uint8_t planeAlpha = hwcLayer->getLayer()->planeAlpha;
    162 
    163     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
    164         // support premultipled & none blanding
    165         switch (blending) {
    166         case HWC_BLENDING_NONE:
    167         case HWC_BLENDING_PREMULT:
    168         // add coverage alpha support for ann
    169         case HWC_BLENDING_COVERAGE:
    170             return true;
    171         default:
    172             VTRACE("unsupported blending %#x", blending);
    173             return false;
    174         }
    175     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
    176         // overlay doesn't support blending
    177         return (blending == HWC_BLENDING_NONE) ? true : false;
    178     } else {
    179         ETRACE("invalid plane type %d", planeType);
    180         return false;
    181     }
    182 }
    183 
    184 bool PlaneCapabilities::isScalingSupported(int planeType, HwcLayer *hwcLayer)
    185 {
    186     hwc_frect_t& src = hwcLayer->getLayer()->sourceCropf;
    187     hwc_rect_t& dest = hwcLayer->getLayer()->displayFrame;
    188     uint32_t trans = hwcLayer->getLayer()->transform;
    189 
    190     int srcW, srcH;
    191     int dstW, dstH;
    192 
    193     srcW = (int)src.right - (int)src.left;
    194     srcH = (int)src.bottom - (int)src.top;
    195     dstW = dest.right - dest.left;
    196     dstH = dest.bottom - dest.top;
    197 
    198     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
    199         // no scaling is supported
    200         return ((srcW == dstW) && (srcH == dstH)) ? true : false;
    201 
    202     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
    203         // overlay cannot support resolution that bigger than 2047x2047.
    204         if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) {
    205             uint32_t format = hwcLayer->getFormat();
    206             if (format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar ||
    207                 format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
    208                 // will fall back to GLES if no scaling buffer provided by ved later
    209                 // so don't return false and print a warning, it's for video format only.
    210                 WTRACE("source size %dx%d hit overlay resolution limitation.", srcW, srcH);
    211             } else {
    212                 return false;
    213             }
    214         }
    215 
    216         if (dstW <= 100 || dstH <= 1 || srcW <= 100 || srcH <= 1) {
    217             // Workaround: Overlay flip when height is 1 causes MIPI stall on TNG
    218             DTRACE("invalid destination size: %dx%d, fall back to GLES", dstW, dstH);
    219             return false;
    220         }
    221 
    222         if (trans == HAL_TRANSFORM_ROT_90 || trans == HAL_TRANSFORM_ROT_270) {
    223             int tmp = srcW;
    224             srcW = srcH;
    225             srcH = tmp;
    226         }
    227 
    228         if (!hwcLayer->isProtected()) {
    229             if ((int)src.left & 63) {
    230                 DTRACE("offset %d is not 64 bytes aligned, fall back to GLES", (int)src.left);
    231                 return false;
    232             }
    233 
    234             float scaleX = (float)srcW / dstW;
    235             float scaleY = (float)srcH / dstH;
    236             if (scaleX >= 3 || scaleY >= 3) {
    237                 DTRACE("overlay rotation with scaling >= 3, fall back to GLES");
    238                 return false;
    239             }
    240 #if 0
    241             if (trans == HAL_TRANSFORM_ROT_90 && (float)srcW / srcH != (float)dstW / dstH) {
    242                 // FIXME: work aournd for pipe crashing issue, when rotate screen
    243                 // from 90 to 0 degree (with Sharp 25x16 panel).
    244                 DTRACE("overlay rotation with uneven scaling, fall back to GLES");
    245                 return false;
    246             }
    247 #endif
    248         }
    249 
    250         return true;
    251     } else {
    252         ETRACE("invalid plane type %d", planeType);
    253         return false;
    254     }
    255 }
    256 
    257 bool PlaneCapabilities::isTransformSupported(int planeType, HwcLayer *hwcLayer)
    258 {
    259     uint32_t trans = hwcLayer->getLayer()->transform;
    260 
    261     if (planeType == DisplayPlane::PLANE_OVERLAY) {
    262         // overlay does not support FLIP_H/FLIP_V
    263         switch (trans) {
    264         case 0:
    265         case HAL_TRANSFORM_ROT_90:
    266         case HAL_TRANSFORM_ROT_180:
    267         case HAL_TRANSFORM_ROT_270:
    268             return true;
    269         default:
    270             return false;
    271         }
    272     }
    273 
    274     // don't transform any tranform
    275     return trans ? false : true;
    276 }
    277 
    278 } // namespace intel
    279 } // namespace android
    280 
    281