1 /*
2 * Copyright (C) 2012 The Android Open Source Project
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 #ifndef _EXYNOSHWCHELPER_H
17 #define _EXYNOSHWCHELPER_H
18
19 #include <drm/drm_fourcc.h>
20 #include <drm/samsung_drm.h>
21 #include <hardware/hwcomposer2.h>
22 #include <utils/String8.h>
23
24 #include <fstream>
25 #include <list>
26 #include <optional>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30
31 #include "DeconCommonHeader.h"
32 #include "VendorGraphicBuffer.h"
33 #include "VendorVideoAPI.h"
34 #include "exynos_format.h"
35 #include "exynos_sync.h"
36 #include "mali_gralloc_formats.h"
37
38 #define MAX_FENCE_NAME 64
39 #define MAX_FENCE_THRESHOLD 500
40 #define MAX_FD_NUM 1024
41
42 #define MAX_USE_FORMAT 27
43 #ifndef P010M_Y_SIZE
44 #define P010M_Y_SIZE(w,h) (__ALIGN_UP((w), 16) * 2 * __ALIGN_UP((h), 16) + 256)
45 #endif
46 #ifndef P010M_CBCR_SIZE
47 #define P010M_CBCR_SIZE(w,h) ((__ALIGN_UP((w), 16) * 2 * __ALIGN_UP((h), 16) / 2) + 256)
48 #endif
49 #ifndef P010_Y_SIZE
50 #define P010_Y_SIZE(w, h) ((w) * (h) * 2)
51 #endif
52 #ifndef P010_CBCR_SIZE
53 #define P010_CBCR_SIZE(w, h) ((w) * (h))
54 #endif
55 #ifndef DRM_FORMAT_YUV420_8BIT
56 #define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8')
57 #endif
58 #ifndef DRM_FORMAT_YUV420_10BIT
59 #define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0')
60 #endif
61
62 static constexpr uint32_t DISPLAYID_MASK_LEN = 8;
63
max(T a,T b)64 template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
min(T a,T b)65 template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
66
67 class ExynosLayer;
68 class ExynosDisplay;
69
70 using namespace android;
71
72 static constexpr uint32_t TRANSFORM_MAT_SIZE = 4*4;
73
74 enum {
75 EXYNOS_HWC_DIM_LAYER = 1 << 0,
76 EXYNOS_HWC_IGNORE_LAYER = 1 << 1,
77 };
78
79 enum {
80 INTERFACE_TYPE_NONE = 0,
81 INTERFACE_TYPE_FB = 1,
82 INTERFACE_TYPE_DRM = 2,
83 };
84
85 typedef enum format_type {
86 TYPE_UNDEF = 0,
87
88 /* format */
89 FORMAT_SHIFT = 0,
90 FORMAT_MASK = 0x00000fff,
91
92 FORMAT_RGB_MASK = 0x0000000f,
93 RGB = 0x00000001,
94
95 FORMAT_YUV_MASK = 0x000000f0,
96 YUV420 = 0x00000010,
97 YUV422 = 0x00000020,
98 P010 = 0x00000030,
99
100 FORMAT_SBWC_MASK = 0x00000f00,
101 SBWC_LOSSLESS = 0x00000100,
102 SBWC_LOSSY_40 = 0x00000200,
103 SBWC_LOSSY_50 = 0x00000300,
104 SBWC_LOSSY_60 = 0x00000400,
105 SBWC_LOSSY_75 = 0x00000500,
106 SBWC_LOSSY_80 = 0x00000600,
107
108 /* bit */
109 BIT_SHIFT = 16,
110 BIT_MASK = 0x000f0000,
111 BIT8 = 0x00010000,
112 BIT10 = 0x00020000,
113 BIT8_2 = 0x00030000,
114 BIT16 = 0x00040000,
115
116 /* Compression types */
117 /* Caution : This field use bit operations */
118 COMP_SHIFT = 20,
119 COMP_TYPE_MASK = 0x0ff00000,
120 COMP_TYPE_NONE = 0x08000000,
121 COMP_TYPE_AFBC = 0x00100000,
122 COMP_TYPE_SBWC = 0x00200000,
123 } format_type_t;
124
125 typedef struct format_description {
getFormatformat_description126 inline uint32_t getFormat() const { return type & FORMAT_MASK; }
getBitformat_description127 inline uint32_t getBit() const { return type & BIT_MASK; }
isCompressionSupportedformat_description128 inline bool isCompressionSupported(uint32_t inType) const {
129 return (type & inType) != 0 ? true : false;
130 }
131 int halFormat;
132 decon_pixel_format s3cFormat;
133 int drmFormat;
134 uint32_t planeNum;
135 uint32_t bufferNum;
136 uint8_t bpp;
137 uint32_t type;
138 bool hasAlpha;
139 String8 name;
140 uint32_t reserved;
141 } format_description_t;
142
143 constexpr int HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED = 0;
144 constexpr int DRM_FORMAT_UNDEFINED = 0;
145
146 // clang-format off
147 const format_description_t exynos_format_desc[] = {
148 /* RGB */
149 {HAL_PIXEL_FORMAT_RGBA_8888, DECON_PIXEL_FORMAT_RGBA_8888, DRM_FORMAT_RGBA8888,
150 1, 1, 32, RGB | BIT8 | COMP_TYPE_NONE | COMP_TYPE_AFBC, true, String8("RGBA_8888"), 0},
151 {HAL_PIXEL_FORMAT_RGBX_8888, DECON_PIXEL_FORMAT_RGBX_8888, DRM_FORMAT_RGBX8888,
152 1, 1, 32, RGB | BIT8 | COMP_TYPE_NONE | COMP_TYPE_AFBC, false, String8("RGBx_8888"), 0},
153 {HAL_PIXEL_FORMAT_RGB_888, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_RGB888,
154 1, 1, 24, RGB | BIT8 | COMP_TYPE_NONE | COMP_TYPE_AFBC, false, String8("RGB_888"), 0},
155 {HAL_PIXEL_FORMAT_RGB_565, DECON_PIXEL_FORMAT_RGB_565, DRM_FORMAT_BGR565,
156 1, 1, 16, RGB | COMP_TYPE_NONE, false, String8("RGB_565"), 0},
157 {HAL_PIXEL_FORMAT_RGB_565, DECON_PIXEL_FORMAT_RGB_565, DRM_FORMAT_RGB565,
158 1, 1, 16, RGB | COMP_TYPE_AFBC, false, String8("RGB_565_AFBC"), 0},
159 {HAL_PIXEL_FORMAT_BGRA_8888, DECON_PIXEL_FORMAT_BGRA_8888, DRM_FORMAT_BGRA8888,
160 1, 1, 32, RGB | BIT8 | COMP_TYPE_NONE | COMP_TYPE_AFBC, true, String8("BGRA_8888"), 0},
161 {HAL_PIXEL_FORMAT_RGBA_1010102, DECON_PIXEL_FORMAT_ABGR_2101010, DRM_FORMAT_RGBA1010102,
162 1, 1, 32, RGB | BIT10 | COMP_TYPE_NONE | COMP_TYPE_AFBC, true, String8("RGBA_1010102"), 0},
163 {HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_ARGB8888,
164 1, 1, 32, RGB | BIT8 | COMP_TYPE_NONE | COMP_TYPE_AFBC, true, String8("EXYNOS_ARGB_8888"), 0},
165 {HAL_PIXEL_FORMAT_RGBA_FP16, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_ARGB16161616F,
166 1, 1, 64, RGB | BIT16 | COMP_TYPE_NONE | COMP_TYPE_AFBC, true, String8("RGBA_FP16"), 0},
167
168 /* YUV 420 */
169 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, DECON_PIXEL_FORMAT_YUV420M, DRM_FORMAT_UNDEFINED,
170 3, 3, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_P_M"), 0},
171 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, DECON_PIXEL_FORMAT_NV12M, DRM_FORMAT_NV12,
172 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SP_M"), 0},
173 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
174 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SP_M_TILED"), 0},
175 {HAL_PIXEL_FORMAT_EXYNOS_YV12_M, DECON_PIXEL_FORMAT_YVU420M, DRM_FORMAT_UNDEFINED,
176 3, 3, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YV12_M"), 0},
177 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, DECON_PIXEL_FORMAT_NV21M, DRM_FORMAT_NV21,
178 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCrCb_420_SP_M"), 0},
179 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, DECON_PIXEL_FORMAT_NV21M, DRM_FORMAT_NV21,
180 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCrCb_420_SP_M_FULL"), 0},
181 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
182 3, 1, 0, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_P"), 0},
183 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
184 2, 1, 0, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SP"), 0},
185 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, DECON_PIXEL_FORMAT_NV12M, DRM_FORMAT_NV12,
186 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SP_M_PRIV"), 0},
187 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
188 3, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_PN"), 0},
189 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, DECON_PIXEL_FORMAT_NV12N, DRM_FORMAT_NV12,
190 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SPN"), 0},
191 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
192 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SPN_TILED"), 0},
193 {HAL_PIXEL_FORMAT_YCrCb_420_SP, DECON_PIXEL_FORMAT_NV21, DRM_FORMAT_NV21,
194 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("YCrCb_420_SP"), 0},
195 {HAL_PIXEL_FORMAT_YV12, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
196 3, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("YV12"), 0},
197 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, DECON_PIXEL_FORMAT_NV12M_S10B, DRM_FORMAT_UNDEFINED,
198 2, 2, 12, YUV420 | BIT10 | BIT8_2 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SP_M_S10B"), 0},
199 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, DECON_PIXEL_FORMAT_NV12N_10B, DRM_FORMAT_UNDEFINED,
200 2, 1, 12, YUV420 | BIT10 | BIT8_2 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_420_SPN_S10B"), 0},
201 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, DECON_PIXEL_FORMAT_NV12M_P010, DRM_FORMAT_P010,
202 2, 2, 24, YUV420 | BIT10 | P010 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_P010_M"), 0},
203 {HAL_PIXEL_FORMAT_YCBCR_P010, DECON_PIXEL_FORMAT_NV12_P010, DRM_FORMAT_P010,
204 2, 1, 24, YUV420 | BIT10 | P010 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_P010"), 0},
205 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN, DECON_PIXEL_FORMAT_NV12_P010, DRM_FORMAT_P010,
206 2, 1, 24, YUV420 | BIT10 | P010 | COMP_TYPE_NONE, false, String8("EXYNOS_YCbCr_P010_SPN"), 0},
207 {MALI_GRALLOC_FORMAT_INTERNAL_P010, DECON_PIXEL_FORMAT_NV12_P010, DRM_FORMAT_P010,
208 2, 1, 24, YUV420 | BIT10 | P010 | COMP_TYPE_NONE, false, String8("MALI_GRALLOC_FORMAT_INTERNAL_P010"), 0},
209
210 {HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_NV12,
211 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("GOOGLE_YCbCr_420_SP"), 0},
212 {HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_P010,
213 2, 1, 24, YUV420 | BIT10 | COMP_TYPE_NONE, false, String8("GOOGLE_YCbCr_P010"), 0},
214 {MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_YUV420_8BIT,
215 1, 1, 12, YUV420 | BIT8 | COMP_TYPE_AFBC, false, String8("MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I"), 0},
216 {MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_YUV420_10BIT,
217 1, 1, 15, YUV420 | BIT10 | COMP_TYPE_AFBC, false, String8("MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I"), 0},
218 {MALI_GRALLOC_FORMAT_INTERNAL_NV21, DECON_PIXEL_FORMAT_NV21, DRM_FORMAT_NV21,
219 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_NONE, false, String8("MALI_GRALLOC_FORMAT_INTERNAL_NV21"), 0},
220
221 /* YUV 422 */
222 {HAL_PIXEL_FORMAT_EXYNOS_CbYCrY_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
223 0, 0, 0, YUV422 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_CbYCrY_422_I"), 0},
224 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_SP, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
225 0, 0, 0, YUV422 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCrCb_422_SP"), 0},
226 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
227 0, 0, 0, YUV422 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_YCrCb_422_I"), 0},
228 {HAL_PIXEL_FORMAT_EXYNOS_CrYCbY_422_I, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
229 0, 0, 0, YUV422 | BIT8 | COMP_TYPE_NONE, false, String8("EXYNOS_CrYCbY_422_I"), 0},
230
231 /* SBWC formats */
232 /* NV12, YCbCr, Multi */
233 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, DECON_PIXEL_FORMAT_NV12M_SBWC_8B, DRM_FORMAT_NV12,
234 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCbCr_420_SP_M_SBWC"), 0},
235 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, DECON_PIXEL_FORMAT_NV12M_SBWC_8B_L50, DRM_FORMAT_NV12,
236 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSY_50, false, String8("EXYNOS_YCbCr_420_SP_M_SBWC_L50"), 0},
237 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, DECON_PIXEL_FORMAT_NV12M_SBWC_8B_L75, DRM_FORMAT_NV12,
238 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSY_75, false, String8("EXYNOS_YCbCr_420_SP_M_SBWC_L75"), 0},
239 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, DECON_PIXEL_FORMAT_NV12M_SBWC_10B, DRM_FORMAT_UNDEFINED,
240 2, 2, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCbCr_420_SP_M_10B_SBWC"), 0},
241 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, DECON_PIXEL_FORMAT_NV12M_SBWC_10B_L40, DRM_FORMAT_UNDEFINED,
242 2, 2, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_40, false, String8("EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40"), 0},
243 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, DECON_PIXEL_FORMAT_NV12M_SBWC_10B_L60, DRM_FORMAT_UNDEFINED,
244 2, 2, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_60, false, String8("EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60"), 0},
245 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, DECON_PIXEL_FORMAT_NV12M_SBWC_10B_L80, DRM_FORMAT_UNDEFINED,
246 2, 2, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_80, false, String8("EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80"), 0},
247
248 /* NV12, YCbCr, Single */
249 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, DECON_PIXEL_FORMAT_NV12N_SBWC_8B, DRM_FORMAT_NV12,
250 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCbCr_420_SPN_SBWC"), 0},
251 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, DECON_PIXEL_FORMAT_NV12N_SBWC_8B_L50, DRM_FORMAT_NV12,
252 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSY_50, false, String8("EXYNOS_YCbCr_420_SPN_SBWC_L50"), 0},
253 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, DECON_PIXEL_FORMAT_NV12N_SBWC_8B_L75, DRM_FORMAT_NV12,
254 2, 1, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSY_75, false, String8("EXYNOS_YCbCr_420_SPN_SBWC_75"), 0},
255 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, DECON_PIXEL_FORMAT_NV12N_SBWC_10B, DRM_FORMAT_UNDEFINED,
256 2, 1, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCbCr_420_SPN_10B_SBWC"), 0},
257 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, DECON_PIXEL_FORMAT_NV12N_SBWC_10B_L40, DRM_FORMAT_UNDEFINED,
258 2, 1, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_40, false, String8("EXYNOS_YCbCr_420_SPN_10B_SBWC_L40"), 0},
259 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, DECON_PIXEL_FORMAT_NV12N_SBWC_10B_L60, DRM_FORMAT_UNDEFINED,
260 2, 1, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_60, false, String8("EXYNOS_YCbCr_420_SPN_10B_SBWC_L60"), 0},
261 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, DECON_PIXEL_FORMAT_NV12N_SBWC_10B_L80, DRM_FORMAT_UNDEFINED,
262 2, 1, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSY_80, false, String8("EXYNOS_YCbCr_420_SPN_10B_SBWC_L80"), 0},
263
264 /* NV12, YCrCb */
265 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, DECON_PIXEL_FORMAT_NV21M_SBWC_8B, DRM_FORMAT_UNDEFINED,
266 2, 2, 12, YUV420 | BIT8 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCrCb_420_SP_M_SBWC"), 0},
267 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, DECON_PIXEL_FORMAT_NV21M_SBWC_10B, DRM_FORMAT_UNDEFINED,
268 2, 2, 12, YUV420 | BIT10 | COMP_TYPE_SBWC | SBWC_LOSSLESS, false, String8("EXYNOS_YCrbCb_420_SP_M_10B_SBWC"), 0},
269
270 {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_UNDEFINED,
271 0, 0, 0, TYPE_UNDEF | COMP_TYPE_NONE, false, String8("ImplDef"), 0},
272
273 {HAL_PIXEL_FORMAT_GOOGLE_R_8, DECON_PIXEL_FORMAT_MAX, DRM_FORMAT_C8,
274 1, 1, 8, RGB | BIT8 | COMP_TYPE_NONE, true, String8("GOOGLE_R_8"), 0},
275 };
276 // clang-format on
277
278 constexpr size_t FORMAT_MAX_CNT = sizeof(exynos_format_desc) / sizeof(format_description);
279
280 enum HwcFdebugFenceType {
281 FENCE_TYPE_SRC_RELEASE = 1,
282 FENCE_TYPE_SRC_ACQUIRE = 2,
283 FENCE_TYPE_DST_RELEASE = 3,
284 FENCE_TYPE_DST_ACQUIRE = 4,
285 FENCE_TYPE_FREE_RELEASE = 5,
286 FENCE_TYPE_FREE_ACQUIRE = 6,
287 FENCE_TYPE_HW_STATE = 7,
288 FENCE_TYPE_RETIRE = 8,
289 FENCE_TYPE_READBACK_ACQUIRE = 9,
290 FENCE_TYPE_READBACK_RELEASE = 10,
291 FENCE_TYPE_ALL = 11,
292 FENCE_TYPE_UNDEFINED = 100
293 };
294
295 enum HwcFdebugIpType {
296 FENCE_IP_DPP = 0,
297 FENCE_IP_MSC = 1,
298 FENCE_IP_G2D = 2,
299 FENCE_IP_FB = 3,
300 FENCE_IP_LAYER = 4,
301 FENCE_IP_ALL = 5,
302 FENCE_IP_UNDEFINED = 100
303 };
304
305 enum HwcFenceType {
306 FENCE_LAYER_RELEASE_DPP = 0,
307 FENCE_LAYER_RELEASE_MPP = 1,
308 FENCE_LAYER_RELEASE_MSC = 2,
309 FENCE_LAYER_RELEASE_G2D = 3,
310 FENCE_DPP_HW_STATE = 4,
311 FENCE_MSC_HW_STATE = 5,
312 FENCE_G2D_HW_STATE = 6,
313 FENCE_MSC_SRC_LAYER = 7,
314 FENCE_G2D_SRC_LAYER = 8,
315 FENCE_MPP_DST_DPP = 9,
316 FENCE_MSC_DST_DPP = 10,
317 FENCE_G2D_DST_DPP = 11,
318 FENCE_DPP_SRC_MPP = 12,
319 FENCE_DPP_SRC_MSC = 13,
320 FENCE_DPP_SRC_G2D = 14,
321 FENCE_DPP_SRC_LAYER = 15,
322 FENCE_MPP_FREE_BUF_ACQUIRE = 16,
323 FENCE_MPP_FREE_BUF_RELEASE = 17,
324 FENCE_RETIRE = 18,
325 FENCE_MAX
326 };
327
328 enum {
329 EXYNOS_ERROR_NONE = 0,
330 EXYNOS_ERROR_CHANGED = 1
331 };
332
333 enum {
334 eSkipLayer = 0x00000001,
335 eInvalidHandle = 0x00000002,
336 eHasFloatSrcCrop = 0x00000004,
337 eUpdateExynosComposition = 0x00000008,
338 eDynamicRecomposition = 0x00000010,
339 eForceFbEnabled = 0x00000020,
340 eSandwitchedBetweenGLES = 0x00000040,
341 eSandwitchedBetweenEXYNOS = 0x00000080,
342 eInsufficientWindow = 0x00000100,
343 eInsufficientMPP = 0x00000200,
344 eSkipStaticLayer = 0x00000400,
345 eUnSupportedUseCase = 0x00000800,
346 eDimLayer = 0x00001000,
347 eResourcePendingWork = 0x00002000,
348 eSkipRotateAnim = 0x00004000,
349 eUnSupportedColorTransform = 0x00008000,
350 eLowFpsLayer = 0x00010000,
351 eReallocOnGoingForDDI = 0x00020000,
352 eInvalidDispFrame = 0x00040000,
353 eExceedMaxLayerNum = 0x00080000,
354 eExceedSdrDimRatio = 0x00100000,
355 eResourceAssignFail = 0x20000000,
356 eMPPUnsupported = 0x40000000,
357 eUnknown = 0x80000000,
358 };
359
360 enum regionType {
361 eTransparentRegion = 0,
362 eCoveredOpaqueRegion = 1,
363 eDamageRegionByDamage = 2,
364 eDamageRegionByLayer = 3,
365 };
366
367 enum {
368 eDamageRegionFull = 0,
369 eDamageRegionPartial,
370 eDamageRegionSkip,
371 eDamageRegionError,
372 };
373
374 struct CompressionInfo {
375 uint32_t type = COMP_TYPE_NONE;
376 uint64_t modifier = 0;
377 };
378
379 /*
380 * bufferHandle can be NULL if it is not allocated yet
381 * or size or format information can be different between other field values and
382 * member of bufferHandle. This means bufferHandle should be reallocated.
383 * */
384 typedef struct exynos_image {
385 uint32_t fullWidth = 0;
386 uint32_t fullHeight = 0;
387 uint32_t x = 0;
388 uint32_t y = 0;
389 uint32_t w = 0;
390 uint32_t h = 0;
391 uint32_t format= 0;
392 uint64_t usageFlags = 0;
393 uint32_t layerFlags = 0;
394 int acquireFenceFd = -1;
395 int releaseFenceFd = -1;
396 buffer_handle_t bufferHandle = NULL;
397 android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
398 uint32_t blending = 0;
399 uint32_t transform = 0;
400 CompressionInfo compressionInfo;
401 float planeAlpha = 0;
402 uint32_t zOrder = 0;
403 /* refer
404 * frameworks/native/include/media/hardware/VideoAPI.h
405 * frameworks/native/include/media/hardware/HardwareAPI.h */
406 bool hasMetaParcel = false;
407 ExynosVideoMeta metaParcel;
408 ExynosVideoInfoType metaType = VIDEO_INFO_TYPE_INVALID;
409 bool needColorTransform = false;
410 bool needPreblending = false;
411
isDimLayerexynos_image412 bool isDimLayer()
413 {
414 if (layerFlags & EXYNOS_HWC_DIM_LAYER)
415 return true;
416 return false;
417 };
418 } exynos_image_t;
419
420 uint32_t getHWC1CompType(int32_t /*hwc2_composition_t*/ type);
421
422 uint32_t getDrmMode(uint64_t flags);
423 uint32_t getDrmMode(const buffer_handle_t handle);
424
WIDTH(const hwc_rect & rect)425 inline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; }
HEIGHT(const hwc_rect & rect)426 inline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; }
WIDTH(const hwc_frect_t & rect)427 inline int WIDTH(const hwc_frect_t &rect) { return (int)(rect.right - rect.left); }
HEIGHT(const hwc_frect_t & rect)428 inline int HEIGHT(const hwc_frect_t &rect) { return (int)(rect.bottom - rect.top); }
429
430 const format_description_t *halFormatToExynosFormat(int format, uint32_t compressType);
431
432 uint32_t halDataSpaceToV4L2ColorSpace(android_dataspace data_space);
433 enum decon_pixel_format halFormatToDpuFormat(int format, uint32_t compressType);
434 uint32_t DpuFormatToHalFormat(int format, uint32_t compressType);
435 int halFormatToDrmFormat(int format, uint32_t compressType);
436 int32_t drmFormatToHalFormats(int format, std::vector<uint32_t> *halFormats);
437 int drmFormatToHalFormat(int format);
438 uint8_t formatToBpp(int format);
439 uint8_t DpuFormatToBpp(decon_pixel_format format);
440 uint64_t halTransformToDrmRot(uint32_t halTransform);
441
442 bool isAFBCCompressed(const buffer_handle_t handle);
443 bool isSBWCCompressed(const buffer_handle_t handle);
444 uint32_t getFormat(const buffer_handle_t handle);
445 uint64_t getFormatModifier(const buffer_handle_t handle);
446 uint32_t getCompressionType(const buffer_handle_t handle);
447 CompressionInfo getCompressionInfo(buffer_handle_t handle);
448 String8 getCompressionStr(CompressionInfo compression);
449 bool isAFBC32x8(CompressionInfo compression);
450
451 bool isFormatRgb(int format);
452 bool isFormatYUV(int format);
453 bool isFormatYUV420(int format);
454 bool isFormatYUV422(int format);
455 bool isFormatYCrCb(int format);
456 bool isFormatYUV8_2(int format);
457 bool isFormat10BitYUV420(int format);
458 bool isFormatLossy(int format);
459 bool isFormatSBWC(int format);
460 bool isFormatP010(int format);
461 bool isFormat10Bit(int format);
462 bool isFormat8Bit(int format);
463 bool formatHasAlphaChannel(int format);
464 unsigned int isNarrowRgb(int format, android_dataspace data_space);
465 bool isSrcCropFloat(hwc_frect &frect);
466 bool isScaled(exynos_image &src, exynos_image &dst);
467 bool isScaledDown(exynos_image &src, exynos_image &dst);
468 bool hasHdrInfo(const exynos_image &img);
469 bool hasHdrInfo(android_dataspace dataSpace);
470 bool hasHdr10Plus(exynos_image &img);
471
472 void dumpExynosImage(uint32_t type, exynos_image &img);
473 void dumpExynosImage(String8& result, exynos_image &img);
474 void dumpHandle(uint32_t type, buffer_handle_t h);
475 void printExynosLayer(const ExynosLayer *layer);
476 String8 getFormatStr(int format, uint32_t compressType);
477 String8 getMPPStr(int typeId);
478 void adjustRect(hwc_rect_t &rect, int32_t width, int32_t height);
479 uint32_t getBufferNumOfFormat(int format, uint32_t compressType);
480 uint32_t getPlaneNumOfFormat(int format, uint32_t compressType);
481 uint32_t getBytePerPixelOfPrimaryPlane(int format);
482
483 int fence_close(int fence, ExynosDisplay *display, HwcFdebugFenceType type, HwcFdebugIpType ip);
484 bool fence_valid(int fence);
485
486 int hwcFdClose(int fd);
487 int hwc_dup(int fd, ExynosDisplay *display, HwcFdebugFenceType type, HwcFdebugIpType ip,
488 bool pendingAllowed = false);
489 int hwc_print_stack();
490
expand(const hwc_rect & r1,const hwc_rect & r2)491 inline hwc_rect expand(const hwc_rect &r1, const hwc_rect &r2)
492 {
493 hwc_rect i;
494 i.top = min(r1.top, r2.top);
495 i.bottom = max(r1.bottom, r2.bottom);
496 i.left = min(r1.left, r2.left);
497 i.right = max(r1.right, r2.right);
498 return i;
499 }
500
501 template <typename T>
pixel_align_down(const T x,const uint32_t a)502 inline T pixel_align_down(const T x, const uint32_t a) {
503 static_assert(std::numeric_limits<T>::is_integer,
504 "Integer type is expected as the alignment input");
505 return a ? (x / a) * a : x;
506 }
507
508 template <typename T>
pixel_align(const T x,const uint32_t a)509 inline T pixel_align(const T x, const uint32_t a) {
510 static_assert(std::numeric_limits<T>::is_integer,
511 "Integer type is expected as the alignment input");
512 return a ? ((x + a - 1) / a) * a : x;
513 }
514
515 uint32_t getExynosBufferYLength(uint32_t width, uint32_t height, int format);
516 int getBufLength(buffer_handle_t handle, uint32_t planer_num, size_t *length, int format, uint32_t width, uint32_t height);
517
518 enum class HwcFenceDirection {
519 FROM = 0,
520 TO,
521 DUP,
522 CLOSE,
523 UPDATE,
524 };
525
526 struct HwcFenceTrace {
527 HwcFenceDirection direction = HwcFenceDirection::FROM;
528 HwcFdebugFenceType type = FENCE_TYPE_UNDEFINED;
529 HwcFdebugIpType ip = FENCE_IP_UNDEFINED;
530 struct timeval time = {0, 0};
531 };
532
533 struct HwcFenceInfo {
534 uint32_t displayId = HWC_DISPLAY_PRIMARY;
535 int32_t usage = 0;
536 int32_t dupFrom = -1;
537 bool pendingAllowed = false;
538 bool leaking = false;
539 std::list<HwcFenceTrace> traces = {};
540 };
541
542 class funcReturnCallback {
543 public:
funcReturnCallback(const std::function<void (void)> cb)544 funcReturnCallback(const std::function<void(void)> cb) : mCb(cb) {}
~funcReturnCallback()545 ~funcReturnCallback() { mCb(); }
546
547 private:
548 const std::function<void(void)> mCb;
549 };
550
551 String8 getLocalTimeStr(struct timeval tv);
552
553 void setFenceName(int fenceFd, HwcFenceType fenceType);
554 void setFenceInfo(uint32_t fd, const ExynosDisplay *display, HwcFdebugFenceType type,
555 HwcFdebugIpType ip, HwcFenceDirection direction, bool pendingAllowed = false,
556 int32_t dupFrom = -1);
557
558 class FenceTracker {
559 public:
560 void updateFenceInfo(uint32_t fd, const ExynosDisplay *display, HwcFdebugFenceType type,
561 HwcFdebugIpType ip, HwcFenceDirection direction,
562 bool pendingAllowed = false, int32_t dupFrom = -1);
563 bool validateFences(ExynosDisplay *display);
564
565 private:
566 void printLastFenceInfoLocked(uint32_t fd) REQUIRES(mFenceMutex);
567 void dumpFenceInfoLocked(int32_t count) REQUIRES(mFenceMutex);
568 void printLeakFdsLocked() REQUIRES(mFenceMutex);
569 void dumpNCheckLeakLocked() REQUIRES(mFenceMutex);
570 bool fenceWarnLocked(uint32_t threshold) REQUIRES(mFenceMutex);
571 bool validateFencePerFrameLocked(const ExynosDisplay *display) REQUIRES(mFenceMutex);
572 int32_t saveFenceTraceLocked(ExynosDisplay *display) REQUIRES(mFenceMutex);
573
574 std::map<int, HwcFenceInfo> mFenceInfos GUARDED_BY(mFenceMutex);
575 mutable std::mutex mFenceMutex;
576 };
577
578 android_dataspace colorModeToDataspace(android_color_mode_t mode);
579 bool hasPPC(uint32_t physicalType, uint32_t formatIndex, uint32_t rotIndex);
580
581 class TableBuilder {
582 public:
583 template <typename T>
add(const std::string & key,const T & value)584 TableBuilder& add(const std::string& key, const T& value) {
585 std::stringstream v;
586 v << value;
587 data.emplace_back(std::make_pair(key, v.str()));
588 return *this;
589 }
590
591 template <typename T>
add(const std::string & key,const std::vector<T> & values)592 TableBuilder& add(const std::string& key, const std::vector<T>& values) {
593 std::stringstream value;
594 for (int i = 0; i < values.size(); i++) {
595 if (i) value << ", ";
596 value << values[i];
597 }
598
599 data.emplace_back(std::make_pair(key, value.str()));
600 return *this;
601 }
602
603 // Template overrides for hex integers
604 TableBuilder& add(const std::string& key, const uint64_t& value, bool toHex);
605 TableBuilder& add(const std::string& key, const std::vector<uint64_t>& values, bool toHex);
606
607 std::string build();
608
609 private:
610 std::string buildPaddedString(const std::string& str, int size);
611
612 using StringPairVec = std::vector<std::pair<std::string, std::string>>;
613 StringPairVec data;
614 };
615
616 void writeFileNode(FILE *fd, int value);
617 int32_t writeIntToFile(const char *file, uint32_t value);
getDisplayId(int32_t displayType,int32_t displayIndex)618 constexpr uint32_t getDisplayId(int32_t displayType, int32_t displayIndex) {
619 return (displayType << DISPLAYID_MASK_LEN) | displayIndex;
620 }
621
622 int32_t load_png_image(const char *filepath, buffer_handle_t buffer);
623 int readLineFromFile(const std::string &filename, std::string &out, char delim);
624
625 template <typename T>
626 struct CtrlValue {
627 public:
CtrlValueCtrlValue628 CtrlValue() : value_(), dirty_(false) {}
CtrlValueCtrlValue629 CtrlValue(const T& value) : value_(value), dirty_(false) {}
630
storeCtrlValue631 void store(T value) {
632 if (value == value_) return;
633 dirty_ = true;
634 value_ = value;
635 };
getCtrlValue636 const T &get() { return value_; };
is_dirtyCtrlValue637 bool is_dirty() { return dirty_; };
clear_dirtyCtrlValue638 void clear_dirty() { dirty_ = false; };
set_dirtyCtrlValue639 void set_dirty() { dirty_ = true; };
resetCtrlValue640 void reset(T value) { value_ = value; dirty_ = false; }
641 private:
642 T value_;
643 bool dirty_;
644 };
645
646 template <typename T>
toUnderlying(T v)647 constexpr typename std::underlying_type<T>::type toUnderlying(T v) {
648 return static_cast<typename std::underlying_type<T>::type>(v);
649 }
650
651 template <size_t bufferSize>
652 struct RollingAverage {
653 std::array<int64_t, bufferSize> buffer{0};
654 int64_t total = 0;
655 int64_t average;
656 size_t elems = 0;
657 size_t buffer_index = 0;
insertRollingAverage658 void insert(int64_t newTime) {
659 total += newTime - buffer[buffer_index];
660 buffer[buffer_index] = newTime;
661 buffer_index = (buffer_index + 1) % bufferSize;
662 elems = std::min(elems + 1, bufferSize);
663 average = total / elems;
664 }
665 };
666
667 // Waits for a given property value, or returns std::nullopt if unavailable
668 std::optional<std::string> waitForPropertyValue(const std::string &property, int64_t timeoutMs);
669
670 uint32_t rectSize(const hwc_rect_t &rect);
671 void assign(decon_win_rect &win_rect, uint32_t left, uint32_t right, uint32_t width,
672 uint32_t height);
673 #endif
674