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 <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
isFormatSupported(int planeType,HwcLayer * hwcLayer)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
isSizeSupported(int planeType,HwcLayer * hwcLayer)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
isBlendingSupported(int planeType,HwcLayer * hwcLayer)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
isScalingSupported(int planeType,HwcLayer * hwcLayer)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
isTransformSupported(int planeType,HwcLayer * hwcLayer)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