• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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