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