1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 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 "OverlayHardware.h" 24#include <HwcLayer.h> 25 26#define SPRITE_PLANE_MAX_STRIDE_TILED 16384 27//FIXME: need confirmation about this stride 28#define SPRITE_PLANE_MAX_STRIDE_LINEAR 8192 29 30#define OVERLAY_PLANE_MAX_STRIDE_PACKED 4096 31#define OVERLAY_PLANE_MAX_STRIDE_LINEAR 8192 32 33namespace android { 34namespace intel { 35 36bool PlaneCapabilities::isFormatSupported(int planeType, HwcLayer *hwcLayer) 37{ 38 uint32_t format = hwcLayer->getFormat(); 39 uint32_t trans = hwcLayer->getLayer()->transform; 40 41 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) { 42 switch (format) { 43 case HAL_PIXEL_FORMAT_BGRA_8888: 44 case HAL_PIXEL_FORMAT_BGRX_8888: 45 case HAL_PIXEL_FORMAT_RGBA_8888: 46 case HAL_PIXEL_FORMAT_RGBX_8888: 47 case HAL_PIXEL_FORMAT_RGB_565: 48 return trans ? false : true; 49 default: 50 VTRACE("unsupported format %#x", format); 51 return false; 52 } 53 } else if (planeType == DisplayPlane::PLANE_OVERLAY) { 54 switch (format) { 55 case HAL_PIXEL_FORMAT_I420: 56 case HAL_PIXEL_FORMAT_YUY2: 57 case HAL_PIXEL_FORMAT_UYVY: 58 // TODO: overlay supports 180 degree rotation 59 if (trans == HAL_TRANSFORM_ROT_180) { 60 WTRACE("180 degree rotation is not supported yet"); 61 } 62 return trans ? false : true; 63 case HAL_PIXEL_FORMAT_YV12: 64 return trans ? false: true; 65 case HAL_PIXEL_FORMAT_NV12: 66 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar: 67 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled: 68 return true; 69 default: 70 VTRACE("unsupported format %#x", format); 71 return false; 72 } 73 } else { 74 ETRACE("invalid plane type %d", planeType); 75 return false; 76 } 77} 78 79bool PlaneCapabilities::isSizeSupported(int planeType, HwcLayer *hwcLayer) 80{ 81 uint32_t format = hwcLayer->getFormat(); 82 uint32_t w = hwcLayer->getBufferWidth(); 83 uint32_t h = hwcLayer->getBufferHeight(); 84 const stride_t& stride = hwcLayer->getBufferStride(); 85 86 bool isYUVPacked; 87 uint32_t maxStride; 88 89 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) { 90 switch (format) { 91 case HAL_PIXEL_FORMAT_BGRA_8888: 92 case HAL_PIXEL_FORMAT_BGRX_8888: 93 case HAL_PIXEL_FORMAT_RGBA_8888: 94 case HAL_PIXEL_FORMAT_RGBX_8888: 95 case HAL_PIXEL_FORMAT_RGB_565: 96 if (stride.rgb.stride > SPRITE_PLANE_MAX_STRIDE_LINEAR) { 97 VTRACE("too large stride %d", stride.rgb.stride); 98 return false; 99 } 100 return true; 101 default: 102 VTRACE("unsupported format %#x", format); 103 return false; 104 } 105 } else if (planeType == DisplayPlane::PLANE_OVERLAY) { 106 switch (format) { 107 case HAL_PIXEL_FORMAT_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 VTRACE("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 VTRACE("stride %d is too large", stride.yuv.yStride); 130 return false; 131 } 132 return true; 133 } else { 134 ETRACE("invalid plane type %d", planeType); 135 return false; 136 } 137} 138 139bool PlaneCapabilities::isBlendingSupported(int planeType, HwcLayer *hwcLayer) 140{ 141 uint32_t blending = (uint32_t)hwcLayer->getLayer()->blending; 142 uint8_t planeAlpha = hwcLayer->getLayer()->planeAlpha; 143 144 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) { 145 bool ret = false; 146 147 // support premultipled & none blanding 148 switch (blending) { 149 case HWC_BLENDING_NONE: 150 return true; 151 case HWC_BLENDING_PREMULT: 152 ret = false; 153 if ((planeAlpha == 0) || (planeAlpha == 255)) { 154 ret = true; 155 } 156 return ret; 157 default: 158 VTRACE("unsupported blending %#x", blending); 159 return false; 160 } 161 } else if (planeType == DisplayPlane::PLANE_OVERLAY) { 162 // overlay doesn't support blending 163 return (blending == HWC_BLENDING_NONE) ? true : false; 164 } else { 165 ETRACE("invalid plane type %d", planeType); 166 return false; 167 } 168} 169 170 171bool PlaneCapabilities::isScalingSupported(int planeType, HwcLayer *hwcLayer) 172{ 173 hwc_frect_t& src = hwcLayer->getLayer()->sourceCropf; 174 hwc_rect_t& dest = hwcLayer->getLayer()->displayFrame; 175 176 int srcW, srcH; 177 int dstW, dstH; 178 179 srcW = (int)src.right - (int)src.left; 180 srcH = (int)src.bottom - (int)src.top; 181 dstW = dest.right - dest.left; 182 dstH = dest.bottom - dest.top; 183 184 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) { 185 // no scaling is supported 186 return ((srcW == dstW) && (srcH == dstH)) ? true : false; 187 188 } else if (planeType == DisplayPlane::PLANE_OVERLAY) { 189 // overlay cannot support resolution that bigger than 2047x2047. 190 if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) { 191 return false; 192 } 193 194 if (dstW <= 1 || dstH <= 1 || srcW <= 1 || srcH <= 1) { 195 // Workaround: Overlay flip when height is 1 causes MIPI stall on TNG 196 return false; 197 } 198 199 return true; 200 } else if (planeType == DisplayPlane::PLANE_CURSOR) { 201 if (srcW > 256 || srcH > 256) { 202 return false; 203 } 204 return true; 205 } else { 206 ETRACE("invalid plane type %d", planeType); 207 return false; 208 } 209} 210 211bool PlaneCapabilities::isTransformSupported(int planeType, HwcLayer *hwcLayer) 212{ 213 uint32_t trans = hwcLayer->getLayer()->transform; 214 215 if (planeType == DisplayPlane::PLANE_OVERLAY) { 216 // overlay does not support FLIP_H/FLIP_V 217 switch (trans) { 218 case 0: 219 case HAL_TRANSFORM_ROT_90: 220 case HAL_TRANSFORM_ROT_180: 221 case HAL_TRANSFORM_ROT_270: 222 return true; 223 default: 224 return false; 225 } 226 } 227 228 // don't transform any tranform 229 return trans ? false : true; 230} 231 232} // namespace intel 233} // namespace android 234 235