• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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