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