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