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