blob: b4114dde9a564bdaf06553dfb9d4f0a978f6d95f [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _EXYNOSHWCHELPER_H
#define _EXYNOSHWCHELPER_H
#include <utils/String8.h>
#include <hardware/hwcomposer2.h>
#include <drm/drm_fourcc.h>
#ifdef GRALLOC_VERSION1
#include "gralloc1_priv.h"
#else
#include "gralloc_priv.h"
#endif
#include "DeconHeader.h"
#include "VendorVideoAPI.h"
#include "exynos_sync.h"
#include "exynos_format.h"
#define MAX_FENCE_NAME 64
#define MAX_FENCE_THRESHOLD 500
#define MAX_FD_NUM 1024
#define MAX_USE_FORMAT 27
#ifndef P010M_Y_SIZE
#define P010M_Y_SIZE(w,h) (__ALIGN_UP((w), 16) * 2 * __ALIGN_UP((h), 16) + 256)
#endif
#ifndef P010M_CBCR_SIZE
#define P010M_CBCR_SIZE(w,h) ((__ALIGN_UP((w), 16) * 2 * __ALIGN_UP((h), 16) / 2) + 256)
#endif
#ifndef P010_Y_SIZE
#define P010_Y_SIZE(w, h) ((w) * (h) * 2)
#endif
#ifndef P010_CBCR_SIZE
#define P010_CBCR_SIZE(w, h) ((w) * (h))
#endif
template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
class ExynosLayer;
class ExynosDisplay;
using namespace android;
enum {
EXYNOS_HWC_DIM_LAYER = 0x00000001,
};
typedef enum format_type {
/* format */
RGB = 0x00000001,
YUV420 = 0x00000002,
YUV422 = 0x00000004,
UNDEF_FORMAT = 0x00008000,
/* bit */
BIT8 = 0x00010000,
BIT10 = 0x00020000,
UNDEF_BIT = 0x08000000,
/* undefined */
UNDEF = 0x80000000,
} format_type_t;
typedef struct format_description {
int halFormat;
decon_pixel_format s3cFormat;
int drmFormat;
uint32_t bufferNum;
uint8_t bpp;
uint32_t type;
bool hasAlpha;
String8 name;
uint32_t reserved;
} format_description_t;
#define HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED 0
#define DRM_FORMAT_UNDEFINED 0
const format_description_t exynos_format_desc[] = {
/* RGB */
{HAL_PIXEL_FORMAT_RGBA_8888, DECON_PIXEL_FORMAT_RGBA_8888, DRM_FORMAT_RGBA8888,
1, 32, RGB|BIT8, true, String8("RGBA_8888"), 0},
{HAL_PIXEL_FORMAT_RGBX_8888, DECON_PIXEL_FORMAT_RGBX_8888, DRM_FORMAT_RGBX8888,
1, 32, RGB|BIT8, false, String8("RGBx_8888"), 0},
{HAL_PIXEL_FORMAT_RGB_888, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_RGB888,
1, 32, RGB|BIT8, false, String8("RGB_888"), 0},
{HAL_PIXEL_FORMAT_RGB_565, DECON_PIXEL_FORMAT_RGB_565, DRM_FORMAT_RGB565,
1, 16, RGB|UNDEF_BIT, false, String8("RGB_565"), 0},
{HAL_PIXEL_FORMAT_BGRA_8888, DECON_PIXEL_FORMAT_BGRA_8888, DRM_FORMAT_BGRA8888,
1, 32, RGB|BIT8, true, String8("BGRA_8888"), 0},
{HAL_PIXEL_FORMAT_RGBA_1010102, DECON_PIXEL_FORMAT_ABGR_2101010, DRM_FORMAT_RGBA1010102,
1, 32, RGB|BIT10, true, String8("RGBA_1010102"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_ARGB8888,
1, 32, RGB|BIT8, true, String8("EXYNOS_ARGB_8888"), 0},
/* YUV 420 */
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, DECON_PIXEL_FORMAT_YUV420M, DRM_FORMAT_UNDEFINED,
3, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_P_M"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, DECON_PIXEL_FORMAT_NV12M, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SP_M"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SP_M_TILED"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YV12_M, DECON_PIXEL_FORMAT_YVU420M, DRM_FORMAT_UNDEFINED,
3, 12, YUV420|BIT8, false, String8("EXYNOS_YV12_M"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, DECON_PIXEL_FORMAT_NV21M, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT8, false, String8("EXYNOS_YCrCb_420_SP_M"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, DECON_PIXEL_FORMAT_NV21M, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT8, false, String8("EXYNOS_YCrCb_420_SP_M_FULL"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
1, 0, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_P"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
1, 0, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SP"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, DECON_PIXEL_FORMAT_NV12M, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SP_M_PRIV"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_PN"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, DECON_PIXEL_FORMAT_NV12N, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SPN"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT8, false, String8("EXYNOS_YCbCr_420_SPN_TILED"), 0},
{HAL_PIXEL_FORMAT_YCrCb_420_SP, DECON_PIXEL_FORMAT_NV21, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT8, false, String8("YCrCb_420_SP"), 0},
{HAL_PIXEL_FORMAT_YV12, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT8, false, String8("YV12"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, DECON_PIXEL_FORMAT_NV12M_S10B, DRM_FORMAT_UNDEFINED,
2, 12, YUV420|BIT10, false, String8("EXYNOS_YCbCr_420_SP_M_S10B"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, DECON_PIXEL_FORMAT_NV12N_10B, DRM_FORMAT_UNDEFINED,
1, 12, YUV420|BIT10, false, String8("EXYNOS_YCbCr_420_SPN_S10B"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, DECON_PIXEL_FORMAT_NV12M_P010, DRM_FORMAT_UNDEFINED,
2, 24, YUV420|BIT10, false, String8("EXYNOS_YCbCr_P010_M"), 0},
{HAL_PIXEL_FORMAT_YCBCR_P010, DECON_PIXEL_FORMAT_NV12_P010, DRM_FORMAT_UNDEFINED,
1, 24, YUV420|BIT10, false, String8("EXYNOS_YCbCr_P010"), 0},
/* YUV 422 */
{HAL_PIXEL_FORMAT_EXYNOS_CbYCrY_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
0, 0, YUV422|BIT8, false, String8("EXYNOS_CbYCrY_422_I"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_SP, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
0, 0, YUV422|BIT8, false, String8("EXYNOS_YCrCb_422_SP"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
0, 0, YUV422|BIT8, false, String8("EXYNOS_YCrCb_422_I"), 0},
{HAL_PIXEL_FORMAT_EXYNOS_CrYCbY_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
0, 0, YUV422|BIT8, false, String8("EXYNOS_CrYCbY_422_I"), 0},
{HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
0, 0, UNDEF, false, String8("ImplDef"), 0}
};
#define FORMAT_MAX_CNT sizeof(exynos_format_desc)/sizeof(format_description)
typedef enum hwc_fdebug_fence_type_t {
FENCE_TYPE_SRC_RELEASE = 1,
FENCE_TYPE_SRC_ACQUIRE = 2,
FENCE_TYPE_DST_RELEASE = 3,
FENCE_TYPE_DST_ACQUIRE = 4,
FENCE_TYPE_FREE_RELEASE = 5,
FENCE_TYPE_FREE_ACQUIRE = 6,
FENCE_TYPE_HW_STATE = 7,
FENCE_TYPE_RETIRE = 8,
FENCE_TYPE_ALL = 9,
FENCE_TYPE_UNDEFINED = 100
} hwc_fdebug_fence_type;
typedef enum hwc_fdebug_ip_type_t {
FENCE_IP_DPP = 0,
FENCE_IP_MSC = 1,
FENCE_IP_G2D = 2,
FENCE_IP_FB = 3,
FENCE_IP_LAYER = 4,
FENCE_IP_ALL = 5,
FENCE_IP_UNDEFINED = 100
} hwc_fdebug_ip_type;
typedef enum hwc_fence_type_t {
FENCE_LAYER_RELEASE_DPP = 0,
FENCE_LAYER_RELEASE_MPP = 1,
FENCE_LAYER_RELEASE_MSC = 2,
FENCE_LAYER_RELEASE_G2D = 3,
FENCE_DPP_HW_STATE = 4,
FENCE_MSC_HW_STATE = 5,
FENCE_G2D_HW_STATE = 6,
FENCE_MSC_SRC_LAYER = 7,
FENCE_G2D_SRC_LAYER = 8,
FENCE_MPP_DST_DPP = 9,
FENCE_MSC_DST_DPP = 10,
FENCE_G2D_DST_DPP = 11,
FENCE_DPP_SRC_MPP = 12,
FENCE_DPP_SRC_MSC = 13,
FENCE_DPP_SRC_G2D = 14,
FENCE_DPP_SRC_LAYER = 15,
FENCE_MPP_FREE_BUF_ACQUIRE = 16,
FENCE_MPP_FREE_BUF_RELEASE = 17,
FENCE_RETIRE = 18,
FENCE_MAX
} hwc_fence_type;
enum {
EXYNOS_ERROR_NONE = 0,
EXYNOS_ERROR_CHANGED = 1
};
enum {
eSkipLayer = 0x00000001,
eInvalidHandle = 0x00000002,
eHasFloatSrcCrop = 0x00000004,
eUpdateExynosComposition = 0x00000008,
eDynamicRecomposition = 0x00000010,
eForceFbEnabled = 0x00000020,
eSandwitchedBetweenGLES = 0x00000040,
eSandwitchedBetweenEXYNOS = 0x00000080,
eInsufficientWindow = 0x00000100,
eInsufficientMPP = 0x00000200,
eSkipStaticLayer = 0x00000400,
eUnSupportedUseCase = 0x00000800,
eDimLayer = 0x00001000,
eResourcePendingWork = 0x00002000,
eSourceOverBelow = 0x00004000,
eSkipRotateAnim = 0x00008000,
eUnSupportedColorTransform = 0x00010000,
eLowFpsLayer = 0x00020000,
eReallocOnGoingForDDI = 0x00040000,
eInvalidDispFrame = 0x00080000,
eExceedMaxLayerNum = 0x00100000,
eResourceAssignFail = 0x20000000,
eMPPUnsupported = 0x40000000,
eUnknown = 0x80000000,
};
enum regionType {
eTransparentRegion = 0,
eCoveredOpaqueRegion = 1,
eDamageRegionByDamage = 2,
eDamageRegionByLayer = 3,
};
enum {
eDamageRegionFull = 0,
eDamageRegionPartial,
eDamageRegionSkip,
eDamageRegionError,
};
/*
* bufferHandle can be NULL if it is not allocated yet
* or size or format information can be different between other field values and
* member of bufferHandle. This means bufferHandle should be reallocated.
* */
typedef struct exynos_image {
uint32_t fullWidth;
uint32_t fullHeight;
uint32_t x;
uint32_t y;
uint32_t w;
uint32_t h;
uint32_t format;
uint64_t usageFlags;
uint32_t layerFlags;
int acquireFenceFd = -1;
int releaseFenceFd = -1;
private_handle_t *bufferHandle;
android_dataspace dataSpace;
uint32_t blending;
uint32_t transform;
uint32_t compressed;
float planeAlpha;
uint32_t zOrder = 0;
/* refer
* frameworks/native/include/media/hardware/VideoAPI.h
* frameworks/native/include/media/hardware/HardwareAPI.h */
ExynosHdrStaticInfo hdrStaticInfo;
ExynosHdrDynamicInfo hdrDynamicInfo;
ExynosVideoInfoType metaType = VIDEO_INFO_TYPE_INVALID;
bool needDegamma = false;
} exynos_image_t;
uint32_t getHWC1CompType(int32_t /*hwc2_composition_t*/ type);
uint32_t getDrmMode(uint64_t flags);
uint32_t getDrmMode(const private_handle_t *handle);
inline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; }
inline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; }
inline int WIDTH(const hwc_frect_t &rect) { return (int)(rect.right - rect.left); }
inline int HEIGHT(const hwc_frect_t &rect) { return (int)(rect.bottom - rect.top); }
uint32_t halDataSpaceToV4L2ColorSpace(android_dataspace data_space);
enum decon_pixel_format halFormatToS3CFormat(int format);
uint32_t S3CFormatToHalFormat(int format);
int S3CFormatToDrmFormat(int format);
uint8_t formatToBpp(int format);
uint8_t DeconFormatToBpp(decon_pixel_format format);
bool isFormatRgb(int format);
bool isFormatYUV(int format);
bool isFormatYUV420(int format);
bool isFormatYUV422(int format);
bool isFormatYCrCb(int format);
bool isFormat10BitYUV420(int format);
bool formatHasAlphaChannel(int format);
unsigned int isNarrowRgb(int format, android_dataspace data_space);
bool isCompressed(const private_handle_t *handle);
bool isSrcCropFloat(hwc_frect &frect);
bool isScaled(exynos_image &src, exynos_image &dst);
bool isScaledDown(exynos_image &src, exynos_image &dst);
bool hasHdrInfo(exynos_image &img);
bool hasHdrInfo(android_dataspace dataSpace);
bool hasHdr10Plus(exynos_image &img);
void dumpExynosImage(uint32_t type, exynos_image &img);
void dumpExynosImage(String8& result, exynos_image &img);
void dumpHandle(uint32_t type, private_handle_t *h);
String8 getFormatStr(int format);
String8 getMPPStr(int typeId);
void adjustRect(hwc_rect_t &rect, int32_t width, int32_t height);
uint32_t getBufferNumOfFormat(int format);
int fence_close(int fence, ExynosDisplay* display,
hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip);
bool fence_valid(int fence);
int hwcFdClose(int fd);
int hwc_dup(int fd, ExynosDisplay* display,
hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip);
int hwc_print_stack();
inline hwc_rect expand(const hwc_rect &r1, const hwc_rect &r2)
{
hwc_rect i;
i.top = min(r1.top, r2.top);
i.bottom = max(r1.bottom, r2.bottom);
i.left = min(r1.left, r2.left);
i.right = max(r1.right, r2.right);
return i;
}
int pixel_align_down(int x, int a);
inline int pixel_align(int x, int a) {
if ((a != 0) && ((x % a) != 0))
return ((x) - (x % a)) + a;
return x;
}
int getBufLength(private_handle_t *handle, uint32_t planer_num, size_t *length, int format, uint32_t width, uint32_t height);
//class hwc_fence_info(sync_fence_info_data* data, sync_pt_info* info) {
struct tm* getHwcFenceTime();
enum {
FENCE_FROM = 0,
FENCE_TO,
FENCE_DUP,
FENCE_CLOSE,
};
typedef struct fenceTrace {
hwc_fdebug_fence_type type;
hwc_fdebug_ip_type ip;
struct timeval time;
int32_t curFlag;
} fenceTrace_t;
typedef struct hwc_fence_info {
uint32_t displayId;
struct sync_fence_info_data* sync_data;
struct sync_pt_info* pt_info;
fenceTrace_t from;
fenceTrace_t to;
fenceTrace_t dup;
fenceTrace_t close;
int32_t usage;
int32_t curFlag;
uint32_t last_dir;
bool pendingAllowed = false;
bool leaking = false;
} hwc_fence_info_t;
void setFenceName(int fenceFd, hwc_fence_type fenceType);
void setFenceName(uint32_t fd, ExynosDisplay *display,
hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
uint32_t direction, bool pendingAllowed = false);
void setFenceInfo(uint32_t fd, ExynosDisplay *display,
hwc_fdebug_fence_type type, hwc_fdebug_ip_type ip,
uint32_t direction, bool pendingAllowed = false);
void printFenceInfo(uint32_t fd, hwc_fence_info_t* info);
void dumpFenceInfo(ExynosDisplay *display, int32_t __unused depth);
bool fenceWarn(hwc_fence_info_t **info, uint32_t threshold);
void resetFenceCurFlag(ExynosDisplay *display);
bool fenceWarn(ExynosDisplay *display, uint32_t threshold);
void printLeakFds(ExynosDisplay *display);
bool validateFencePerFrame(ExynosDisplay *display);
android_dataspace colorModeToDataspace(android_color_mode_t mode);
#endif