1 /*
2  * Copyright (C) 2020 Arm Limited.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "drmutils.h"
19 #include "mali_gralloc_formats.h"
20 #include <exynos_format.h>
21 
drm_fourcc_from_handle(const private_handle_t * hnd)22 uint32_t drm_fourcc_from_handle(const private_handle_t *hnd)
23 {
24 	/* Clean the modifier bits in the internal format. */
25 	struct table_entry
26 	{
27 		uint64_t internal;
28 		uint32_t fourcc;
29 	};
30 
31 	static table_entry table[] = {
32 		{ MALI_GRALLOC_FORMAT_INTERNAL_RAW16, DRM_FORMAT_R16 },
33 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888, DRM_FORMAT_ABGR8888 },
34 		{ MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888, DRM_FORMAT_ARGB8888 },
35 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGB_565, DRM_FORMAT_RGB565 },
36 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888, DRM_FORMAT_XBGR8888 },
37 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGB_888, DRM_FORMAT_BGR888 },
38 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102, DRM_FORMAT_ABGR2101010 },
39 		{ MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616, DRM_FORMAT_ABGR16161616F },
40 		{ MALI_GRALLOC_FORMAT_INTERNAL_YV12, DRM_FORMAT_YVU420 },
41 		{ MALI_GRALLOC_FORMAT_INTERNAL_NV12, DRM_FORMAT_NV12 },
42 		{ MALI_GRALLOC_FORMAT_INTERNAL_NV16, DRM_FORMAT_NV16 },
43 		{ MALI_GRALLOC_FORMAT_INTERNAL_NV21, DRM_FORMAT_NV21 },
44 		{ MALI_GRALLOC_FORMAT_INTERNAL_Y0L2, DRM_FORMAT_Y0L2 },
45 		{ MALI_GRALLOC_FORMAT_INTERNAL_Y210, DRM_FORMAT_Y210 },
46 		{ MALI_GRALLOC_FORMAT_INTERNAL_P010, DRM_FORMAT_P010 },
47 		{ MALI_GRALLOC_FORMAT_INTERNAL_P210, DRM_FORMAT_P210 },
48 		{ MALI_GRALLOC_FORMAT_INTERNAL_Y410, DRM_FORMAT_Y410 },
49 		{ MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT, DRM_FORMAT_YUYV },
50 		{ MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, DRM_FORMAT_YUV420_8BIT },
51 		{ MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, DRM_FORMAT_YUV420_10BIT },
52 
53 		/* Deprecated legacy formats, mapped to MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT. */
54 		{ HAL_PIXEL_FORMAT_YCbCr_422_I, DRM_FORMAT_YUYV },
55 		/* Deprecated legacy formats, mapped to MALI_GRALLOC_FORMAT_INTERNAL_NV21. */
56 		{ HAL_PIXEL_FORMAT_YCrCb_420_SP, DRM_FORMAT_NV21 },
57 		/* Format introduced in Android P, mapped to MALI_GRALLOC_FORMAT_INTERNAL_P010. */
58 		{ HAL_PIXEL_FORMAT_YCBCR_P010, DRM_FORMAT_P010 },
59 
60 		/* Exynos Formats */
61 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP,  DRM_FORMAT_NV12 },
62 		{ HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, DRM_FORMAT_NV21 },
63 		{ HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, DRM_FORMAT_NV21 },
64 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, DRM_FORMAT_NV12 },
65 		{ HAL_PIXEL_FORMAT_EXYNOS_YV12_M, DRM_FORMAT_YVU420 },
66 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, DRM_FORMAT_NV12 },
67 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B,  DRM_FORMAT_NV12 },
68 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, DRM_FORMAT_NV12 },
69 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN,        DRM_FORMAT_NV12 },
70 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B,   DRM_FORMAT_NV12 },
71 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M,         DRM_FORMAT_P010 },
72 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P,          DRM_FORMAT_NV12 },
73 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC,         DRM_FORMAT_NV12 },
74 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC,          DRM_FORMAT_NV12 },
75 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC,     DRM_FORMAT_P010 },
76 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC,      DRM_FORMAT_P010 },
77 		{ HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC,         DRM_FORMAT_NV21 },
78 		{ HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC,     DRM_FORMAT_P010 },
79 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50,     DRM_FORMAT_NV12 },
80 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75,     DRM_FORMAT_NV12 },
81 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50,      DRM_FORMAT_NV12 },
82 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75,      DRM_FORMAT_NV12 },
83 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, DRM_FORMAT_P010 },
84 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, DRM_FORMAT_P010 },
85 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, DRM_FORMAT_P010 },
86 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40,  DRM_FORMAT_P010 },
87 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60,  DRM_FORMAT_P010 },
88 		{ HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80,  DRM_FORMAT_P010 },
89 
90 		/* Google Formats */
91 		{ HAL_PIXEL_FORMAT_GOOGLE_NV12_SP,      DRM_FORMAT_NV12 },
92 		{ HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B,  DRM_FORMAT_P010 },
93 		{ HAL_PIXEL_FORMAT_GOOGLE_R_8,  DRM_FORMAT_R8 },
94 		{ HAL_PIXEL_FORMAT_GOOGLE_RG_88,  DRM_FORMAT_RG88 },
95 	};
96 
97 	const uint64_t unmasked_format = hnd->alloc_format;
98 	const uint64_t internal_format = (unmasked_format & MALI_GRALLOC_INTFMT_FMT_MASK);
99 	for (size_t i = 0; i < sizeof(table) / sizeof(table[0]); i++)
100 	{
101 		if (table[i].internal == internal_format)
102 		{
103 			bool afbc = (unmasked_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK);
104 			/* The internal RGB565 format describes two different component orderings depending on AFBC. */
105 			if (afbc && internal_format == MALI_GRALLOC_FORMAT_INTERNAL_RGB_565)
106 			{
107 				return DRM_FORMAT_BGR565;
108 			}
109 			return table[i].fourcc;
110 		}
111 	}
112 
113 	return DRM_FORMAT_INVALID;
114 }
115 
drm_modifier_from_handle(const private_handle_t * hnd)116 uint64_t drm_modifier_from_handle(const private_handle_t *hnd)
117 {
118 	const uint64_t internal_format = hnd->alloc_format;
119 	if ((internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) == 0)
120 	{
121 		return 0;
122 	}
123 
124 	uint64_t modifier = 0;
125 
126 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK)
127 	{
128 		modifier |= AFBC_FORMAT_MOD_SPLIT;
129 	}
130 
131 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
132 	{
133 		modifier |= AFBC_FORMAT_MOD_TILED;
134 	}
135 
136 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY)
137 	{
138 		modifier |= AFBC_FORMAT_MOD_DB;
139 	}
140 
141 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_BCH)
142 	{
143 		modifier |= AFBC_FORMAT_MOD_BCH;
144 	}
145 
146 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM)
147 	{
148 		modifier |= AFBC_FORMAT_MOD_YTR;
149 	}
150 
151 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_SPARSE)
152 	{
153 		modifier |= AFBC_FORMAT_MOD_SPARSE;
154 	}
155 
156 	/* Extract the block-size modifiers. */
157 	if (internal_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
158 	{
159 		modifier |= (hnd->is_multi_plane() ? AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 : AFBC_FORMAT_MOD_BLOCK_SIZE_32x8);
160 	}
161 	else if (internal_format & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
162 	{
163 		modifier |= AFBC_FORMAT_MOD_BLOCK_SIZE_64x4;
164 	}
165 	else
166 	{
167 		modifier |= AFBC_FORMAT_MOD_BLOCK_SIZE_16x16;
168 	}
169 
170 	return DRM_FORMAT_MOD_ARM_AFBC(modifier);
171 }
172