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
33 namespace android {
34 namespace intel {
35
isFormatSupported(int planeType,HwcLayer * hwcLayer)36 bool 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
isSizeSupported(int planeType,HwcLayer * hwcLayer)79 bool 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
isBlendingSupported(int planeType,HwcLayer * hwcLayer)139 bool 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
isScalingSupported(int planeType,HwcLayer * hwcLayer)171 bool 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
isTransformSupported(int planeType,HwcLayer * hwcLayer)211 bool 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