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