1 /*
2 * Copyright (C) 2020 Arm Limited.
3 *
4 * Copyright 2016 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "MapperMetadata.h"
20 #include "SharedMetadata.h"
21 #include "core/format_info.h"
22 #include "core/mali_gralloc_bufferallocation.h"
23 #include "mali_gralloc_buffer.h"
24 #include "mali_gralloc_log.h"
25 #include "drmutils.h"
26 #include "gralloctypes/Gralloc4.h"
27
28 #include "exynos_format.h"
29 #include "mali_gralloc_formats.h"
30
31 #include <pixel-gralloc/metadata.h>
32
33 #include <vector>
34
35 namespace arm
36 {
37 namespace mapper
38 {
39 namespace common
40 {
41
42 using aidl::android::hardware::graphics::common::PlaneLayout;
43 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
44 using aidl::android::hardware::graphics::common::Rect;
45 using aidl::android::hardware::graphics::common::Dataspace;
46 using aidl::android::hardware::graphics::common::BlendMode;
47 using aidl::android::hardware::graphics::common::StandardMetadataType;
48 using aidl::android::hardware::graphics::common::XyColor;
49 using aidl::android::hardware::graphics::common::Smpte2086;
50 using aidl::android::hardware::graphics::common::Cta861_3;
51 #if 0
52 using aidl::arm::graphics::ArmMetadataType;
53 #endif
54
55 using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
56
get_num_planes(const private_handle_t * hnd)57 static int get_num_planes(const private_handle_t *hnd)
58 {
59 if (is_exynos_format(hnd->get_alloc_format()))
60 {
61 switch (hnd->get_alloc_format())
62 {
63 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
64 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
65 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
66 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
67 return 3;
68
69 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
70 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
71 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
72 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
73 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
74 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
75 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
76 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
77 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
78 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
79 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
80 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
81 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
82 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
83 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
84 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
85 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
86 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
87 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
88 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
89 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
90 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
91 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
92 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
93 return 2;
94 }
95 }
96
97 return hnd->is_multi_plane() ? (hnd->plane_info[2].offset == 0 ? 2 : 3) : 1;
98 }
99
plane_layout_components_from_handle(const private_handle_t * hnd)100 static std::vector<std::vector<PlaneLayoutComponent>> plane_layout_components_from_handle(const private_handle_t *hnd)
101 {
102 /* Re-define the component constants to make the table easier to read. */
103 const ExtendableType R = android::gralloc4::PlaneLayoutComponentType_R;
104 const ExtendableType G = android::gralloc4::PlaneLayoutComponentType_G;
105 const ExtendableType B = android::gralloc4::PlaneLayoutComponentType_B;
106 const ExtendableType A = android::gralloc4::PlaneLayoutComponentType_A;
107 const ExtendableType CB = android::gralloc4::PlaneLayoutComponentType_CB;
108 const ExtendableType CR = android::gralloc4::PlaneLayoutComponentType_CR;
109 const ExtendableType Y = android::gralloc4::PlaneLayoutComponentType_Y;
110 const ExtendableType RAW = android::gralloc4::PlaneLayoutComponentType_RAW;
111
112 struct table_entry
113 {
114 uint32_t drm_fourcc;
115 std::vector<std::vector<PlaneLayoutComponent>> components;
116 };
117
118 /* clang-format off */
119 static table_entry table[] = {
120 /* 16 bit RGB(A) */
121 {
122 .drm_fourcc = DRM_FORMAT_RGB565,
123 .components = { { { B, 0, 5 }, { G, 5, 6 }, { R, 11, 5 } } }
124 },
125 {
126 .drm_fourcc = DRM_FORMAT_BGR565,
127 .components = { { { R, 0, 5 }, { G, 5, 6 }, { B, 11, 5 } } }
128 },
129 /* 24 bit RGB(A) */
130 {
131 .drm_fourcc = DRM_FORMAT_BGR888,
132 .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } }
133 },
134 /* 32 bit RGB(A) */
135 {
136 .drm_fourcc = DRM_FORMAT_ARGB8888,
137 .components = { { { B, 0, 8 }, { G, 8, 8 }, { R, 16, 8 }, { A, 24, 8 } } }
138 },
139 {
140 .drm_fourcc = DRM_FORMAT_ABGR8888,
141 .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 }, { A, 24, 8 } } }
142 },
143 {
144 .drm_fourcc = DRM_FORMAT_XBGR8888,
145 .components = { { { R, 0, 8 }, { G, 8, 8 }, { B, 16, 8 } } }
146 },
147 {
148 .drm_fourcc = DRM_FORMAT_ABGR2101010,
149 .components = { { { R, 0, 10 }, { G, 10, 10 }, { B, 20, 10 }, { A, 30, 2 } } }
150 },
151 /* 64 bit RGB(A) */
152 {
153 .drm_fourcc = DRM_FORMAT_ABGR16161616F,
154 .components = { { { R, 0, 16 }, { G, 16, 16 }, { B, 32, 16 }, { A, 48, 16 } } }
155 },
156 /* Single plane 8 bit YUV 4:2:2 */
157 {
158 .drm_fourcc = DRM_FORMAT_YUYV,
159 .components = { { { Y, 0, 8 }, { CB, 8, 8 }, { Y, 16, 8 }, { CR, 24, 8 } } }
160 },
161 /* Single plane 10 bit YUV 4:4:4 */
162 {
163 .drm_fourcc = DRM_FORMAT_Y410,
164 .components = { { { CB, 0, 10 }, { Y, 10, 10 }, { CR, 20, 10 }, { A, 30, 2 } } }
165 },
166 /* Single plane 10 bit YUV 4:2:2 */
167 {
168 .drm_fourcc = DRM_FORMAT_Y210,
169 .components = { { { Y, 6, 10 }, { CB, 22, 10 }, { Y, 38, 10 }, { CR, 54, 10 } } }
170 },
171 /* Single plane 10 bit YUV 4:2:0 */
172 {
173 .drm_fourcc = DRM_FORMAT_Y0L2,
174 .components = { {
175 { Y, 0, 10 }, { CB, 10, 10 }, { Y, 20, 10 }, { A, 30, 1 }, { A, 31, 1 },
176 { Y, 32, 10 }, { CR, 42, 10 }, { Y, 52, 10 }, { A, 62, 1 }, { A, 63, 1 }
177 } }
178 },
179 /* Semi-planar 8 bit YUV 4:2:2 */
180 {
181 .drm_fourcc = DRM_FORMAT_NV16,
182 .components = {
183 { { Y, 0, 8 } },
184 { { CB, 0, 8 }, { CR, 8, 8 } }
185 }
186 },
187 /* Semi-planar 8 bit YUV 4:2:0 */
188 {
189 .drm_fourcc = DRM_FORMAT_NV12,
190 .components = {
191 { { Y, 0, 8 } },
192 { { CB, 0, 8 }, { CR, 8, 8 } }
193 }
194 },
195 {
196 .drm_fourcc = DRM_FORMAT_NV21,
197 .components = {
198 { { Y, 0, 8 } },
199 { { CR, 0, 8 }, { CB, 8, 8 } }
200 }
201 },
202 /* Semi-planar 10 bit YUV 4:2:2 */
203 {
204 .drm_fourcc = DRM_FORMAT_P210,
205 .components = {
206 { { Y, 6, 10 } },
207 { { CB, 6, 10 }, { CB, 22, 10 } }
208 }
209 },
210 /* Semi-planar 10 bit YUV 4:2:0 */
211 {
212 .drm_fourcc = DRM_FORMAT_P010,
213 .components = {
214 { { Y, 6, 10 } },
215 { { CB, 6, 10 }, { CR, 22, 10 } }
216 }
217 },
218 /* Planar 8 bit YUV 4:2:0 */
219 {
220 .drm_fourcc = DRM_FORMAT_YVU420,
221 .components = {
222 { { Y, 0, 8 } },
223 { { CR, 0, 8 } },
224 { { CB, 0, 8 } }
225 }
226 },
227 /* Planar 8 bit YUV 4:4:4 */
228 {
229 .drm_fourcc = DRM_FORMAT_YUV444,
230 .components = {
231 { { Y, 0, 8 } },
232 { { CB, 0, 8 } },
233 { { CR, 0, 8 } }
234 }
235 },
236
237 /* AFBC Only FourCC */
238 {.drm_fourcc = DRM_FORMAT_YUV420_8BIT, .components = { {} } },
239 {.drm_fourcc = DRM_FORMAT_YUV420_10BIT, .components = { {} } },
240
241 /* Google specific formats */
242 {
243 .drm_fourcc = DRM_FORMAT_R8,
244 .components = {
245 { { R, 0, 8 } }
246 }
247 },
248 {
249 .drm_fourcc = DRM_FORMAT_RG88,
250 .components = {
251 { { R, 0, 8 }, { G, 8, 8 } }
252 }
253 },
254 };
255 /* clang-format on */
256
257 const uint32_t drm_fourcc = drm_fourcc_from_handle(hnd);
258 if (drm_fourcc != DRM_FORMAT_INVALID)
259 {
260 for (const auto& entry : table)
261 {
262 if (entry.drm_fourcc == drm_fourcc)
263 {
264 return entry.components;
265 }
266 }
267 }
268
269 switch (hnd->get_alloc_format())
270 {
271 case HAL_PIXEL_FORMAT_RAW10:
272 return {{{RAW, 0, -1}}};
273 case HAL_PIXEL_FORMAT_RAW12:
274 return {{{RAW, 0, -1}}};
275 case HAL_PIXEL_FORMAT_BLOB:
276 break;
277 default:
278 MALI_GRALLOC_LOGW("Could not find component description for Format(%#x) FourCC value(%#x)",
279 hnd->get_alloc_format(), drm_fourcc);
280 }
281
282 return std::vector<std::vector<PlaneLayoutComponent>>(0);
283 }
284
get_plane_layouts(const private_handle_t * handle,std::vector<PlaneLayout> * layouts)285 static android::status_t get_plane_layouts(const private_handle_t *handle, std::vector<PlaneLayout> *layouts)
286 {
287 const int num_planes = get_num_planes(handle);
288 uint32_t base_format = handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
289 int32_t format_index = get_format_index(base_format);
290 if (format_index < 0)
291 {
292 MALI_GRALLOC_LOGE("Negative format index in get_plane_layouts");
293 return android::BAD_VALUE;
294 }
295 const format_info_t format_info = formats[format_index];
296 layouts->reserve(num_planes);
297
298 if (is_exynos_format(handle->get_alloc_format()))
299 {
300 std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle);
301 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
302 {
303 int64_t plane_size = handle->plane_info[plane_index].size;
304 int64_t sample_increment_in_bits = format_info.bpp[plane_index];
305 int64_t offset = handle->plane_info[plane_index].offset;
306
307 static bool warn_multifd = true;
308 if (warn_multifd) {
309 uint8_t fd_count = get_exynos_fd_count(base_format);
310 if (fd_count != 1) {
311 warn_multifd = false;
312 MALI_GRALLOC_LOGW("Offsets in plane layouts of multi-fd format (%s %" PRIu64
313 ") are not reliable. This can lead to image corruption.",
314 format_name(base_format), handle->alloc_format);
315 }
316 }
317
318 PlaneLayout layout = {.offsetInBytes = offset,
319 .sampleIncrementInBits = sample_increment_in_bits,
320 .strideInBytes = handle->plane_info[plane_index].byte_stride,
321 .widthInSamples = handle->plane_info[plane_index].alloc_width,
322 .heightInSamples = handle->plane_info[plane_index].alloc_height,
323 .totalSizeInBytes = plane_size,
324 .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub),
325 .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub),
326 .components = components.size() > plane_index ? components[plane_index] :
327 std::vector<PlaneLayoutComponent>(0) };
328 layouts->push_back(layout);
329 }
330 }
331 else
332 {
333 std::vector<std::vector<PlaneLayoutComponent>> components = plane_layout_components_from_handle(handle);
334 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
335 {
336 int64_t plane_size;
337 if (plane_index < num_planes - 1)
338 {
339 plane_size = handle->plane_info[plane_index + 1].offset;
340 }
341 else
342 {
343 int64_t layer_size = handle->alloc_sizes[0] / handle->layer_count;
344 plane_size = layer_size - handle->plane_info[plane_index].offset;
345 }
346
347 if (handle->fd_count > 1 && handle->plane_info[plane_index].fd_idx == plane_index)
348 {
349 plane_size = handle->plane_info[plane_index].size;
350 }
351
352 int64_t sample_increment_in_bits = 0;
353 if (handle->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
354 {
355 sample_increment_in_bits = format_info.bpp_afbc[plane_index];
356 }
357 else
358 {
359 sample_increment_in_bits = format_info.bpp[plane_index];
360 }
361
362 switch (handle->get_alloc_format())
363 {
364 case HAL_PIXEL_FORMAT_RAW10:
365 case HAL_PIXEL_FORMAT_RAW12:
366 sample_increment_in_bits = 0;
367 break;
368 default:
369 break;
370 }
371
372 PlaneLayout layout = {.offsetInBytes = handle->plane_info[plane_index].offset,
373 .sampleIncrementInBits = sample_increment_in_bits,
374 .strideInBytes = handle->plane_info[plane_index].byte_stride,
375 .widthInSamples = handle->plane_info[plane_index].alloc_width,
376 .heightInSamples = handle->plane_info[plane_index].alloc_height,
377 .totalSizeInBytes = plane_size,
378 .horizontalSubsampling = (plane_index == 0 ? 1 : format_info.hsub),
379 .verticalSubsampling = (plane_index == 0 ? 1 : format_info.vsub),
380 .components = components.size() > plane_index ? components[plane_index] :
381 std::vector<PlaneLayoutComponent>(0) };
382 layouts->push_back(layout);
383 }
384 }
385
386 return android::OK;
387 }
388
encodePointer(void * ptr)389 static hidl_vec<uint8_t> encodePointer(void* ptr) {
390 constexpr uint8_t kPtrSize = sizeof(void*);
391
392 hidl_vec<uint8_t> output(kPtrSize);
393 std::memcpy(output.data(), &ptr, kPtrSize);
394
395 return output;
396 }
397
get_metadata(const private_handle_t * handle,const IMapper::MetadataType & metadataType,IMapper::get_cb hidl_cb)398 void get_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb)
399 {
400 android::status_t err = android::OK;
401 hidl_vec<uint8_t> vec;
402
403 if (android::gralloc4::isStandardMetadataType(metadataType))
404 {
405 switch (android::gralloc4::getStandardMetadataTypeValue(metadataType))
406 {
407 case StandardMetadataType::BUFFER_ID:
408 err = android::gralloc4::encodeBufferId(handle->backing_store_id, &vec);
409 break;
410 case StandardMetadataType::NAME:
411 {
412 std::string name;
413 get_name(handle, &name);
414 err = android::gralloc4::encodeName(name, &vec);
415 break;
416 }
417 case StandardMetadataType::WIDTH:
418 err = android::gralloc4::encodeWidth(handle->width, &vec);
419 break;
420 case StandardMetadataType::HEIGHT:
421 err = android::gralloc4::encodeHeight(handle->height, &vec);
422 break;
423 case StandardMetadataType::LAYER_COUNT:
424 err = android::gralloc4::encodeLayerCount(handle->layer_count, &vec);
425 break;
426 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
427 err = android::gralloc4::encodePixelFormatRequested(static_cast<PixelFormat>(handle->req_format), &vec);
428 break;
429 case StandardMetadataType::PIXEL_FORMAT_FOURCC:
430 err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(handle), &vec);
431 break;
432 case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
433 err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(handle), &vec);
434 break;
435 case StandardMetadataType::USAGE:
436 err = android::gralloc4::encodeUsage(handle->consumer_usage | handle->producer_usage, &vec);
437 break;
438 case StandardMetadataType::ALLOCATION_SIZE:
439 {
440 uint64_t total_size = 0;
441 for (int fidx = 0; fidx < handle->fd_count; fidx++)
442 {
443 total_size += handle->alloc_sizes[fidx];
444 }
445 err = android::gralloc4::encodeAllocationSize(total_size, &vec);
446 break;
447 }
448 case StandardMetadataType::PROTECTED_CONTENT:
449 {
450 /* This is set to 1 if the buffer has protected content. */
451 const int is_protected =
452 (((handle->consumer_usage | handle->producer_usage) & BufferUsage::PROTECTED) == 0) ? 0 : 1;
453 err = android::gralloc4::encodeProtectedContent(is_protected, &vec);
454 break;
455 }
456 case StandardMetadataType::COMPRESSION:
457 {
458 ExtendableType compression;
459 if (handle->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
460 {
461 compression = Compression_AFBC;
462 }
463 else
464 {
465 compression = android::gralloc4::Compression_None;
466 }
467 err = android::gralloc4::encodeCompression(compression, &vec);
468 break;
469 }
470 case StandardMetadataType::INTERLACED:
471 err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec);
472 break;
473 case StandardMetadataType::CHROMA_SITING:
474 {
475 int format_index = get_format_index(handle->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
476 if (format_index < 0)
477 {
478 err = android::BAD_VALUE;
479 break;
480 }
481 ExtendableType siting = android::gralloc4::ChromaSiting_None;
482 if (formats[format_index].is_yuv)
483 {
484 siting = android::gralloc4::ChromaSiting_Unknown;
485 }
486 err = android::gralloc4::encodeChromaSiting(siting, &vec);
487 break;
488 }
489 case StandardMetadataType::PLANE_LAYOUTS:
490 {
491 std::vector<PlaneLayout> layouts;
492 err = get_plane_layouts(handle, &layouts);
493 if (!err)
494 {
495 err = android::gralloc4::encodePlaneLayouts(layouts, &vec);
496 }
497 break;
498 }
499 case StandardMetadataType::DATASPACE:
500 {
501 std::optional<Dataspace> dataspace;
502 get_dataspace(handle, &dataspace);
503 err = android::gralloc4::encodeDataspace(dataspace.value_or(Dataspace::UNKNOWN), &vec);
504 break;
505 }
506 case StandardMetadataType::BLEND_MODE:
507 {
508 std::optional<BlendMode> blend_mode;
509 get_blend_mode(handle, &blend_mode);
510 err = android::gralloc4::encodeBlendMode(blend_mode.value_or(BlendMode::INVALID), &vec);
511 break;
512 }
513 case StandardMetadataType::CROP:
514 {
515 const int num_planes = get_num_planes(handle);
516 std::vector<Rect> crops(num_planes);
517 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
518 {
519 /* Set the default crop rectangle. Android mandates that it must fit [0, 0, widthInSamples, heightInSamples]
520 * We always require using the requested width and height for the crop rectangle size.
521 * For planes > 0 the size might need to be scaled, but since we only use plane[0] for crop set it to the
522 * Android default of [0, 0, widthInSamples, heightInSamples] for other planes.
523 */
524 Rect rect = {.top = 0,
525 .left = 0,
526 .right = static_cast<int32_t>(handle->plane_info[plane_index].alloc_width),
527 .bottom = static_cast<int32_t>(handle->plane_info[plane_index].alloc_height) };
528 if (plane_index == 0)
529 {
530 std::optional<Rect> crop_rect;
531 get_crop_rect(handle, &crop_rect);
532 if (crop_rect.has_value())
533 {
534 rect = crop_rect.value();
535 }
536 else
537 {
538 rect = {.top = 0, .left = 0, .right = handle->width, .bottom = handle->height };
539 }
540 }
541 crops[plane_index] = rect;
542 }
543 err = android::gralloc4::encodeCrop(crops, &vec);
544 break;
545 }
546 case StandardMetadataType::SMPTE2086:
547 {
548 std::optional<Smpte2086> smpte2086;
549 get_smpte2086(handle, &smpte2086);
550 err = android::gralloc4::encodeSmpte2086(smpte2086, &vec);
551 break;
552 }
553 case StandardMetadataType::CTA861_3:
554 {
555 std::optional<Cta861_3> cta861_3;
556 get_cta861_3(handle, &cta861_3);
557 err = android::gralloc4::encodeCta861_3(cta861_3, &vec);
558 break;
559 }
560 case StandardMetadataType::SMPTE2094_40:
561 {
562 std::optional<std::vector<uint8_t>> smpte2094_40;
563 get_smpte2094_40(handle, &smpte2094_40);
564 err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec);
565 break;
566 }
567 case StandardMetadataType::INVALID:
568 default:
569 err = android::BAD_VALUE;
570 }
571 }
572 else if (metadataType.name == ::pixel::graphics::kPixelMetadataTypeName) {
573 switch (static_cast<::pixel::graphics::MetadataType>(metadataType.value)) {
574 case ::pixel::graphics::MetadataType::VIDEO_HDR:
575 vec = encodePointer(get_video_hdr(handle));
576 break;
577 case ::pixel::graphics::MetadataType::VIDEO_ROI:
578 {
579 auto roi = get_video_roiinfo(handle);
580 if (roi == nullptr) {
581 err = android::BAD_VALUE;
582 } else {
583 vec = encodePointer(roi);
584 }
585 break;
586 }
587 default:
588 err = android::BAD_VALUE;
589 }
590 }
591 else
592 {
593 err = android::BAD_VALUE;
594 }
595
596 hidl_cb((err) ? Error::UNSUPPORTED : Error::NONE, vec);
597 }
598
set_metadata(const private_handle_t * handle,const IMapper::MetadataType & metadataType,const hidl_vec<uint8_t> & metadata)599 Error set_metadata(const private_handle_t *handle, const IMapper::MetadataType &metadataType,
600 const hidl_vec<uint8_t> &metadata)
601 {
602 if (android::gralloc4::isStandardMetadataType(metadataType))
603 {
604 android::status_t err = android::OK;
605 switch (android::gralloc4::getStandardMetadataTypeValue(metadataType))
606 {
607 case StandardMetadataType::DATASPACE:
608 {
609 Dataspace dataspace;
610 err = android::gralloc4::decodeDataspace(metadata, &dataspace);
611 if (!err)
612 {
613 set_dataspace(handle, dataspace);
614 }
615 break;
616 }
617 case StandardMetadataType::BLEND_MODE:
618 {
619 BlendMode blend_mode;
620 err = android::gralloc4::decodeBlendMode(metadata, &blend_mode);
621 if (!err)
622 {
623 set_blend_mode(handle, blend_mode);
624 }
625 break;
626 }
627 case StandardMetadataType::SMPTE2086:
628 {
629 std::optional<Smpte2086> smpte2086;
630 err = android::gralloc4::decodeSmpte2086(metadata, &smpte2086);
631 if (!err)
632 {
633 err = set_smpte2086(handle, smpte2086);
634 }
635 break;
636 }
637 case StandardMetadataType::CTA861_3:
638 {
639 std::optional<Cta861_3> cta861_3;
640 err = android::gralloc4::decodeCta861_3(metadata, &cta861_3);
641 if (!err)
642 {
643 err = set_cta861_3(handle, cta861_3);
644 }
645 break;
646 }
647 case StandardMetadataType::SMPTE2094_40:
648 {
649 std::optional<std::vector<uint8_t>> smpte2094_40;
650 err = android::gralloc4::decodeSmpte2094_40(metadata, &smpte2094_40);
651 if (!err)
652 {
653 err = set_smpte2094_40(handle, smpte2094_40);
654 }
655 break;
656 }
657 case StandardMetadataType::CROP:
658 {
659 std::vector<Rect> crops;
660 err = android::gralloc4::decodeCrop(metadata, &crops);
661 if (!err)
662 {
663 err = set_crop_rect(handle, crops[0]);
664 }
665 break;
666 }
667 /* The following meta data types cannot be changed after allocation. */
668 case StandardMetadataType::BUFFER_ID:
669 case StandardMetadataType::NAME:
670 case StandardMetadataType::WIDTH:
671 case StandardMetadataType::HEIGHT:
672 case StandardMetadataType::LAYER_COUNT:
673 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
674 case StandardMetadataType::USAGE:
675 return Error::BAD_VALUE;
676 /* Changing other metadata types is unsupported. */
677 case StandardMetadataType::PLANE_LAYOUTS:
678 case StandardMetadataType::PIXEL_FORMAT_FOURCC:
679 case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
680 case StandardMetadataType::ALLOCATION_SIZE:
681 case StandardMetadataType::PROTECTED_CONTENT:
682 case StandardMetadataType::COMPRESSION:
683 case StandardMetadataType::INTERLACED:
684 case StandardMetadataType::CHROMA_SITING:
685 case StandardMetadataType::INVALID:
686 default:
687 return Error::UNSUPPORTED;
688 }
689 return ((err) ? Error::UNSUPPORTED : Error::NONE);
690 }
691 else
692 {
693 /* None of the vendor types support set. */
694 return Error::UNSUPPORTED;
695 }
696 }
697
getFromBufferDescriptorInfo(IMapper::BufferDescriptorInfo const & description,IMapper::MetadataType const & metadataType,IMapper::getFromBufferDescriptorInfo_cb hidl_cb)698 void getFromBufferDescriptorInfo(IMapper::BufferDescriptorInfo const &description,
699 IMapper::MetadataType const &metadataType,
700 IMapper::getFromBufferDescriptorInfo_cb hidl_cb)
701 {
702 /* This will hold the metadata that is returned. */
703 hidl_vec<uint8_t> vec;
704
705 buffer_descriptor_t descriptor;
706 descriptor.width = description.width;
707 descriptor.height = description.height;
708 descriptor.layer_count = description.layerCount;
709 descriptor.hal_format = static_cast<uint64_t>(description.format);
710 descriptor.producer_usage = static_cast<uint64_t>(description.usage);
711 descriptor.consumer_usage = descriptor.producer_usage;
712 descriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
713
714 /* Check if it is possible to allocate a buffer for the given description */
715 const int alloc_result = mali_gralloc_derive_format_and_size(&descriptor);
716 if (alloc_result != 0)
717 {
718 MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", alloc_result);
719 hidl_cb(Error::BAD_VALUE, vec);
720 return;
721 }
722 /* Create buffer handle from the initialized descriptor without a backing store or shared metadata region.
723 * Used to share functionality with the normal metadata get function that can only use the allocated buffer handle
724 * and does not have the buffer descriptor available. */
725 private_handle_t partial_handle(0, descriptor.alloc_sizes, descriptor.consumer_usage, descriptor.producer_usage,
726 nullptr, descriptor.fd_count,
727 descriptor.hal_format, descriptor.alloc_format,
728 descriptor.width, descriptor.height, descriptor.pixel_stride,
729 descriptor.layer_count, descriptor.plane_info);
730 if (android::gralloc4::isStandardMetadataType(metadataType))
731 {
732 android::status_t err = android::OK;
733
734 switch (android::gralloc4::getStandardMetadataTypeValue(metadataType))
735 {
736 case StandardMetadataType::NAME:
737 err = android::gralloc4::encodeName(description.name, &vec);
738 break;
739 case StandardMetadataType::WIDTH:
740 err = android::gralloc4::encodeWidth(description.width, &vec);
741 break;
742 case StandardMetadataType::HEIGHT:
743 err = android::gralloc4::encodeHeight(description.height, &vec);
744 break;
745 case StandardMetadataType::LAYER_COUNT:
746 err = android::gralloc4::encodeLayerCount(description.layerCount, &vec);
747 break;
748 case StandardMetadataType::PIXEL_FORMAT_REQUESTED:
749 err = android::gralloc4::encodePixelFormatRequested(static_cast<PixelFormat>(description.format), &vec);
750 break;
751 case StandardMetadataType::USAGE:
752 err = android::gralloc4::encodeUsage(description.usage, &vec);
753 break;
754 case StandardMetadataType::PIXEL_FORMAT_FOURCC:
755 err = android::gralloc4::encodePixelFormatFourCC(drm_fourcc_from_handle(&partial_handle), &vec);
756 break;
757 case StandardMetadataType::PIXEL_FORMAT_MODIFIER:
758 err = android::gralloc4::encodePixelFormatModifier(drm_modifier_from_handle(&partial_handle), &vec);
759 break;
760 case StandardMetadataType::ALLOCATION_SIZE:
761 {
762 /* TODO: Returns expetected size if the buffer was actually allocated.
763 * Is this the right behavior?
764 */
765 uint64_t total_size = 0;
766 for (int fidx = 0; fidx < descriptor.fd_count; fidx++)
767 {
768 total_size += descriptor.alloc_sizes[fidx];
769 }
770 err = android::gralloc4::encodeAllocationSize(total_size, &vec);
771 break;
772 }
773 case StandardMetadataType::PROTECTED_CONTENT:
774 {
775 /* This is set to 1 if the buffer has protected content. */
776 const int is_protected =
777 (((partial_handle.consumer_usage | partial_handle.producer_usage) & BufferUsage::PROTECTED)) ? 1 : 0;
778 err = android::gralloc4::encodeProtectedContent(is_protected, &vec);
779 break;
780 }
781 case StandardMetadataType::COMPRESSION:
782 {
783 ExtendableType compression;
784 if (partial_handle.alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
785 {
786 compression = Compression_AFBC;
787 }
788 else
789 {
790 compression = android::gralloc4::Compression_None;
791 }
792 err = android::gralloc4::encodeCompression(compression, &vec);
793 break;
794 }
795 case StandardMetadataType::INTERLACED:
796 err = android::gralloc4::encodeInterlaced(android::gralloc4::Interlaced_None, &vec);
797 break;
798 case StandardMetadataType::CHROMA_SITING:
799 {
800 int format_index = get_format_index(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
801 if (format_index < 0)
802 {
803 err = android::BAD_VALUE;
804 break;
805 }
806 ExtendableType siting = android::gralloc4::ChromaSiting_None;
807 if (formats[format_index].is_yuv)
808 {
809 siting = android::gralloc4::ChromaSiting_Unknown;
810 }
811 err = android::gralloc4::encodeChromaSiting(siting, &vec);
812 break;
813 }
814 case StandardMetadataType::PLANE_LAYOUTS:
815 {
816 std::vector<PlaneLayout> layouts;
817 err = get_plane_layouts(&partial_handle, &layouts);
818 if (!err)
819 {
820 err = android::gralloc4::encodePlaneLayouts(layouts, &vec);
821 }
822 break;
823 }
824 case StandardMetadataType::DATASPACE:
825 {
826 android_dataspace_t dataspace;
827 get_format_dataspace(partial_handle.alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK,
828 partial_handle.consumer_usage | partial_handle.producer_usage, partial_handle.width,
829 partial_handle.height, &dataspace);
830 err = android::gralloc4::encodeDataspace(static_cast<Dataspace>(dataspace), &vec);
831 break;
832 }
833 case StandardMetadataType::BLEND_MODE:
834 err = android::gralloc4::encodeBlendMode(BlendMode::INVALID, &vec);
835 break;
836 case StandardMetadataType::CROP:
837 {
838 const int num_planes = get_num_planes(&partial_handle);
839 std::vector<Rect> crops(num_planes);
840 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index)
841 {
842 Rect rect = {.top = 0,
843 .left = 0,
844 .right = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_width),
845 .bottom = static_cast<int32_t>(partial_handle.plane_info[plane_index].alloc_height) };
846 if (plane_index == 0)
847 {
848 rect = {.top = 0, .left = 0, .right = partial_handle.width, .bottom = partial_handle.height };
849 }
850 crops[plane_index] = rect;
851 }
852 err = android::gralloc4::encodeCrop(crops, &vec);
853 break;
854 }
855 case StandardMetadataType::SMPTE2086:
856 {
857 std::optional<Smpte2086> smpte2086{};
858 err = android::gralloc4::encodeSmpte2086(smpte2086, &vec);
859 break;
860 }
861 case StandardMetadataType::CTA861_3:
862 {
863 std::optional<Cta861_3> cta861_3{};
864 err = android::gralloc4::encodeCta861_3(cta861_3, &vec);
865 break;
866 }
867 case StandardMetadataType::SMPTE2094_40:
868 {
869 std::optional<std::vector<uint8_t>> smpte2094_40{};
870 err = android::gralloc4::encodeSmpte2094_40(smpte2094_40, &vec);
871 break;
872 }
873
874 case StandardMetadataType::BUFFER_ID:
875 case StandardMetadataType::INVALID:
876 default:
877 err = android::BAD_VALUE;
878 }
879 hidl_cb((err) ? Error::UNSUPPORTED : Error::NONE, vec);
880 }
881 else
882 {
883 hidl_cb(Error::UNSUPPORTED, vec);
884 }
885 }
886
887 } // namespace common
888 } // namespace mapper
889 } // namespace arm
890