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