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