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