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