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