xref: /aosp_15_r20/external/minigbm/cros_gralloc/gralloc4/CrosGralloc4Utils.cc (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1 /*
2  * Copyright 2020 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
8 
9 #include <array>
10 #include <unordered_map>
11 
12 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponent.h>
13 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
14 #include <android-base/stringprintf.h>
15 #include <android-base/strings.h>
16 #include <cutils/native_handle.h>
17 #include <gralloctypes/Gralloc4.h>
18 
19 #include "cros_gralloc/cros_gralloc_helpers.h"
20 
21 using aidl::android::hardware::graphics::common::PlaneLayout;
22 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
23 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
24 using android::hardware::hidl_bitfield;
25 using android::hardware::hidl_handle;
26 using android::hardware::graphics::common::V1_2::BufferUsage;
27 using android::hardware::graphics::common::V1_2::PixelFormat;
28 
29 using BufferDescriptorInfo =
30         android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
31 
getPixelFormatString(PixelFormat format)32 std::string getPixelFormatString(PixelFormat format) {
33     return android::hardware::graphics::common::V1_2::toString(format);
34 }
35 
getUsageString(hidl_bitfield<BufferUsage> bufferUsage)36 std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) {
37     static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value);
38 
39     const uint64_t usage = static_cast<uint64_t>(bufferUsage);
40     return android::hardware::graphics::common::V1_2::toString<BufferUsage>(usage);
41 }
42 
convertToDrmFormat(PixelFormat format,uint32_t * outDrmFormat)43 int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) {
44     static_assert(std::is_same<std::underlying_type<PixelFormat>::type, int32_t>::value);
45 
46     const uint32_t drmFormat = cros_gralloc_convert_format(static_cast<int32_t>(format));
47     if (drmFormat == DRM_FORMAT_NONE) return -EINVAL;
48 
49     *outDrmFormat = drmFormat;
50     return 0;
51 }
52 
convertToBufferUsage(uint64_t grallocUsage,uint64_t * outBufferUsage)53 int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) {
54     *outBufferUsage = cros_gralloc_convert_usage(grallocUsage);
55     return 0;
56 }
57 
convertToCrosDescriptor(const BufferDescriptorInfo & descriptor,struct cros_gralloc_buffer_descriptor * outCrosDescriptor)58 int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor,
59                             struct cros_gralloc_buffer_descriptor* outCrosDescriptor) {
60     outCrosDescriptor->name = descriptor.name;
61     outCrosDescriptor->width = descriptor.width;
62     outCrosDescriptor->height = descriptor.height;
63     outCrosDescriptor->droid_format = static_cast<int32_t>(descriptor.format);
64     outCrosDescriptor->droid_usage = descriptor.usage;
65     outCrosDescriptor->enable_metadata_fd = true;
66     outCrosDescriptor->client_metadata_size = descriptor.reservedSize;
67     if (descriptor.layerCount > 1) {
68         ALOGE("Failed to convert descriptor. Unsupported layerCount: %d", descriptor.layerCount);
69         return -EINVAL;
70     }
71     if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
72         std::string pixelFormatString = getPixelFormatString(descriptor.format);
73         ALOGE("Failed to convert descriptor. Unsupported format %s", pixelFormatString.c_str());
74         return -EINVAL;
75     }
76     if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
77         std::string usageString = getUsageString(descriptor.usage);
78         ALOGE("Failed to convert descriptor. Unsupported usage flags %s", usageString.c_str());
79         return -EINVAL;
80     }
81     return 0;
82 }
83 
convertToMapUsage(uint64_t grallocUsage,uint32_t * outMapUsage)84 int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
85     *outMapUsage = cros_gralloc_convert_map_usage(grallocUsage);
86     return 0;
87 }
88 
convertToFenceFd(const hidl_handle & fenceHandle,int * outFenceFd)89 int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
90     if (!outFenceFd) {
91         return -EINVAL;
92     }
93 
94     const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
95     if (nativeHandle && nativeHandle->numFds > 1) {
96         return -EINVAL;
97     }
98 
99     *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
100     return 0;
101 }
102 
convertToFenceHandle(int fenceFd,char * nativeHandleStorage)103 hidl_handle convertToFenceHandle(int fenceFd, char* nativeHandleStorage) {
104     native_handle_t* nativeHandle = nullptr;
105     if (fenceFd >= 0) {
106         nativeHandle = native_handle_init(nativeHandleStorage, 1, 0);
107         nativeHandle->data[0] = fenceFd;
108     }
109     return hidl_handle(nativeHandle);
110 }
111 
GetPlaneLayoutsMap()112 const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
113     static const auto* kPlaneLayoutsMap =
114             new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
115                     {DRM_FORMAT_ABGR8888,
116                      {{
117                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
118                                              .offsetInBits = 0,
119                                              .sizeInBits = 8},
120                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
121                                              .offsetInBits = 8,
122                                              .sizeInBits = 8},
123                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
124                                              .offsetInBits = 16,
125                                              .sizeInBits = 8},
126                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
127                                              .offsetInBits = 24,
128                                              .sizeInBits = 8}},
129                              .sampleIncrementInBits = 32,
130                              .horizontalSubsampling = 1,
131                              .verticalSubsampling = 1,
132                      }}},
133 
134                     {DRM_FORMAT_ABGR2101010,
135                      {{
136                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
137                                              .offsetInBits = 0,
138                                              .sizeInBits = 10},
139                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
140                                              .offsetInBits = 10,
141                                              .sizeInBits = 10},
142                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
143                                              .offsetInBits = 20,
144                                              .sizeInBits = 10},
145                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
146                                              .offsetInBits = 30,
147                                              .sizeInBits = 2}},
148                              .sampleIncrementInBits = 32,
149                              .horizontalSubsampling = 1,
150                              .verticalSubsampling = 1,
151                      }}},
152 
153                     {DRM_FORMAT_ABGR16161616F,
154                      {{
155                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
156                                              .offsetInBits = 0,
157                                              .sizeInBits = 16},
158                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
159                                              .offsetInBits = 16,
160                                              .sizeInBits = 16},
161                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
162                                              .offsetInBits = 32,
163                                              .sizeInBits = 16},
164                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
165                                              .offsetInBits = 48,
166                                              .sizeInBits = 16}},
167                              .sampleIncrementInBits = 64,
168                              .horizontalSubsampling = 1,
169                              .verticalSubsampling = 1,
170                      }}},
171 
172                     {DRM_FORMAT_ARGB8888,
173                      {{
174                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
175                                              .offsetInBits = 0,
176                                              .sizeInBits = 8},
177                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
178                                              .offsetInBits = 8,
179                                              .sizeInBits = 8},
180                                             {.type = android::gralloc4::PlaneLayoutComponentType_R,
181                                              .offsetInBits = 16,
182                                              .sizeInBits = 8},
183                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
184                                              .offsetInBits = 24,
185                                              .sizeInBits = 8}},
186                              .sampleIncrementInBits = 32,
187                              .horizontalSubsampling = 1,
188                              .verticalSubsampling = 1,
189                      }}},
190 
191                     {DRM_FORMAT_NV12,
192                      {{
193                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
194                                               .offsetInBits = 0,
195                                               .sizeInBits = 8}},
196                               .sampleIncrementInBits = 8,
197                               .horizontalSubsampling = 1,
198                               .verticalSubsampling = 1,
199                       },
200                       {
201                               .components =
202                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
203                                         .offsetInBits = 0,
204                                         .sizeInBits = 8},
205                                        {.type = android::gralloc4::PlaneLayoutComponentType_CR,
206                                         .offsetInBits = 8,
207                                         .sizeInBits = 8}},
208                               .sampleIncrementInBits = 16,
209                               .horizontalSubsampling = 2,
210                               .verticalSubsampling = 2,
211                       }}},
212 
213                     {DRM_FORMAT_NV21,
214                      {{
215                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
216                                               .offsetInBits = 0,
217                                               .sizeInBits = 8}},
218                               .sampleIncrementInBits = 8,
219                               .horizontalSubsampling = 1,
220                               .verticalSubsampling = 1,
221                       },
222                       {
223                               .components =
224                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
225                                         .offsetInBits = 0,
226                                         .sizeInBits = 8},
227                                        {.type = android::gralloc4::PlaneLayoutComponentType_CB,
228                                         .offsetInBits = 8,
229                                         .sizeInBits = 8}},
230                               .sampleIncrementInBits = 16,
231                               .horizontalSubsampling = 2,
232                               .verticalSubsampling = 2,
233                       }}},
234 
235                     {DRM_FORMAT_P010,
236                      {{
237                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
238                                               .offsetInBits = 6,
239                                               .sizeInBits = 10}},
240                               .sampleIncrementInBits = 16,
241                               .horizontalSubsampling = 1,
242                               .verticalSubsampling = 1,
243                       },
244                       {
245                               .components =
246                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
247                                         .offsetInBits = 6,
248                                         .sizeInBits = 10},
249                                        {.type = android::gralloc4::PlaneLayoutComponentType_CR,
250                                         .offsetInBits = 22,
251                                         .sizeInBits = 10}},
252                               .sampleIncrementInBits = 32,
253                               .horizontalSubsampling = 2,
254                               .verticalSubsampling = 2,
255                       }}},
256 
257                     {DRM_FORMAT_R8,
258                      {{
259                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
260                                              .offsetInBits = 0,
261                                              .sizeInBits = 8}},
262                              .sampleIncrementInBits = 8,
263                              .horizontalSubsampling = 1,
264                              .verticalSubsampling = 1,
265                      }}},
266 
267                     {DRM_FORMAT_R16,
268                      {{
269                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
270                                              .offsetInBits = 0,
271                                              .sizeInBits = 16}},
272                              .sampleIncrementInBits = 16,
273                              .horizontalSubsampling = 1,
274                              .verticalSubsampling = 1,
275                      }}},
276 
277                     {DRM_FORMAT_RGB565,
278                      {{
279                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
280                                              .offsetInBits = 0,
281                                              .sizeInBits = 5},
282                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
283                                              .offsetInBits = 5,
284                                              .sizeInBits = 6},
285                                             {.type = android::gralloc4::PlaneLayoutComponentType_R,
286                                              .offsetInBits = 11,
287                                              .sizeInBits = 5}},
288                              .sampleIncrementInBits = 16,
289                              .horizontalSubsampling = 1,
290                              .verticalSubsampling = 1,
291                      }}},
292 
293                     {DRM_FORMAT_BGR888,
294                      {{
295                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
296                                              .offsetInBits = 0,
297                                              .sizeInBits = 8},
298                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
299                                              .offsetInBits = 8,
300                                              .sizeInBits = 8},
301                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
302                                              .offsetInBits = 16,
303                                              .sizeInBits = 8}},
304                              .sampleIncrementInBits = 24,
305                              .horizontalSubsampling = 1,
306                              .verticalSubsampling = 1,
307                      }}},
308 
309                     {DRM_FORMAT_XBGR8888,
310                      {{
311                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
312                                              .offsetInBits = 0,
313                                              .sizeInBits = 8},
314                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
315                                              .offsetInBits = 8,
316                                              .sizeInBits = 8},
317                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
318                                              .offsetInBits = 16,
319                                              .sizeInBits = 8}},
320                              .sampleIncrementInBits = 32,
321                              .horizontalSubsampling = 1,
322                              .verticalSubsampling = 1,
323                      }}},
324 
325                     {DRM_FORMAT_YVU420,
326                      {
327                              {
328                                      .components = {{.type = android::gralloc4::
329                                                              PlaneLayoutComponentType_Y,
330                                                      .offsetInBits = 0,
331                                                      .sizeInBits = 8}},
332                                      .sampleIncrementInBits = 8,
333                                      .horizontalSubsampling = 1,
334                                      .verticalSubsampling = 1,
335                              },
336                              {
337                                      .components = {{.type = android::gralloc4::
338                                                              PlaneLayoutComponentType_CR,
339                                                      .offsetInBits = 0,
340                                                      .sizeInBits = 8}},
341                                      .sampleIncrementInBits = 8,
342                                      .horizontalSubsampling = 2,
343                                      .verticalSubsampling = 2,
344                              },
345                              {
346                                      .components = {{.type = android::gralloc4::
347                                                              PlaneLayoutComponentType_CB,
348                                                      .offsetInBits = 0,
349                                                      .sizeInBits = 8}},
350                                      .sampleIncrementInBits = 8,
351                                      .horizontalSubsampling = 2,
352                                      .verticalSubsampling = 2,
353                              },
354                      }},
355 
356                     {DRM_FORMAT_YVU420_ANDROID,
357                      {
358                              {
359                                      .components = {{.type = android::gralloc4::
360                                                              PlaneLayoutComponentType_Y,
361                                                      .offsetInBits = 0,
362                                                      .sizeInBits = 8}},
363                                      .sampleIncrementInBits = 8,
364                                      .horizontalSubsampling = 1,
365                                      .verticalSubsampling = 1,
366                              },
367                              {
368                                      .components = {{.type = android::gralloc4::
369                                                              PlaneLayoutComponentType_CR,
370                                                      .offsetInBits = 0,
371                                                      .sizeInBits = 8}},
372                                      .sampleIncrementInBits = 8,
373                                      .horizontalSubsampling = 2,
374                                      .verticalSubsampling = 2,
375                              },
376                              {
377                                      .components = {{.type = android::gralloc4::
378                                                              PlaneLayoutComponentType_CB,
379                                                      .offsetInBits = 0,
380                                                      .sizeInBits = 8}},
381                                      .sampleIncrementInBits = 8,
382                                      .horizontalSubsampling = 2,
383                                      .verticalSubsampling = 2,
384                              },
385                      }},
386             });
387     return *kPlaneLayoutsMap;
388 }
389 
getPlaneLayouts(uint32_t drmFormat,std::vector<PlaneLayout> * outPlaneLayouts)390 int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
391     const auto& planeLayoutsMap = GetPlaneLayoutsMap();
392     const auto it = planeLayoutsMap.find(drmFormat);
393     if (it == planeLayoutsMap.end()) {
394         ALOGE("Unknown plane layout for format %d", drmFormat);
395         return -EINVAL;
396     }
397 
398     *outPlaneLayouts = it->second;
399     return 0;
400 }
401