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
33namespace android {
34namespace intel {
35
36bool 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
79bool 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
139bool 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
171bool 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
211bool 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