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 <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 OVERLAY_PLANE_MAX_STRIDE_PACKED 4096
29 #define OVERLAY_PLANE_MAX_STRIDE_LINEAR 8192
30
31 namespace android {
32 namespace intel {
33
isFormatSupported(int planeType,HwcLayer * hwcLayer)34 bool PlaneCapabilities::isFormatSupported(int planeType, HwcLayer *hwcLayer)
35 {
36 uint32_t format = hwcLayer->getFormat();
37 uint32_t trans = hwcLayer->getLayer()->transform;
38
39 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
40 switch (format) {
41 case HAL_PIXEL_FORMAT_BGRA_8888:
42 case HAL_PIXEL_FORMAT_BGRX_8888:
43 case HAL_PIXEL_FORMAT_RGBA_8888:
44 case HAL_PIXEL_FORMAT_RGBX_8888:
45 case HAL_PIXEL_FORMAT_RGB_565:
46 return trans ? false : true;
47 default:
48 VLOGTRACE("unsupported format %#x", format);
49 return false;
50 }
51 } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
52 switch (format) {
53 case HAL_PIXEL_FORMAT_I420:
54 case HAL_PIXEL_FORMAT_YUY2:
55 case HAL_PIXEL_FORMAT_UYVY:
56 // TODO: overlay supports 180 degree rotation
57 if (trans == HAL_TRANSFORM_ROT_180) {
58 WLOGTRACE("180 degree rotation is not supported yet");
59 }
60 return trans ? false : true;
61 case HAL_PIXEL_FORMAT_YV12:
62 return trans ? false: true;
63 case HAL_PIXEL_FORMAT_NV12:
64 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
65 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
66 return true;
67 default:
68 VLOGTRACE("unsupported format %#x", format);
69 return false;
70 }
71 } else {
72 ELOGTRACE("invalid plane type %d", planeType);
73 return false;
74 }
75 }
76
isSizeSupported(int planeType,HwcLayer * hwcLayer)77 bool PlaneCapabilities::isSizeSupported(int planeType, HwcLayer *hwcLayer)
78 {
79 uint32_t format = hwcLayer->getFormat();
80 const stride_t& stride = hwcLayer->getBufferStride();
81
82 bool isYUVPacked;
83 uint32_t maxStride;
84
85 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
86 switch (format) {
87 case HAL_PIXEL_FORMAT_BGRA_8888:
88 case HAL_PIXEL_FORMAT_BGRX_8888:
89 case HAL_PIXEL_FORMAT_RGBA_8888:
90 case HAL_PIXEL_FORMAT_RGBX_8888:
91 case HAL_PIXEL_FORMAT_RGB_565:
92 VLOGTRACE("stride %d", stride.rgb.stride);
93 if (stride.rgb.stride > SPRITE_PLANE_MAX_STRIDE_LINEAR) {
94 VLOGTRACE("too large stride %d", stride.rgb.stride);
95 return false;
96 }
97 return true;
98 default:
99 VLOGTRACE("unsupported format %#x", format);
100 return false;
101 }
102 } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
103 switch (format) {
104 case HAL_PIXEL_FORMAT_YV12:
105 case HAL_PIXEL_FORMAT_I420:
106 case HAL_PIXEL_FORMAT_NV12:
107 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
108 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
109 isYUVPacked = false;
110 break;
111 case HAL_PIXEL_FORMAT_YUY2:
112 case HAL_PIXEL_FORMAT_UYVY:
113 isYUVPacked = true;
114 break;
115 default:
116 VLOGTRACE("unsupported format %#x", format);
117 return false;
118 }
119 // don't use overlay plane if stride is too big
120 maxStride = OVERLAY_PLANE_MAX_STRIDE_LINEAR;
121 if (isYUVPacked) {
122 maxStride = OVERLAY_PLANE_MAX_STRIDE_PACKED;
123 }
124
125 if (stride.yuv.yStride > maxStride) {
126 VLOGTRACE("stride %d is too large", stride.yuv.yStride);
127 return false;
128 }
129 return true;
130 } else {
131 ELOGTRACE("invalid plane type %d", planeType);
132 return false;
133 }
134 }
135
isBlendingSupported(int planeType,HwcLayer * hwcLayer)136 bool PlaneCapabilities::isBlendingSupported(int planeType, HwcLayer *hwcLayer)
137 {
138 uint32_t blending = (uint32_t)hwcLayer->getLayer()->blending;
139
140 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
141 // support premultipled & none blanding
142 switch (blending) {
143 case HWC_BLENDING_NONE:
144 case HWC_BLENDING_PREMULT:
145 // add coverage alpha support for ann
146 case HWC_BLENDING_COVERAGE:
147 return true;
148 default:
149 VLOGTRACE("unsupported blending %#x", blending);
150 return false;
151 }
152 } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
153 // overlay doesn't support blending
154 return (blending == HWC_BLENDING_NONE) ? true : false;
155 } else {
156 ELOGTRACE("invalid plane type %d", planeType);
157 return false;
158 }
159 }
160
isScalingSupported(int planeType,HwcLayer * hwcLayer)161 bool PlaneCapabilities::isScalingSupported(int planeType, HwcLayer *hwcLayer)
162 {
163 hwc_frect_t& src = hwcLayer->getLayer()->sourceCropf;
164 hwc_rect_t& dest = hwcLayer->getLayer()->displayFrame;
165 uint32_t trans = hwcLayer->getLayer()->transform;
166
167 int srcW, srcH;
168 int dstW, dstH;
169
170 srcW = (int)src.right - (int)src.left;
171 srcH = (int)src.bottom - (int)src.top;
172 dstW = dest.right - dest.left;
173 dstH = dest.bottom - dest.top;
174
175 if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
176 // no scaling is supported
177 return ((srcW == dstW) && (srcH == dstH)) ? true : false;
178
179 } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
180 // overlay cannot support resolution that bigger than 2047x2047.
181 if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) {
182 return false;
183 }
184
185 if (dstW <= 1 || dstH <= 1 || srcW <= 1 || srcH <= 1) {
186 // Workaround: Overlay flip when height is 1 causes MIPI stall on TNG
187 DLOGTRACE("invalid destination size: %dx%d, fall back to GLES", dstW, dstH);
188 return false;
189 }
190
191 if (trans == HAL_TRANSFORM_ROT_90 || trans == HAL_TRANSFORM_ROT_270) {
192 int tmp = srcW;
193 srcW = srcH;
194 srcH = tmp;
195 }
196
197 if (!hwcLayer->isProtected()) {
198 if ((int)src.left & 63) {
199 DLOGTRACE("offset %d is not 64 bytes aligned, fall back to GLES", (int)src.left);
200 return false;
201 }
202
203 float scaleX = (float)srcW / dstW;
204 float scaleY = (float)srcH / dstH;
205 if (scaleX > 4.0 || scaleY > 4.0 || scaleX < 0.25 || scaleY < 0.25) {
206 WLOGTRACE("overlay scaling > 4, fall back to GLES");
207 return false;
208 }
209 }
210
211 return true;
212 } else {
213 ELOGTRACE("invalid plane type %d", planeType);
214 return false;
215 }
216 }
217
isTransformSupported(int planeType,HwcLayer * hwcLayer)218 bool PlaneCapabilities::isTransformSupported(int planeType, HwcLayer *hwcLayer)
219 {
220 uint32_t trans = hwcLayer->getLayer()->transform;
221
222 if (planeType == DisplayPlane::PLANE_OVERLAY) {
223 // overlay does not support FLIP_H/FLIP_V
224 switch (trans) {
225 case 0:
226 case HAL_TRANSFORM_ROT_90:
227 case HAL_TRANSFORM_ROT_270:
228 return true;
229 default:
230 return false;
231 }
232 }
233
234 // don't transform any tranform
235 return trans ? false : true;
236 }
237
238 } // namespace intel
239 } // namespace android
240
241