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