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