1 /*
2  * Copyright (C) 2020 ARM Limited. All rights reserved.
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 <inttypes.h>
20 #include <sync/sync.h>
21 #include <hardware/gralloc1.h>
22 #include "RegisteredHandlePool.h"
23 #include "Mapper.h"
24 #include "BufferDescriptor.h"
25 #include "mali_gralloc_log.h"
26 #include "core/mali_gralloc_bufferallocation.h"
27 #include "core/mali_gralloc_bufferdescriptor.h"
28 #include "core/mali_gralloc_bufferaccess.h"
29 #include "core/mali_gralloc_reference.h"
30 #include "core/format_info.h"
31 #include "allocator/mali_gralloc_ion.h"
32 #include "mali_gralloc_buffer.h"
33 #include "mali_gralloc_log.h"
34 
35 #include "MapperMetadata.h"
36 #include "SharedMetadata.h"
37 
38 #include <cstdio>
39 
40 /* GraphicBufferMapper is expected to be valid (and leaked) during process
41  * termination. IMapper, and in turn, gRegisteredHandles must be valid as
42  * well. Create the registered handle pool on the heap, and let
43  * it leak for simplicity.
44  *
45  * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
46  * of static/global object in gralloc0/gralloc1 that may have been destructed
47  * is potentially broken.
48  */
49 RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;
50 
51 namespace arm {
52 namespace mapper {
53 namespace common {
54 
getBuffer(void * buffer)55 buffer_handle_t getBuffer(void *buffer) {
56 	return gRegisteredHandles->get(buffer);
57 }
58 
59 /*
60  * Translates the register buffer API into existing gralloc implementation
61  *
62  * @param bufferHandle [in] Private handle for the buffer to be imported
63  *
64  * @return Error::BAD_BUFFER for an invalid buffer
65  *         Error::NO_RESOURCES when unable to import the given buffer
66  *         Error::NONE on successful import
67  */
registerBuffer(buffer_handle_t bufferHandle)68 static Error registerBuffer(buffer_handle_t bufferHandle)
69 {
70 	if (private_handle_t::validate(bufferHandle) < 0)
71 	{
72 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
73 		return Error::BAD_BUFFER;
74 	}
75 
76 	if (mali_gralloc_reference_retain(bufferHandle) < 0)
77 	{
78 		return Error::NO_RESOURCES;
79 	}
80 
81 	return Error::NONE;
82 }
83 
84 /*
85  * Translates the unregister buffer API into existing gralloc implementation
86  *
87  * @param bufferHandle [in] Private handle for the buffer to be released
88  *
89  * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released
90  *         Error::NONE on successful release of the buffer
91  */
unregisterBuffer(buffer_handle_t bufferHandle)92 static Error unregisterBuffer(buffer_handle_t bufferHandle)
93 {
94 	if (private_handle_t::validate(bufferHandle) < 0)
95 	{
96 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
97 		return Error::BAD_BUFFER;
98 	}
99 
100 	const int status = mali_gralloc_reference_release(bufferHandle);
101 	if (status != 0)
102 	{
103 		MALI_GRALLOC_LOGE("Unable to release buffer:%p", bufferHandle);
104 		return Error::BAD_BUFFER;
105 	}
106 
107 	return Error::NONE;
108 }
109 
110 /*
111  * Converts a gralloc error code to a mapper error code
112  *
113  * @param grallocError  [in] Gralloc error as integer.
114  *
115  * @return Corresponding Mapper error code
116  *
117  * @note There is no full 1:1 correspondence, several gralloc errors may map to Error::UNSUPPORTED.
118  * @note -EINVAL is mapped to Error::BAD_VALUE.
119  */
grallocErrorToMapperError(int grallocError)120 static Error grallocErrorToMapperError(int grallocError)
121 {
122 	switch(grallocError)
123 	{
124 		case GRALLOC1_ERROR_NONE:
125 			return Error::NONE;
126 		case GRALLOC1_ERROR_BAD_DESCRIPTOR:
127 			return Error::BAD_DESCRIPTOR;
128 		case GRALLOC1_ERROR_BAD_HANDLE:
129 			return Error::BAD_BUFFER;
130 		case GRALLOC1_ERROR_BAD_VALUE:
131 		case -EINVAL:
132 			return Error::BAD_VALUE;
133 		case GRALLOC1_ERROR_NO_RESOURCES:
134 			return Error::NO_RESOURCES;
135 		default:
136 			/* Covers NOT_SHARED, UNDEFINED, UNSUPPORTED */
137 			return Error::UNSUPPORTED;
138 	}
139 }
140 
141 /*
142  * Locks the given buffer for the specified CPU usage.
143  *
144  * @param bufferHandle [in]  Buffer to lock.
145  * @param cpuUsage     [in]  Specifies one or more CPU usage flags to request
146  * @param accessRegion [in]  Portion of the buffer that the client intends to
147  * access.
148  * @param fenceFd      [in]  Fence file descriptor
149  * @param outData      [out] CPU accessible buffer address
150  *
151  * @return Error::BAD_BUFFER for an invalid buffer
152  *         Error::NO_RESOURCES when unable to duplicate fence
153  *         Error::BAD_VALUE when locking fails
154  *         Error::UNSUPPORTED when locking fails on unsupported image formats
155  *         Error::NONE on successful buffer lock
156  */
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const GrallocRect & accessRegion,int fenceFd,void ** outData)157 static Error lockBuffer(buffer_handle_t bufferHandle,
158                         uint64_t cpuUsage,
159                         const GrallocRect& accessRegion, int fenceFd,
160                         void** outData)
161 {
162 	/* dup fenceFd as it is going to be owned by gralloc. Note that it is
163 	 * gralloc's responsibility to close it, even on locking errors.
164 	 */
165 	if (fenceFd >= 0)
166 	{
167 		fenceFd = dup(fenceFd);
168 		if (fenceFd < 0)
169 		{
170 			MALI_GRALLOC_LOGE("Error encountered while duplicating fence file descriptor");
171 			return Error::NO_RESOURCES;
172 		}
173 	}
174 
175 	if (private_handle_t::validate(bufferHandle) < 0)
176 	{
177 		if (fenceFd >= 0)
178 		{
179 			close(fenceFd);
180 		}
181 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
182 		return Error::BAD_BUFFER;
183 	}
184 
185 	if (mali_gralloc_reference_validate(bufferHandle) < 0)
186 	{
187 		if (fenceFd >= 0)
188 		{
189 			close(fenceFd);
190 		}
191 		MALI_GRALLOC_LOGE("Buffer: %p is not imported", bufferHandle);
192 		return Error::BAD_VALUE;
193 	}
194 
195 	auto private_handle = private_handle_t::dynamicCast(bufferHandle);
196 	if (private_handle->cpu_write != 0 && (cpuUsage & static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK)))
197 	{
198 		if (fenceFd >= 0)
199 		{
200 			close(fenceFd);
201 		}
202 #if 0
203 		MALI_GRALLOC_LOGW("Attempt to call lock*() for writing on an already locked buffer (%p)", bufferHandle);
204 #endif
205 
206 		/* TODO: handle simulatneous locks differently. May be keep a global lock count per buffer? */
207 	}
208 	else if (fenceFd >= 0)
209 	{
210 		sync_wait(fenceFd, -1);
211 		close(fenceFd);
212 	}
213 
214 	void* data = nullptr;
215 	const int gralloc_err =
216 		mali_gralloc_lock(bufferHandle, cpuUsage, accessRegion.left, accessRegion.top,
217 				  accessRegion.right - accessRegion.left,
218 				  accessRegion.bottom - accessRegion.top, &data);
219 	const Error lock_err = grallocErrorToMapperError(gralloc_err);
220 
221 	if(Error::NONE == lock_err)
222 	{
223 		*outData = data;
224 	}
225 	else
226 	{
227 		MALI_GRALLOC_LOGE("Locking failed with error: %d", gralloc_err);
228 	}
229 
230 	return lock_err;
231 }
232 
233 /*
234  * Unlocks a buffer to indicate all CPU accesses to the buffer have completed
235  *
236  * @param bufferHandle [in]  Buffer to lock.
237  * @param outFenceFd   [out] Fence file descriptor
238  *
239  * @return Error::BAD_BUFFER for an invalid buffer
240  *         Error::BAD_VALUE when unlocking failed
241  *         Error::NONE on successful buffer unlock
242  */
unlockBuffer(buffer_handle_t bufferHandle,int * outFenceFd)243 static Error unlockBuffer(buffer_handle_t bufferHandle,
244                                   int* outFenceFd)
245 {
246 	if (private_handle_t::validate(bufferHandle) < 0)
247 	{
248 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
249 		return Error::BAD_BUFFER;
250 	}
251 
252 	const int gralloc_err = mali_gralloc_unlock(bufferHandle);
253 	const Error unlock_err = grallocErrorToMapperError(gralloc_err);
254 
255 	if (Error::NONE == unlock_err)
256 	{
257 		*outFenceFd = -1;
258 	}
259 	else
260 	{
261 		MALI_GRALLOC_LOGE("Unlocking failed with error: %d",
262 				  gralloc_err);
263 		return Error::BAD_BUFFER;
264 	}
265 
266 	return unlock_err;
267 }
268 
importBuffer(const native_handle_t * inBuffer,buffer_handle_t * outBuffer)269 Error importBuffer(const native_handle_t *inBuffer, buffer_handle_t *outBuffer)
270 {
271 	*outBuffer = const_cast<buffer_handle_t>(native_handle_clone(inBuffer));
272 	const Error error = registerBuffer(*outBuffer);
273 	if (error != Error::NONE)
274 	{
275 		return error;
276 	}
277 
278 	if (gRegisteredHandles->add(*outBuffer) == false)
279 	{
280 		/* The newly cloned handle is already registered. This can only happen
281 		 * when a handle previously registered was native_handle_delete'd instead
282 		 * of freeBuffer'd.
283 		 */
284 		MALI_GRALLOC_LOGE("Handle %p has already been imported; potential fd leaking",
285 		       outBuffer);
286 		unregisterBuffer(*outBuffer);
287 		return Error::NO_RESOURCES;
288 	}
289 
290 	return Error::NONE;
291 }
292 
freeBuffer(buffer_handle_t bufferHandle)293 Error freeBuffer(buffer_handle_t bufferHandle)
294 {
295 	native_handle_t *handle = gRegisteredHandles->remove(bufferHandle);
296 	if (handle == nullptr)
297 	{
298 		MALI_GRALLOC_LOGE("Invalid buffer handle %p to freeBuffer", bufferHandle);
299 		return Error::BAD_BUFFER;
300 	}
301 
302 	const Error status = unregisterBuffer(handle);
303 	if (status != Error::NONE)
304 	{
305 		return status;
306 	}
307 
308 	native_handle_close(handle);
309 	native_handle_delete(handle);
310 
311 	return Error::NONE;
312 }
313 
lock(buffer_handle_t bufferHandle,uint64_t cpuUsage,const GrallocRect & accessRegion,int acquireFence,void ** outData)314 Error lock(buffer_handle_t bufferHandle, uint64_t cpuUsage, const GrallocRect &accessRegion, int acquireFence, void **outData)
315 {
316 	*outData = nullptr;
317 	if (!bufferHandle || private_handle_t::validate(bufferHandle) < 0)
318 	{
319 		MALI_GRALLOC_LOGE("Buffer to lock: %p is not valid",
320 				  bufferHandle);
321 		return Error::BAD_BUFFER;
322 	}
323 
324 	const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion,
325 				       acquireFence, outData);
326 	return error;
327 }
328 
unlock(buffer_handle_t bufferHandle,int * releaseFence)329 Error unlock(buffer_handle_t bufferHandle, int *releaseFence) {
330 	if(bufferHandle == nullptr) return Error::BAD_BUFFER;
331 	if(!gRegisteredHandles->isRegistered(bufferHandle)) {
332 		MALI_GRALLOC_LOGE("Buffer to unlock: %p has not been registered with Gralloc",
333 		    bufferHandle);
334 		return Error::BAD_BUFFER;
335 	}
336 
337 	const Error error = unlockBuffer(bufferHandle, releaseFence);
338 	return error;
339 }
340 #ifdef GRALLOC_MAPPER_4
validateBufferSize(void * buffer,const IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t in_stride)341 Error validateBufferSize(void* buffer,
342                          const IMapper::BufferDescriptorInfo& descriptorInfo,
343                          uint32_t in_stride)
344 {
345 	/* The buffer must have been allocated by Gralloc */
346 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
347 	if (!bufferHandle)
348 	{
349 		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
350 		return Error::BAD_BUFFER;
351 	}
352 
353 	if (private_handle_t::validate(bufferHandle) < 0)
354 	{
355 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
356 		return Error::BAD_BUFFER;
357 	}
358 
359 	buffer_descriptor_t grallocDescriptor;
360 	grallocDescriptor.width = descriptorInfo.width;
361 	grallocDescriptor.height = descriptorInfo.height;
362 	grallocDescriptor.layer_count = descriptorInfo.layerCount;
363 	grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
364 	grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
365 	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
366 	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
367 
368 	/* Derive the buffer size for the given descriptor */
369 	const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
370 	if (result)
371 	{
372 		MALI_GRALLOC_LOGV("Unable to derive format and size for the given descriptor information. error: %d", result);
373 		return Error::BAD_VALUE;
374 	}
375 
376 	/* Validate the buffer parameters against descriptor info */
377 	private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;
378 
379 	/* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
380 	for (int i = 0; i < gralloc_buffer->fd_count; i++)
381 	{
382 		if (gralloc_buffer->alloc_sizes[i] < grallocDescriptor.alloc_sizes[i])
383 		{
384 			MALI_GRALLOC_LOGW("Buf size mismatch. fd_idx(%d) Buffer size = %" PRIu64 ", Descriptor (derived) size = %" PRIu64,
385 			       i, gralloc_buffer->alloc_sizes[i], grallocDescriptor.alloc_sizes[i]);
386 			return Error::BAD_VALUE;
387 		}
388 	}
389 
390 	if (in_stride != 0 && (uint32_t)gralloc_buffer->stride != in_stride)
391 	{
392 		MALI_GRALLOC_LOGE("Stride mismatch. Expected stride = %d, Buffer stride = %" PRIu64,
393 		                       in_stride, gralloc_buffer->stride);
394 		return Error::BAD_VALUE;
395 	}
396 
397 	if (gralloc_buffer->alloc_format != grallocDescriptor.alloc_format)
398 	{
399 		MALI_GRALLOC_LOGE("Buffer alloc format: (%s, 0x%" PRIx64") does not match descriptor (derived) alloc format: (%s 0x%"
400 			PRIx64 ")", format_name(gralloc_buffer->alloc_format), gralloc_buffer->alloc_format,
401 			format_name(grallocDescriptor.alloc_format), grallocDescriptor.alloc_format);
402 		return Error::BAD_VALUE;
403 	}
404 
405 	const int format_idx = get_format_index(gralloc_buffer->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
406 	if (format_idx == -1)
407 	{
408 		MALI_GRALLOC_LOGE("Invalid format to validate buffer descriptor");
409 		return Error::BAD_VALUE;
410 	}
411 	else
412 	{
413 		for (int i = 0; i < formats[format_idx].npln; i++)
414 		{
415 			if (gralloc_buffer->plane_info[i].byte_stride != grallocDescriptor.plane_info[i].byte_stride)
416 			{
417 				MALI_GRALLOC_LOGE("Buffer byte stride %" PRIu64 " mismatch with desc byte stride %" PRIu64 " in plane %d ",
418 				      gralloc_buffer->plane_info[i].byte_stride, grallocDescriptor.plane_info[i].byte_stride, i);
419 				return Error::BAD_VALUE;
420 			}
421 
422 			if (gralloc_buffer->plane_info[i].alloc_width != grallocDescriptor.plane_info[i].alloc_width)
423 			{
424 				MALI_GRALLOC_LOGE("Buffer alloc width %" PRIu64 " mismatch with desc alloc width %" PRIu64 " in plane %d ",
425 				      gralloc_buffer->plane_info[i].alloc_width, grallocDescriptor.plane_info[i].alloc_width, i);
426 				return Error::BAD_VALUE;
427 			}
428 
429 			if (gralloc_buffer->plane_info[i].alloc_height != grallocDescriptor.plane_info[i].alloc_height)
430 			{
431 				MALI_GRALLOC_LOGE("Buffer alloc height %" PRIu64 " mismatch with desc alloc height %" PRIu64 " in plane %d ",
432 				      gralloc_buffer->plane_info[i].alloc_height, grallocDescriptor.plane_info[i].alloc_height, i);
433 				return Error::BAD_VALUE;
434 			}
435 		}
436 	}
437 
438 	if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
439 	{
440 		MALI_GRALLOC_LOGE("Width mismatch. Buffer width = %u, Descriptor width = %u",
441 		      gralloc_buffer->width, grallocDescriptor.width);
442 		return Error::BAD_VALUE;
443 	}
444 
445 	if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
446 	{
447 		MALI_GRALLOC_LOGE("Height mismatch. Buffer height = %u, Descriptor height = %u",
448 		      gralloc_buffer->height, grallocDescriptor.height);
449 		return Error::BAD_VALUE;
450 	}
451 
452 	if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
453 	{
454 		MALI_GRALLOC_LOGE("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
455 		      gralloc_buffer->layer_count, grallocDescriptor.layer_count);
456 		return Error::BAD_VALUE;
457 	}
458 
459 	return Error::NONE;
460 }
461 #endif
462 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts)463 Error getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds, uint32_t *outNumInts)
464 {
465 	*outNumFds = 0;
466 	*outNumInts = 0;
467 	/* The buffer must have been allocated by Gralloc */
468 	if (!bufferHandle)
469 	{
470 		MALI_GRALLOC_LOGE("Buffer %p is not registered with Gralloc",
471 				  bufferHandle);
472 		return Error::BAD_BUFFER;
473 	}
474 
475 	if (private_handle_t::validate(bufferHandle) < 0)
476 	{
477 		MALI_GRALLOC_LOGE("Buffer %p is corrupted", bufferHandle);
478 		return Error::BAD_BUFFER;
479 	}
480 	*outNumFds = bufferHandle->numFds;
481 	*outNumInts = bufferHandle->numInts;
482 	return Error::NONE;
483 }
484 
485 #ifdef GRALLOC_MAPPER_4
isSupported(const IMapper::BufferDescriptorInfo & description)486 bool isSupported(const IMapper::BufferDescriptorInfo &description)
487 {
488 	buffer_descriptor_t grallocDescriptor;
489 	grallocDescriptor.width = description.width;
490 	grallocDescriptor.height = description.height;
491 	grallocDescriptor.layer_count = description.layerCount;
492 	grallocDescriptor.hal_format = static_cast<uint64_t>(description.format);
493 	grallocDescriptor.producer_usage = static_cast<uint64_t>(description.usage);
494 	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
495 	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
496 
497 	/* Check if it is possible to allocate a buffer for the given description */
498 	const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
499 	if (result != 0)
500 	{
501 		MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result);
502 		return false;
503 	}
504 	else
505 	{
506 		return true;
507 	}
508 }
509 
510 #endif
flushLockedBuffer(buffer_handle_t handle)511 Error flushLockedBuffer(buffer_handle_t handle)
512 {
513 	if (private_handle_t::validate(handle) < 0)
514 	{
515 		MALI_GRALLOC_LOGE("Handle: %p is corrupted", handle);
516 		return Error::BAD_BUFFER;
517 	}
518 
519 	auto private_handle = static_cast<const private_handle_t *>(handle);
520 	if (!private_handle->cpu_write && !private_handle->cpu_read)
521 	{
522 		MALI_GRALLOC_LOGE("Attempt to call flushLockedBuffer() on an unlocked buffer (%p)", handle);
523 		return Error::BAD_BUFFER;
524 	}
525 
526 	mali_gralloc_ion_sync_end(private_handle, false, true);
527 	return Error::NONE;
528 }
529 
rereadLockedBuffer(buffer_handle_t handle)530 Error rereadLockedBuffer(buffer_handle_t handle)
531 {
532 	if (private_handle_t::validate(handle) < 0)
533 	{
534 		MALI_GRALLOC_LOGE("Buffer: %p is corrupted", handle);
535 		return Error::BAD_BUFFER;
536 	}
537 
538 	auto private_handle = static_cast<const private_handle_t *>(handle);
539 	if (!private_handle->cpu_write && !private_handle->cpu_read)
540 	{
541 		MALI_GRALLOC_LOGE("Attempt to call rereadLockedBuffer() on an unlocked buffer (%p)", handle);
542 		return Error::BAD_BUFFER;
543 	}
544 
545 	mali_gralloc_ion_sync_start(private_handle, true, false);
546 	return Error::NONE;
547 }
548 
get(buffer_handle_t buffer,const MetadataType & metadataType,std::vector<uint8_t> & vec)549 Error get(buffer_handle_t buffer, const MetadataType &metadataType, std::vector<uint8_t> &vec)
550 {
551 	/* The buffer must have been allocated by Gralloc */
552 	const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
553 	if (handle == nullptr)
554 	{
555 		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
556 		return Error::BAD_BUFFER;
557 	}
558 
559 	if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
560 	{
561 		MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
562 		return Error::BAD_VALUE;
563 	}
564 
565 	return get_metadata(handle, metadataType, vec);
566 }
567 
set(buffer_handle_t buffer,const MetadataType & metadataType,const hidl_vec<uint8_t> & metadata)568 Error set(buffer_handle_t buffer, const MetadataType &metadataType, const hidl_vec<uint8_t> &metadata)
569 {
570 	/* The buffer must have been allocated by Gralloc */
571 	const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
572 	if (handle == nullptr)
573 	{
574 		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
575 		return Error::BAD_BUFFER;
576 	}
577 
578 	if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
579 	{
580 		MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
581 		return Error::BAD_VALUE;
582 	}
583 
584 	return set_metadata(handle, metadataType, metadata);
585 }
586 
describeStandard(StandardMetadataType meta,bool isGettable,bool isSettable)587 MetadataTypeDescription describeStandard(StandardMetadataType meta, bool isGettable, bool isSettable)
588 {
589 	return MetadataTypeDescription(MetadataType(GRALLOC4_STANDARD_METADATA_TYPE,
590 						    static_cast<uint64_t>(meta)), "", isGettable, isSettable);
591 }
592 
listSupportedMetadataTypes()593 std::vector<MetadataTypeDescription> listSupportedMetadataTypes()
594 {
595 	/* Returns a vector of {metadata type, description, isGettable, isSettable}
596 	*  Only non-standardMetadataTypes require a description.
597 	*/
598 	std::array<MetadataTypeDescription, 23> descriptions = {
599 		describeStandard(StandardMetadataType::BUFFER_ID, true, false ),
600 		describeStandard(StandardMetadataType::NAME, true, false ),
601 		describeStandard(StandardMetadataType::WIDTH, true, false ),
602 		describeStandard(StandardMetadataType::STRIDE, true, false ),
603 		describeStandard(StandardMetadataType::HEIGHT, true, false ),
604 		describeStandard(StandardMetadataType::LAYER_COUNT, true, false ),
605 		describeStandard(StandardMetadataType::PIXEL_FORMAT_REQUESTED, true, false ),
606 		describeStandard(StandardMetadataType::PIXEL_FORMAT_FOURCC, true, false ),
607 		describeStandard(StandardMetadataType::PIXEL_FORMAT_MODIFIER, true, false ),
608 		describeStandard(StandardMetadataType::USAGE, true, false ),
609 		describeStandard(StandardMetadataType::ALLOCATION_SIZE, true, false ),
610 		describeStandard(StandardMetadataType::PROTECTED_CONTENT, true, false ),
611 		describeStandard(StandardMetadataType::COMPRESSION, true, false ),
612 		describeStandard(StandardMetadataType::INTERLACED, true, false ),
613 		describeStandard(StandardMetadataType::CHROMA_SITING, true, false ),
614 		describeStandard(StandardMetadataType::PLANE_LAYOUTS, true, false ),
615 		describeStandard(StandardMetadataType::DATASPACE, true, true ),
616 		describeStandard(StandardMetadataType::BLEND_MODE, true, true ),
617 		describeStandard(StandardMetadataType::SMPTE2086, true, true ),
618 		describeStandard(StandardMetadataType::CTA861_3, true, true ),
619 		describeStandard(StandardMetadataType::SMPTE2094_40, true, true ),
620 		describeStandard(StandardMetadataType::CROP, true, true ),
621 		/* Arm vendor metadata */
622 		{ ArmMetadataType_PLANE_FDS,
623 			"Vector of file descriptors of each plane", true, false},
624         };
625 	return std::vector<MetadataTypeDescription>(descriptions.begin(), descriptions.end());
626 }
627 
628 
dumpBufferHelper(const private_handle_t * handle)629 static BufferDump dumpBufferHelper(const private_handle_t *handle)
630 {
631 	static std::array<MetadataType, 21> standardMetadataTypes = {
632 		MetadataType(StandardMetadataType::BUFFER_ID),
633 		MetadataType(StandardMetadataType::NAME),
634 		MetadataType(StandardMetadataType::WIDTH),
635 		MetadataType(StandardMetadataType::HEIGHT),
636 		MetadataType(StandardMetadataType::LAYER_COUNT),
637 		MetadataType(StandardMetadataType::PIXEL_FORMAT_REQUESTED),
638 		MetadataType(StandardMetadataType::PIXEL_FORMAT_FOURCC),
639 		MetadataType(StandardMetadataType::PIXEL_FORMAT_MODIFIER),
640 		MetadataType(StandardMetadataType::USAGE),
641 		MetadataType(StandardMetadataType::ALLOCATION_SIZE),
642 		MetadataType(StandardMetadataType::PROTECTED_CONTENT),
643 		MetadataType(StandardMetadataType::COMPRESSION),
644 		MetadataType(StandardMetadataType::INTERLACED),
645 		MetadataType(StandardMetadataType::CHROMA_SITING),
646 		MetadataType(StandardMetadataType::PLANE_LAYOUTS),
647 		MetadataType(StandardMetadataType::DATASPACE),
648 		MetadataType(StandardMetadataType::BLEND_MODE),
649 		MetadataType(StandardMetadataType::SMPTE2086),
650 		MetadataType(StandardMetadataType::CTA861_3),
651 		MetadataType(StandardMetadataType::SMPTE2094_40),
652 		MetadataType(StandardMetadataType::CROP),
653 	};
654 
655 	std::vector<MetadataDump> metadataDumps;
656 	for (const auto& metadataType: standardMetadataTypes)
657 	{
658 		std::vector<uint8_t> metadata;
659 		Error error = get_metadata(handle, metadataType, metadata);
660 		if (error == Error::NONE)
661 		{
662 			metadataDumps.push_back(MetadataDump(MetadataType(metadataType), metadata));
663 		}
664 		else
665 		{
666 			return BufferDump();
667 		}
668 	}
669 	return BufferDump(metadataDumps);
670 }
671 
dumpBuffer(buffer_handle_t buffer,BufferDump & bufferDump)672 Error dumpBuffer(buffer_handle_t buffer, BufferDump &bufferDump)
673 {
674 	auto handle = static_cast<const private_handle_t *>(buffer);
675 	if (handle == nullptr)
676 	{
677 		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
678 		return Error::BAD_BUFFER;
679 	}
680 
681 	bufferDump = dumpBufferHelper(handle);
682 	return Error::NONE;
683 }
684 
dumpBuffers()685 std::vector<BufferDump> dumpBuffers()
686 {
687 	std::vector<BufferDump> bufferDumps;
688 	gRegisteredHandles->for_each([&bufferDumps](buffer_handle_t buffer) {
689 		BufferDump bufferDump { dumpBufferHelper(static_cast<const private_handle_t *>(buffer)) };
690 		bufferDumps.push_back(bufferDump);
691 	});
692 	return bufferDumps;
693 }
694 
getReservedRegion(buffer_handle_t buffer,void ** outReservedRegion,uint64_t & outReservedSize)695 Error getReservedRegion(buffer_handle_t buffer, void **outReservedRegion, uint64_t &outReservedSize)
696 {
697 	auto handle = static_cast<const private_handle_t *>(buffer);
698 	if (handle == nullptr)
699 	{
700 		MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
701 		return Error::BAD_BUFFER;
702 	}
703 	else if (handle->reserved_region_size == 0)
704 	{
705 		MALI_GRALLOC_LOGE("Buffer: %p has no reserved region", buffer);
706 		return Error::BAD_BUFFER;
707 	}
708 
709 	auto metadata_addr_oe = mali_gralloc_reference_get_metadata_addr(handle);
710 	if (!metadata_addr_oe.has_value()) {
711 		return Error::BAD_BUFFER;
712 	}
713 
714 	*outReservedRegion = static_cast<std::byte *>(metadata_addr_oe.value())
715 	    + mapper::common::shared_metadata_size();
716 	outReservedSize = handle->reserved_region_size;
717 	return Error::NONE;
718 }
719 
720 } // namespace common
721 } // namespace mapper
722 } // namespace arm
723