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