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 SPRITE_PLANE_MAX_WIDTH             4096
     29 #define SPRITE_PLANE_MAX_HEIGHT            4096
     30 
     31 #define OVERLAY_PLANE_MAX_STRIDE_PACKED    4096
     32 #define OVERLAY_PLANE_MAX_STRIDE_LINEAR    8192
     33 
     34 namespace android {
     35 namespace intel {
     36 
     37 bool PlaneCapabilities::isFormatSupported(int planeType, HwcLayer *hwcLayer)
     38 {
     39     uint32_t format = hwcLayer->getFormat();
     40     uint32_t trans = hwcLayer->getLayer()->transform;
     41 
     42     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
     43         switch (format) {
     44         case HAL_PIXEL_FORMAT_BGRA_8888:
     45         case HAL_PIXEL_FORMAT_BGRX_8888:
     46         case HAL_PIXEL_FORMAT_RGBA_8888:
     47         case HAL_PIXEL_FORMAT_RGBX_8888:
     48         case HAL_PIXEL_FORMAT_RGB_565:
     49             return trans ? false : true;
     50         default:
     51             VLOGTRACE("unsupported format %#x", format);
     52             return false;
     53         }
     54     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
     55         switch (format) {
     56         case HAL_PIXEL_FORMAT_I420:
     57         case HAL_PIXEL_FORMAT_YUY2:
     58         case HAL_PIXEL_FORMAT_UYVY:
     59             // TODO: overlay supports 180 degree rotation
     60             if (trans == HAL_TRANSFORM_ROT_180) {
     61                 WLOGTRACE("180 degree rotation is not supported yet");
     62             }
     63             return trans ? false : true;
     64         case HAL_PIXEL_FORMAT_INTEL_YV12:
     65             return trans ? false: true;
     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             VLOGTRACE("unsupported format %#x", format);
     72             return false;
     73         }
     74     } else {
     75         ELOGTRACE("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     const stride_t& stride = hwcLayer->getBufferStride();
     84 
     85     bool isYUVPacked;
     86     uint32_t maxStride;
     87 
     88     if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
     89         switch (format) {
     90         case HAL_PIXEL_FORMAT_BGRA_8888:
     91         case HAL_PIXEL_FORMAT_BGRX_8888:
     92         case HAL_PIXEL_FORMAT_RGBA_8888:
     93         case HAL_PIXEL_FORMAT_RGBX_8888:
     94         case HAL_PIXEL_FORMAT_RGB_565:
     95             VLOGTRACE("stride %d", stride.rgb.stride);
     96             if (stride.rgb.stride > SPRITE_PLANE_MAX_STRIDE_LINEAR) {
     97                 VLOGTRACE("too large stride %d", stride.rgb.stride);
     98                 return false;
     99             }
    100             return true;
    101         default:
    102             VLOGTRACE("unsupported format %#x", format);
    103             return false;
    104         }
    105     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
    106         switch (format) {
    107         case HAL_PIXEL_FORMAT_INTEL_YV12:
    108         case HAL_PIXEL_FORMAT_I420:
    109         case HAL_PIXEL_FORMAT_NV12:
    110         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
    111         case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
    112             isYUVPacked = false;
    113             break;
    114         case HAL_PIXEL_FORMAT_YUY2:
    115         case HAL_PIXEL_FORMAT_UYVY:
    116             isYUVPacked = true;
    117             break;
    118         default:
    119             VLOGTRACE("unsupported format %#x", format);
    120             return false;
    121         }
    122         // don't use overlay plane if stride is too big
    123         maxStride = OVERLAY_PLANE_MAX_STRIDE_LINEAR;
    124         if (isYUVPacked) {
    125             maxStride = OVERLAY_PLANE_MAX_STRIDE_PACKED;
    126         }
    127 
    128         if (stride.yuv.yStride > maxStride) {
    129             VLOGTRACE("stride %d is too large", stride.yuv.yStride);
    130             return false;
    131         }
    132         return true;
    133     } else {
    134         ELOGTRACE("invalid plane type %d", planeType);
    135         return false;
    136     }
    137 }
    138 
    139 bool PlaneCapabilities::isBlendingSupported(int planeType, HwcLayer *hwcLayer)
    140 {
    141     uint32_t blending = (uint32_t)hwcLayer->getLayer()->blending;
    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         if ((dstW - 1) <= 0 || (dstH - 1) <= 0 ||
    180             (dstW - 1) >= SPRITE_PLANE_MAX_WIDTH ||
    181             (dstH - 1) >= SPRITE_PLANE_MAX_HEIGHT) {
    182             // Should check size in isSizeSupported().
    183             DLOGTRACE("invalid destination size: %d x %d, fall back to GLES", dstW, dstH);
    184             return false;
    185         }
    186 
    187         // no scaling is supported
    188         return ((srcW == dstW) && (srcH == dstH)) ? true : false;
    189 
    190     } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
    191         // overlay cannot support resolution that bigger than 2047x2047.
    192         if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) {
    193             return false;
    194         }
    195 
    196         if (dstW <= 1 || dstH <= 1 || srcW <= 1 || srcH <= 1) {
    197             // Workaround: Overlay flip when height is 1 causes MIPI stall on TNG
    198             DLOGTRACE("invalid destination size: %dx%d, fall back to GLES", dstW, dstH);
    199             return false;
    200         }
    201 
    202         if (trans == HAL_TRANSFORM_ROT_90 || trans == HAL_TRANSFORM_ROT_270) {
    203             int tmp = srcW;
    204             srcW = srcH;
    205             srcH = tmp;
    206         }
    207 
    208         if (!hwcLayer->isProtected()) {
    209             if ((int)src.left & 63) {
    210                 DLOGTRACE("offset %d is not 64 bytes aligned, fall back to GLES", (int)src.left);
    211                 return false;
    212             }
    213 
    214             float scaleX = (float)srcW / dstW;
    215             float scaleY = (float)srcH / dstH;
    216             if (scaleX > 4.0 || scaleY > 4.0 || scaleX < 0.25 || scaleY < 0.25) {
    217                 WLOGTRACE("overlay scaling > 4, fall back to GLES");
    218                 return false;
    219             }
    220         }
    221 
    222         return true;
    223     } else {
    224         ELOGTRACE("invalid plane type %d", planeType);
    225         return false;
    226     }
    227 }
    228 
    229 bool PlaneCapabilities::isTransformSupported(int planeType, HwcLayer *hwcLayer)
    230 {
    231     uint32_t trans = hwcLayer->getLayer()->transform;
    232 
    233     if (planeType == DisplayPlane::PLANE_OVERLAY) {
    234         // overlay does not support FLIP_H/FLIP_V
    235         switch (trans) {
    236         case 0:
    237         case HAL_TRANSFORM_ROT_90:
    238         case HAL_TRANSFORM_ROT_270:
    239             return true;
    240         default:
    241             return false;
    242         }
    243     }
    244 
    245     // don't transform any tranform
    246     return trans ? false : true;
    247 }
    248 
    249 } // namespace intel
    250 } // namespace android
    251 
    252