blob: 0817baa11c4152e86bbc671d1fb77cc078ca8a3a [file] [log] [blame]
Jason Macnak2a77d942020-09-10 10:57:46 -07001/*
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
21using aidl::android::hardware::graphics::common::PlaneLayout;
22using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
23using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
24using android::hardware::hidl_bitfield;
25using android::hardware::hidl_handle;
26using android::hardware::graphics::common::V1_2::BufferUsage;
27using android::hardware::graphics::common::V1_2::PixelFormat;
28
29using BufferDescriptorInfo =
30 android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
31
Jason Macnak2a77d942020-09-10 10:57:46 -070032std::string getPixelFormatString(PixelFormat format) {
Yiwei Zhang3c8db482021-09-14 20:10:07 +000033 return android::hardware::graphics::common::V1_2::toString(format);
Jason Macnak2a77d942020-09-10 10:57:46 -070034}
35
36std::string getUsageString(hidl_bitfield<BufferUsage> bufferUsage) {
Yiwei Zhang3c8db482021-09-14 20:10:07 +000037 static_assert(std::is_same<std::underlying_type<BufferUsage>::type, uint64_t>::value);
Jason Macnak2a77d942020-09-10 10:57:46 -070038
Yiwei Zhang3c8db482021-09-14 20:10:07 +000039 const uint64_t usage = static_cast<uint64_t>(bufferUsage);
40 return android::hardware::graphics::common::V1_2::toString<BufferUsage>(usage);
Jason Macnak2a77d942020-09-10 10:57:46 -070041}
42
43int convertToDrmFormat(PixelFormat format, uint32_t* outDrmFormat) {
44 switch (format) {
45 case PixelFormat::BGRA_8888:
46 *outDrmFormat = DRM_FORMAT_ARGB8888;
47 return 0;
48 /**
49 * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers
50 * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width
51 * equal to their size in bytes.
52 */
53 case PixelFormat::BLOB:
54 *outDrmFormat = DRM_FORMAT_R8;
55 return 0;
56 case PixelFormat::DEPTH_16:
57 return -EINVAL;
58 case PixelFormat::DEPTH_24:
59 return -EINVAL;
60 case PixelFormat::DEPTH_24_STENCIL_8:
61 return -EINVAL;
62 case PixelFormat::DEPTH_32F:
63 return -EINVAL;
64 case PixelFormat::DEPTH_32F_STENCIL_8:
65 return -EINVAL;
66 case PixelFormat::HSV_888:
67 return -EINVAL;
68 case PixelFormat::IMPLEMENTATION_DEFINED:
69 *outDrmFormat = DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED;
70 return 0;
71 case PixelFormat::RAW10:
72 return -EINVAL;
73 case PixelFormat::RAW12:
74 return -EINVAL;
75 case PixelFormat::RAW16:
76 *outDrmFormat = DRM_FORMAT_R16;
77 return 0;
78 /* TODO use blob */
79 case PixelFormat::RAW_OPAQUE:
80 return -EINVAL;
81 case PixelFormat::RGBA_1010102:
82 *outDrmFormat = DRM_FORMAT_ABGR2101010;
83 return 0;
84 case PixelFormat::RGBA_8888:
85 *outDrmFormat = DRM_FORMAT_ABGR8888;
86 return 0;
87 case PixelFormat::RGBA_FP16:
88 *outDrmFormat = DRM_FORMAT_ABGR16161616F;
89 return 0;
90 case PixelFormat::RGBX_8888:
91 *outDrmFormat = DRM_FORMAT_XBGR8888;
92 return 0;
93 case PixelFormat::RGB_565:
94 *outDrmFormat = DRM_FORMAT_RGB565;
95 return 0;
96 case PixelFormat::RGB_888:
97 *outDrmFormat = DRM_FORMAT_RGB888;
98 return 0;
99 case PixelFormat::STENCIL_8:
100 return -EINVAL;
101 case PixelFormat::Y16:
102 *outDrmFormat = DRM_FORMAT_R16;
103 return 0;
104 case PixelFormat::Y8:
105 *outDrmFormat = DRM_FORMAT_R8;
106 return 0;
107 case PixelFormat::YCBCR_420_888:
108 *outDrmFormat = DRM_FORMAT_FLEX_YCbCr_420_888;
109 return 0;
110 case PixelFormat::YCBCR_422_SP:
111 return -EINVAL;
112 case PixelFormat::YCBCR_422_I:
113 return -EINVAL;
114 case PixelFormat::YCBCR_P010:
115 *outDrmFormat = DRM_FORMAT_P010;
116 return 0;
117 case PixelFormat::YCRCB_420_SP:
118 *outDrmFormat = DRM_FORMAT_NV21;
119 return 0;
120 case PixelFormat::YV12:
121 *outDrmFormat = DRM_FORMAT_YVU420_ANDROID;
122 return 0;
123 };
124 return -EINVAL;
125}
126
127int convertToBufferUsage(uint64_t grallocUsage, uint64_t* outBufferUsage) {
Yiwei Zhang6b894b12021-09-16 22:28:22 +0000128 *outBufferUsage = cros_gralloc_convert_usage(grallocUsage);
Jason Macnak2a77d942020-09-10 10:57:46 -0700129 return 0;
130}
131
132int convertToCrosDescriptor(const BufferDescriptorInfo& descriptor,
133 struct cros_gralloc_buffer_descriptor* outCrosDescriptor) {
134 outCrosDescriptor->name = descriptor.name;
135 outCrosDescriptor->width = descriptor.width;
136 outCrosDescriptor->height = descriptor.height;
137 outCrosDescriptor->droid_format = static_cast<int32_t>(descriptor.format);
138 outCrosDescriptor->droid_usage = descriptor.usage;
139 outCrosDescriptor->reserved_region_size = descriptor.reservedSize;
Jason Macnak07f62092020-12-10 11:42:54 -0800140 if (descriptor.layerCount > 1) {
141 drv_log("Failed to convert descriptor. Unsupported layerCount: %d\n",
142 descriptor.layerCount);
Gurchetan Singhcadc54f2021-02-01 12:03:11 -0800143 return -EINVAL;
Jason Macnak07f62092020-12-10 11:42:54 -0800144 }
Jason Macnak2a77d942020-09-10 10:57:46 -0700145 if (convertToDrmFormat(descriptor.format, &outCrosDescriptor->drm_format)) {
146 std::string pixelFormatString = getPixelFormatString(descriptor.format);
Jason Macnak07f62092020-12-10 11:42:54 -0800147 drv_log("Failed to convert descriptor. Unsupported format %s\n", pixelFormatString.c_str());
Gurchetan Singhcadc54f2021-02-01 12:03:11 -0800148 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -0700149 }
150 if (convertToBufferUsage(descriptor.usage, &outCrosDescriptor->use_flags)) {
151 std::string usageString = getUsageString(descriptor.usage);
152 drv_log("Failed to convert descriptor. Unsupported usage flags %s\n", usageString.c_str());
Gurchetan Singhcadc54f2021-02-01 12:03:11 -0800153 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -0700154 }
155 return 0;
156}
157
158int convertToMapUsage(uint64_t grallocUsage, uint32_t* outMapUsage) {
159 uint32_t mapUsage = BO_MAP_NONE;
160
161 if (grallocUsage & BufferUsage::CPU_READ_MASK) {
162 mapUsage |= BO_MAP_READ;
163 }
164 if (grallocUsage & BufferUsage::CPU_WRITE_MASK) {
165 mapUsage |= BO_MAP_WRITE;
166 }
167
168 *outMapUsage = mapUsage;
169 return 0;
170}
171
172int convertToFenceFd(const hidl_handle& fenceHandle, int* outFenceFd) {
173 if (!outFenceFd) {
174 return -EINVAL;
175 }
176
177 const native_handle_t* nativeHandle = fenceHandle.getNativeHandle();
178 if (nativeHandle && nativeHandle->numFds > 1) {
179 return -EINVAL;
180 }
181
182 *outFenceFd = (nativeHandle && nativeHandle->numFds == 1) ? nativeHandle->data[0] : -1;
183 return 0;
184}
185
186int convertToFenceHandle(int fenceFd, hidl_handle* outFenceHandle) {
187 if (!outFenceHandle) {
188 return -EINVAL;
189 }
190 if (fenceFd < 0) {
191 return 0;
192 }
193
194 NATIVE_HANDLE_DECLARE_STORAGE(handleStorage, 1, 0);
195 auto fenceHandle = native_handle_init(handleStorage, 1, 0);
196 fenceHandle->data[0] = fenceFd;
197
198 *outFenceHandle = fenceHandle;
199 return 0;
200}
201
202const std::unordered_map<uint32_t, std::vector<PlaneLayout>>& GetPlaneLayoutsMap() {
203 static const auto* kPlaneLayoutsMap =
204 new std::unordered_map<uint32_t, std::vector<PlaneLayout>>({
205 {DRM_FORMAT_ABGR8888,
206 {{
207 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
208 .offsetInBits = 0,
209 .sizeInBits = 8},
210 {.type = android::gralloc4::PlaneLayoutComponentType_G,
211 .offsetInBits = 8,
212 .sizeInBits = 8},
213 {.type = android::gralloc4::PlaneLayoutComponentType_B,
214 .offsetInBits = 16,
215 .sizeInBits = 8},
216 {.type = android::gralloc4::PlaneLayoutComponentType_A,
217 .offsetInBits = 24,
218 .sizeInBits = 8}},
219 .sampleIncrementInBits = 32,
220 .horizontalSubsampling = 1,
221 .verticalSubsampling = 1,
222 }}},
223
224 {DRM_FORMAT_ABGR2101010,
225 {{
226 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
227 .offsetInBits = 0,
228 .sizeInBits = 10},
229 {.type = android::gralloc4::PlaneLayoutComponentType_G,
230 .offsetInBits = 10,
231 .sizeInBits = 10},
232 {.type = android::gralloc4::PlaneLayoutComponentType_B,
233 .offsetInBits = 20,
234 .sizeInBits = 10},
235 {.type = android::gralloc4::PlaneLayoutComponentType_A,
236 .offsetInBits = 30,
237 .sizeInBits = 2}},
238 .sampleIncrementInBits = 32,
239 .horizontalSubsampling = 1,
240 .verticalSubsampling = 1,
241 }}},
242
243 {DRM_FORMAT_ABGR16161616F,
244 {{
245 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
246 .offsetInBits = 0,
247 .sizeInBits = 16},
248 {.type = android::gralloc4::PlaneLayoutComponentType_G,
249 .offsetInBits = 16,
250 .sizeInBits = 16},
251 {.type = android::gralloc4::PlaneLayoutComponentType_B,
252 .offsetInBits = 32,
253 .sizeInBits = 16},
254 {.type = android::gralloc4::PlaneLayoutComponentType_A,
255 .offsetInBits = 48,
256 .sizeInBits = 16}},
257 .sampleIncrementInBits = 64,
258 .horizontalSubsampling = 1,
259 .verticalSubsampling = 1,
260 }}},
261
262 {DRM_FORMAT_ARGB8888,
263 {{
264 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
265 .offsetInBits = 0,
266 .sizeInBits = 8},
267 {.type = android::gralloc4::PlaneLayoutComponentType_G,
268 .offsetInBits = 8,
269 .sizeInBits = 8},
270 {.type = android::gralloc4::PlaneLayoutComponentType_R,
271 .offsetInBits = 16,
272 .sizeInBits = 8},
273 {.type = android::gralloc4::PlaneLayoutComponentType_A,
274 .offsetInBits = 24,
275 .sizeInBits = 8}},
276 .sampleIncrementInBits = 32,
277 .horizontalSubsampling = 1,
278 .verticalSubsampling = 1,
279 }}},
280
281 {DRM_FORMAT_NV12,
282 {{
283 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
284 .offsetInBits = 0,
285 .sizeInBits = 8}},
286 .sampleIncrementInBits = 8,
287 .horizontalSubsampling = 1,
288 .verticalSubsampling = 1,
289 },
290 {
291 .components =
292 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
293 .offsetInBits = 0,
294 .sizeInBits = 8},
295 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
296 .offsetInBits = 8,
297 .sizeInBits = 8}},
298 .sampleIncrementInBits = 16,
299 .horizontalSubsampling = 2,
300 .verticalSubsampling = 2,
301 }}},
302
303 {DRM_FORMAT_NV21,
304 {{
305 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
306 .offsetInBits = 0,
307 .sizeInBits = 8}},
308 .sampleIncrementInBits = 8,
309 .horizontalSubsampling = 1,
310 .verticalSubsampling = 1,
311 },
312 {
313 .components =
314 {{.type = android::gralloc4::PlaneLayoutComponentType_CR,
315 .offsetInBits = 0,
316 .sizeInBits = 8},
317 {.type = android::gralloc4::PlaneLayoutComponentType_CB,
318 .offsetInBits = 8,
319 .sizeInBits = 8}},
320 .sampleIncrementInBits = 16,
321 .horizontalSubsampling = 2,
322 .verticalSubsampling = 2,
323 }}},
324
325 {DRM_FORMAT_P010,
326 {{
327 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_Y,
328 .offsetInBits = 6,
329 .sizeInBits = 10}},
330 .sampleIncrementInBits = 16,
331 .horizontalSubsampling = 1,
332 .verticalSubsampling = 1,
333 },
334 {
335 .components =
336 {{.type = android::gralloc4::PlaneLayoutComponentType_CB,
337 .offsetInBits = 6,
338 .sizeInBits = 10},
339 {.type = android::gralloc4::PlaneLayoutComponentType_CR,
340 .offsetInBits = 22,
341 .sizeInBits = 10}},
342 .sampleIncrementInBits = 32,
343 .horizontalSubsampling = 2,
344 .verticalSubsampling = 2,
345 }}},
346
347 {DRM_FORMAT_R8,
348 {{
349 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
350 .offsetInBits = 0,
351 .sizeInBits = 8}},
352 .sampleIncrementInBits = 8,
353 .horizontalSubsampling = 1,
354 .verticalSubsampling = 1,
355 }}},
356
357 {DRM_FORMAT_R16,
358 {{
359 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
360 .offsetInBits = 0,
361 .sizeInBits = 16}},
362 .sampleIncrementInBits = 16,
363 .horizontalSubsampling = 1,
364 .verticalSubsampling = 1,
365 }}},
366
367 {DRM_FORMAT_RGB565,
368 {{
369 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
370 .offsetInBits = 0,
371 .sizeInBits = 5},
372 {.type = android::gralloc4::PlaneLayoutComponentType_G,
373 .offsetInBits = 5,
374 .sizeInBits = 6},
375 {.type = android::gralloc4::PlaneLayoutComponentType_B,
376 .offsetInBits = 11,
377 .sizeInBits = 5}},
378 .sampleIncrementInBits = 16,
379 .horizontalSubsampling = 1,
380 .verticalSubsampling = 1,
381 }}},
382
383 {DRM_FORMAT_RGB888,
384 {{
385 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_R,
386 .offsetInBits = 0,
387 .sizeInBits = 8},
388 {.type = android::gralloc4::PlaneLayoutComponentType_G,
389 .offsetInBits = 8,
390 .sizeInBits = 8},
391 {.type = android::gralloc4::PlaneLayoutComponentType_B,
392 .offsetInBits = 16,
393 .sizeInBits = 8}},
394 .sampleIncrementInBits = 24,
395 .horizontalSubsampling = 1,
396 .verticalSubsampling = 1,
397 }}},
398
399 {DRM_FORMAT_XBGR8888,
400 {{
401 .components = {{.type = android::gralloc4::PlaneLayoutComponentType_B,
402 .offsetInBits = 0,
403 .sizeInBits = 8},
404 {.type = android::gralloc4::PlaneLayoutComponentType_G,
405 .offsetInBits = 8,
406 .sizeInBits = 8},
407 {.type = android::gralloc4::PlaneLayoutComponentType_R,
408 .offsetInBits = 16,
409 .sizeInBits = 8}},
410 .sampleIncrementInBits = 32,
411 .horizontalSubsampling = 1,
412 .verticalSubsampling = 1,
413 }}},
414
415 {DRM_FORMAT_YVU420,
416 {
417 {
418 .components = {{.type = android::gralloc4::
419 PlaneLayoutComponentType_Y,
420 .offsetInBits = 0,
421 .sizeInBits = 8}},
422 .sampleIncrementInBits = 8,
423 .horizontalSubsampling = 1,
424 .verticalSubsampling = 1,
425 },
426 {
427 .components = {{.type = android::gralloc4::
428 PlaneLayoutComponentType_CB,
429 .offsetInBits = 0,
430 .sizeInBits = 8}},
431 .sampleIncrementInBits = 8,
432 .horizontalSubsampling = 2,
433 .verticalSubsampling = 2,
434 },
435 {
436 .components = {{.type = android::gralloc4::
437 PlaneLayoutComponentType_CR,
438 .offsetInBits = 0,
439 .sizeInBits = 8}},
440 .sampleIncrementInBits = 8,
441 .horizontalSubsampling = 2,
442 .verticalSubsampling = 2,
443 },
444 }},
445
446 {DRM_FORMAT_YVU420_ANDROID,
447 {
448 {
449 .components = {{.type = android::gralloc4::
450 PlaneLayoutComponentType_Y,
451 .offsetInBits = 0,
452 .sizeInBits = 8}},
453 .sampleIncrementInBits = 8,
454 .horizontalSubsampling = 1,
455 .verticalSubsampling = 1,
456 },
457 {
458 .components = {{.type = android::gralloc4::
459 PlaneLayoutComponentType_CR,
460 .offsetInBits = 0,
461 .sizeInBits = 8}},
462 .sampleIncrementInBits = 8,
463 .horizontalSubsampling = 2,
464 .verticalSubsampling = 2,
465 },
466 {
467 .components = {{.type = android::gralloc4::
468 PlaneLayoutComponentType_CB,
469 .offsetInBits = 0,
470 .sizeInBits = 8}},
471 .sampleIncrementInBits = 8,
472 .horizontalSubsampling = 2,
473 .verticalSubsampling = 2,
474 },
475 }},
476 });
477 return *kPlaneLayoutsMap;
478}
479
480int getPlaneLayouts(uint32_t drmFormat, std::vector<PlaneLayout>* outPlaneLayouts) {
481 const auto& planeLayoutsMap = GetPlaneLayoutsMap();
482 const auto it = planeLayoutsMap.find(drmFormat);
483 if (it == planeLayoutsMap.end()) {
484 drv_log("Unknown plane layout for format %d\n", drmFormat);
Gurchetan Singhcadc54f2021-02-01 12:03:11 -0800485 return -EINVAL;
Jason Macnak2a77d942020-09-10 10:57:46 -0700486 }
487
488 *outPlaneLayouts = it->second;
489 return 0;
Gurchetan Singh2d482e02020-10-05 17:17:13 -0700490}