• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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->reserved_region_size = descriptor.reservedSize;
66     if (descriptor.layerCount > 1) {
67         ALOGE("Failed to convert descriptor. Unsupported layerCount: %d", descriptor.layerCount);
68         return -EINVAL;
69     }
70     if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
71         std::string pixelFormatString = getPixelFormatString(descriptor.format);
72         ALOGE("Failed to convert descriptor. Unsupported format %s", pixelFormatString.c_str());
73         return -EINVAL;
74     }
75     if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
76         std::string usageString = getUsageString(descriptor.usage);
77         ALOGE("Failed to convert descriptor. Unsupported usage flags %s", usageString.c_str());
78         return -EINVAL;
79     }
80     return 0;
81 }
82 
convertToMapUsage(uint64_t grallocUsage,uint32_t * outMapUsage)83 int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
84     *outMapUsage = cros_gralloc_convert_map_usage(grallocUsage);
85     return 0;
86 }
87 
convertToFenceFd(const hidl_handle & fenceHandle,int * outFenceFd)88 int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
89     if (!outFenceFd) {
90         return -EINVAL;
91     }
92 
93     const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
94     if (nativeHandle && nativeHandle->numFds > 1) {
95         return -EINVAL;
96     }
97 
98     *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
99     return 0;
100 }
101 
convertToFenceHandle(int fenceFd,hidl_handle * outFenceHandle)102 int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) {
103     if (!outFenceHandle) {
104         return -EINVAL;
105     }
106     if (fenceFd < 0) {
107         return 0;
108     }
109 
110     NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0);
111     auto fenceHandle = native_handle_init(handleStorage, 1, 0);
112     fenceHandle->data[0] = fenceFd;
113 
114     *outFenceHandle = fenceHandle;
115     return 0;
116 }
117 
GetPlaneLayoutsMap()118 const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
119     static const auto* kPlaneLayoutsMap =
120             new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
121                     {DRM_FORMAT_ABGR8888,
122                      {{
123                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
124                                              .offsetInBits = 0,
125                                              .sizeInBits = 8},
126                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
127                                              .offsetInBits = 8,
128                                              .sizeInBits = 8},
129                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
130                                              .offsetInBits = 16,
131                                              .sizeInBits = 8},
132                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
133                                              .offsetInBits = 24,
134                                              .sizeInBits = 8}},
135                              .sampleIncrementInBits = 32,
136                              .horizontalSubsampling = 1,
137                              .verticalSubsampling = 1,
138                      }}},
139 
140                     {DRM_FORMAT_ABGR2101010,
141                      {{
142                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
143                                              .offsetInBits = 0,
144                                              .sizeInBits = 10},
145                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
146                                              .offsetInBits = 10,
147                                              .sizeInBits = 10},
148                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
149                                              .offsetInBits = 20,
150                                              .sizeInBits = 10},
151                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
152                                              .offsetInBits = 30,
153                                              .sizeInBits = 2}},
154                              .sampleIncrementInBits = 32,
155                              .horizontalSubsampling = 1,
156                              .verticalSubsampling = 1,
157                      }}},
158 
159                     {DRM_FORMAT_ABGR16161616F,
160                      {{
161                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
162                                              .offsetInBits = 0,
163                                              .sizeInBits = 16},
164                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
165                                              .offsetInBits = 16,
166                                              .sizeInBits = 16},
167                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
168                                              .offsetInBits = 32,
169                                              .sizeInBits = 16},
170                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
171                                              .offsetInBits = 48,
172                                              .sizeInBits = 16}},
173                              .sampleIncrementInBits = 64,
174                              .horizontalSubsampling = 1,
175                              .verticalSubsampling = 1,
176                      }}},
177 
178                     {DRM_FORMAT_ARGB8888,
179                      {{
180                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
181                                              .offsetInBits = 0,
182                                              .sizeInBits = 8},
183                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
184                                              .offsetInBits = 8,
185                                              .sizeInBits = 8},
186                                             {.type = android::gralloc4::PlaneLayoutComponentType_R,
187                                              .offsetInBits = 16,
188                                              .sizeInBits = 8},
189                                             {.type = android::gralloc4::PlaneLayoutComponentType_A,
190                                              .offsetInBits = 24,
191                                              .sizeInBits = 8}},
192                              .sampleIncrementInBits = 32,
193                              .horizontalSubsampling = 1,
194                              .verticalSubsampling = 1,
195                      }}},
196 
197                     {DRM_FORMAT_NV12,
198                      {{
199                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
200                                               .offsetInBits = 0,
201                                               .sizeInBits = 8}},
202                               .sampleIncrementInBits = 8,
203                               .horizontalSubsampling = 1,
204                               .verticalSubsampling = 1,
205                       },
206                       {
207                               .components =
208                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
209                                         .offsetInBits = 0,
210                                         .sizeInBits = 8},
211                                        {.type = android::gralloc4::PlaneLayoutComponentType_CR,
212                                         .offsetInBits = 8,
213                                         .sizeInBits = 8}},
214                               .sampleIncrementInBits = 16,
215                               .horizontalSubsampling = 2,
216                               .verticalSubsampling = 2,
217                       }}},
218 
219                     {DRM_FORMAT_NV21,
220                      {{
221                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
222                                               .offsetInBits = 0,
223                                               .sizeInBits = 8}},
224                               .sampleIncrementInBits = 8,
225                               .horizontalSubsampling = 1,
226                               .verticalSubsampling = 1,
227                       },
228                       {
229                               .components =
230                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
231                                         .offsetInBits = 0,
232                                         .sizeInBits = 8},
233                                        {.type = android::gralloc4::PlaneLayoutComponentType_CB,
234                                         .offsetInBits = 8,
235                                         .sizeInBits = 8}},
236                               .sampleIncrementInBits = 16,
237                               .horizontalSubsampling = 2,
238                               .verticalSubsampling = 2,
239                       }}},
240 
241                     {DRM_FORMAT_P010,
242                      {{
243                               .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
244                                               .offsetInBits = 6,
245                                               .sizeInBits = 10}},
246                               .sampleIncrementInBits = 16,
247                               .horizontalSubsampling = 1,
248                               .verticalSubsampling = 1,
249                       },
250                       {
251                               .components =
252                                       {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
253                                         .offsetInBits = 6,
254                                         .sizeInBits = 10},
255                                        {.type = android::gralloc4::PlaneLayoutComponentType_CR,
256                                         .offsetInBits = 22,
257                                         .sizeInBits = 10}},
258                               .sampleIncrementInBits = 32,
259                               .horizontalSubsampling = 2,
260                               .verticalSubsampling = 2,
261                       }}},
262 
263                     {DRM_FORMAT_R8,
264                      {{
265                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
266                                              .offsetInBits = 0,
267                                              .sizeInBits = 8}},
268                              .sampleIncrementInBits = 8,
269                              .horizontalSubsampling = 1,
270                              .verticalSubsampling = 1,
271                      }}},
272 
273                     {DRM_FORMAT_R16,
274                      {{
275                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
276                                              .offsetInBits = 0,
277                                              .sizeInBits = 16}},
278                              .sampleIncrementInBits = 16,
279                              .horizontalSubsampling = 1,
280                              .verticalSubsampling = 1,
281                      }}},
282 
283                     {DRM_FORMAT_RGB565,
284                      {{
285                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
286                                              .offsetInBits = 0,
287                                              .sizeInBits = 5},
288                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
289                                              .offsetInBits = 5,
290                                              .sizeInBits = 6},
291                                             {.type = android::gralloc4::PlaneLayoutComponentType_R,
292                                              .offsetInBits = 11,
293                                              .sizeInBits = 5}},
294                              .sampleIncrementInBits = 16,
295                              .horizontalSubsampling = 1,
296                              .verticalSubsampling = 1,
297                      }}},
298 
299                     {DRM_FORMAT_BGR888,
300                      {{
301                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
302                                              .offsetInBits = 0,
303                                              .sizeInBits = 8},
304                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
305                                              .offsetInBits = 8,
306                                              .sizeInBits = 8},
307                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
308                                              .offsetInBits = 16,
309                                              .sizeInBits = 8}},
310                              .sampleIncrementInBits = 24,
311                              .horizontalSubsampling = 1,
312                              .verticalSubsampling = 1,
313                      }}},
314 
315                     {DRM_FORMAT_XBGR8888,
316                      {{
317                              .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
318                                              .offsetInBits = 0,
319                                              .sizeInBits = 8},
320                                             {.type = android::gralloc4::PlaneLayoutComponentType_G,
321                                              .offsetInBits = 8,
322                                              .sizeInBits = 8},
323                                             {.type = android::gralloc4::PlaneLayoutComponentType_B,
324                                              .offsetInBits = 16,
325                                              .sizeInBits = 8}},
326                              .sampleIncrementInBits = 32,
327                              .horizontalSubsampling = 1,
328                              .verticalSubsampling = 1,
329                      }}},
330 
331                     {DRM_FORMAT_YVU420,
332                      {
333                              {
334                                      .components = {{.type = android::gralloc4::
335                                                              PlaneLayoutComponentType_Y,
336                                                      .offsetInBits = 0,
337                                                      .sizeInBits = 8}},
338                                      .sampleIncrementInBits = 8,
339                                      .horizontalSubsampling = 1,
340                                      .verticalSubsampling = 1,
341                              },
342                              {
343                                      .components = {{.type = android::gralloc4::
344                                                              PlaneLayoutComponentType_CR,
345                                                      .offsetInBits = 0,
346                                                      .sizeInBits = 8}},
347                                      .sampleIncrementInBits = 8,
348                                      .horizontalSubsampling = 2,
349                                      .verticalSubsampling = 2,
350                              },
351                              {
352                                      .components = {{.type = android::gralloc4::
353                                                              PlaneLayoutComponentType_CB,
354                                                      .offsetInBits = 0,
355                                                      .sizeInBits = 8}},
356                                      .sampleIncrementInBits = 8,
357                                      .horizontalSubsampling = 2,
358                                      .verticalSubsampling = 2,
359                              },
360                      }},
361 
362                     {DRM_FORMAT_YVU420_ANDROID,
363                      {
364                              {
365                                      .components = {{.type = android::gralloc4::
366                                                              PlaneLayoutComponentType_Y,
367                                                      .offsetInBits = 0,
368                                                      .sizeInBits = 8}},
369                                      .sampleIncrementInBits = 8,
370                                      .horizontalSubsampling = 1,
371                                      .verticalSubsampling = 1,
372                              },
373                              {
374                                      .components = {{.type = android::gralloc4::
375                                                              PlaneLayoutComponentType_CR,
376                                                      .offsetInBits = 0,
377                                                      .sizeInBits = 8}},
378                                      .sampleIncrementInBits = 8,
379                                      .horizontalSubsampling = 2,
380                                      .verticalSubsampling = 2,
381                              },
382                              {
383                                      .components = {{.type = android::gralloc4::
384                                                              PlaneLayoutComponentType_CB,
385                                                      .offsetInBits = 0,
386                                                      .sizeInBits = 8}},
387                                      .sampleIncrementInBits = 8,
388                                      .horizontalSubsampling = 2,
389                                      .verticalSubsampling = 2,
390                              },
391                      }},
392             });
393     return *kPlaneLayoutsMap;
394 }
395 
getPlaneLayouts(uint32_t drmFormat,std::vector<PlaneLayout> * outPlaneLayouts)396 int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
397     const auto& planeLayoutsMap = GetPlaneLayoutsMap();
398     const auto it = planeLayoutsMap.find(drmFormat);
399     if (it == planeLayoutsMap.end()) {
400         ALOGE("Unknown plane layout for format %d", drmFormat);
401         return -EINVAL;
402     }
403 
404     *outPlaneLayouts = it->second;
405     return 0;
406 }
407