PlaneCapabilities.cpp revision 349e264642be6b6efab5085b0a781fd0896400f1
1/*
2 * Copyright © 2012 Intel Corporation
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Jackie Li <yaodong.li@intel.com>
26 */
27
28#include <HwcTrace.h>
29#include <DisplayPlane.h>
30#include <hal_public.h>
31#include <OMX_IVCommon.h>
32#include <PlaneCapabilities.h>
33#include <common/OverlayHardware.h>
34#include <HwcLayer.h>
35
36#define SPRITE_PLANE_MAX_STRIDE_TILED      16384
37#define SPRITE_PLANE_MAX_STRIDE_LINEAR     16384
38
39#define OVERLAY_PLANE_MAX_STRIDE_PACKED    4096
40#define OVERLAY_PLANE_MAX_STRIDE_LINEAR    8192
41
42namespace android {
43namespace intel {
44
45bool PlaneCapabilities::isFormatSupported(int planeType, HwcLayer *hwcLayer)
46{
47    uint32_t format = hwcLayer->getFormat();
48    uint32_t trans = hwcLayer->getLayer()->transform;
49
50    if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
51        switch (format) {
52        case HAL_PIXEL_FORMAT_BGRA_8888:
53        case HAL_PIXEL_FORMAT_BGRX_8888:
54        case HAL_PIXEL_FORMAT_RGBA_8888:
55        case HAL_PIXEL_FORMAT_RGBX_8888:
56        case HAL_PIXEL_FORMAT_RGB_565:
57            return trans ? false : true;
58        default:
59            VTRACE("unsupported format %#x", format);
60            return false;
61        }
62    } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
63        switch (format) {
64        case HAL_PIXEL_FORMAT_I420:
65        case HAL_PIXEL_FORMAT_YUY2:
66        case HAL_PIXEL_FORMAT_UYVY:
67            // TODO: overlay supports 180 degree rotation
68            if (trans == HAL_TRANSFORM_ROT_180) {
69                WTRACE("180 degree rotation is not supported yet");
70            }
71            return trans ? false : true;
72        case HAL_PIXEL_FORMAT_NV12:
73        case HAL_PIXEL_FORMAT_YV12:
74        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
75        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
76            return true;
77        default:
78            VTRACE("unsupported format %#x", format);
79            return false;
80        }
81    } else {
82        ETRACE("invalid plane type %d", planeType);
83        return false;
84    }
85}
86
87bool PlaneCapabilities::isSizeSupported(int planeType, HwcLayer *hwcLayer)
88{
89    uint32_t format = hwcLayer->getFormat();
90    uint32_t w = hwcLayer->getBufferWidth();
91    uint32_t h = hwcLayer->getBufferHeight();
92    const stride_t& stride = hwcLayer->getBufferStride();
93
94    bool isYUVPacked;
95    uint32_t maxStride;
96
97    if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
98        switch (format) {
99        case HAL_PIXEL_FORMAT_BGRA_8888:
100        case HAL_PIXEL_FORMAT_BGRX_8888:
101        case HAL_PIXEL_FORMAT_RGBA_8888:
102        case HAL_PIXEL_FORMAT_RGBX_8888:
103        case HAL_PIXEL_FORMAT_RGB_565:
104            VTRACE("stride %d", stride.rgb.stride);
105            if (stride.rgb.stride > SPRITE_PLANE_MAX_STRIDE_LINEAR) {
106                VTRACE("too large stride %d", stride.rgb.stride);
107                return false;
108            }
109            return true;
110        default:
111            VTRACE("unsupported format %#x", format);
112            return false;
113        }
114    } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
115        switch (format) {
116        case HAL_PIXEL_FORMAT_YV12:
117        case HAL_PIXEL_FORMAT_I420:
118        case HAL_PIXEL_FORMAT_NV12:
119        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
120        case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
121            isYUVPacked = false;
122            break;
123        case HAL_PIXEL_FORMAT_YUY2:
124        case HAL_PIXEL_FORMAT_UYVY:
125            isYUVPacked = true;
126            break;
127        default:
128            VTRACE("unsupported format %#x", format);
129            return false;
130        }
131        // don't use overlay plane if stride is too big
132        maxStride = OVERLAY_PLANE_MAX_STRIDE_LINEAR;
133        if (isYUVPacked) {
134            maxStride = OVERLAY_PLANE_MAX_STRIDE_PACKED;
135        }
136
137        if (stride.yuv.yStride > maxStride) {
138            VTRACE("stride %d is too large", stride.yuv.yStride);
139            return false;
140        }
141        return true;
142    } else {
143        ETRACE("invalid plane type %d", planeType);
144        return false;
145    }
146}
147
148bool PlaneCapabilities::isBlendingSupported(int planeType, HwcLayer *hwcLayer)
149{
150    uint32_t blending = (uint32_t)hwcLayer->getLayer()->blending;
151    uint8_t planeAlpha = hwcLayer->getLayer()->planeAlpha;
152
153    if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
154        // support premultipled & none blanding
155        switch (blending) {
156        case DisplayPlane::PLANE_BLENDING_NONE:
157        case DisplayPlane::PLANE_BLENDING_PREMULT:
158            return true;
159        default:
160            VTRACE("unsupported blending %#x", blending);
161            return false;
162        }
163    } else if (planeType == DisplayPlane::PLANE_OVERLAY) {
164        // overlay doesn't support blending
165        return (blending == DisplayPlane::PLANE_BLENDING_NONE) ? true : false;
166    } else {
167        ETRACE("invalid plane type %d", planeType);
168        return false;
169    }
170}
171
172bool PlaneCapabilities::isScalingSupported(int planeType, HwcLayer *hwcLayer)
173{
174    hwc_frect_t& src = hwcLayer->getLayer()->sourceCropf;
175    hwc_rect_t& dest = hwcLayer->getLayer()->displayFrame;
176    uint32_t trans = hwcLayer->getLayer()->transform;
177
178    int srcW, srcH;
179    int dstW, dstH;
180
181    srcW = (int)src.right - (int)src.left;
182    srcH = (int)src.bottom - (int)src.top;
183    dstW = dest.right - dest.left;
184    dstH = dest.bottom - dest.top;
185
186    if (planeType == DisplayPlane::PLANE_SPRITE || planeType == DisplayPlane::PLANE_PRIMARY) {
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) {
197            // Workaround: Overlay flip when height is 1 causes MIPI stall on TNG
198            DTRACE("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                DTRACE("offset %d is not 64 bytes aligned, fall back to GLES", (int)src.left);
211                return false;
212            }
213
214            int scaleX = srcW / dstW;
215            int scaleY = srcH / dstH;
216            if (trans && (scaleX >= 3 || scaleY >= 3)) {
217                DTRACE("overlay rotation with scaling >= 3, fall back to GLES");
218                return false;
219            }
220            if (trans == HAL_TRANSFORM_ROT_90 && (float)srcW / srcH != (float)dstW / dstH) {
221                // FIXME: work aournd for pipe crashing issue, when rotate screen
222                // from 90 to 0 degree (with Sharp 25x16 panel).
223                DTRACE("overlay rotation with uneven scaling, fall back to GLES");
224                return false;
225            }
226        }
227
228        return true;
229    } else {
230        ETRACE("invalid plane type %d", planeType);
231        return false;
232    }
233}
234
235bool PlaneCapabilities::isTransformSupported(int planeType, HwcLayer *hwcLayer)
236{
237    uint32_t trans = hwcLayer->getLayer()->transform;
238
239    if (planeType == DisplayPlane::PLANE_OVERLAY) {
240        // overlay does not support FLIP_H/FLIP_V
241        switch (trans) {
242        case DisplayPlane::PLANE_TRANSFORM_0:
243        case DisplayPlane::PLANE_TRANSFORM_90:
244        case DisplayPlane::PLANE_TRANSFORM_180:
245        case DisplayPlane::PLANE_TRANSFORM_270:
246            return true;
247        default:
248            return false;
249        }
250    }
251
252    // don't transform any tranform
253    return trans ? false : true;
254}
255
256} // namespace intel
257} // namespace android
258
259