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);
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
249 const int result = mali_gralloc_unlock(bufferHandle);
250 if (result)
251 {
252 MALI_GRALLOC_LOGE("Unlocking failed with error: %d", result);
253 return Error::BAD_VALUE;
254 }
255
256 *outFenceFd = -1;
257
258 return Error::NONE;
259 }
260
importBuffer(const hidl_handle & rawHandle,IMapper::importBuffer_cb hidl_cb)261 void importBuffer(const hidl_handle& rawHandle, IMapper::importBuffer_cb hidl_cb)
262 {
263 if (!rawHandle.getNativeHandle())
264 {
265 MALI_GRALLOC_LOGE("Invalid buffer handle to import");
266 hidl_cb(Error::BAD_BUFFER, nullptr);
267 return;
268 }
269
270 native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
271 if (!bufferHandle)
272 {
273 MALI_GRALLOC_LOGE("Failed to clone buffer handle");
274 hidl_cb(Error::NO_RESOURCES, nullptr);
275 return;
276 }
277
278 const Error error = registerBuffer(bufferHandle);
279 if (error != Error::NONE)
280 {
281 native_handle_close(bufferHandle);
282 native_handle_delete(bufferHandle);
283
284 hidl_cb(error, nullptr);
285 return;
286 }
287
288 auto *private_handle = static_cast<private_handle_t *>(bufferHandle);
289
290 if (gRegisteredHandles->add(bufferHandle) == false)
291 {
292 /* The newly cloned handle is already registered. This can only happen
293 * when a handle previously registered was native_handle_delete'd instead
294 * of freeBuffer'd.
295 */
296 MALI_GRALLOC_LOGE("Handle %p has already been imported; potential fd leaking",
297 bufferHandle);
298 unregisterBuffer(bufferHandle);
299 native_handle_close(bufferHandle);
300 native_handle_delete(bufferHandle);
301
302 hidl_cb(Error::NO_RESOURCES, nullptr);
303 return;
304 }
305
306 hidl_cb(Error::NONE, bufferHandle);
307 }
308
freeBuffer(void * buffer)309 Error freeBuffer(void* buffer)
310 {
311 native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer);
312 if (!bufferHandle)
313 {
314 MALI_GRALLOC_LOGE("Invalid buffer handle %p to freeBuffer", buffer);
315 return Error::BAD_BUFFER;
316 }
317
318 const Error status = unregisterBuffer(bufferHandle);
319 if (status != Error::NONE)
320 {
321 return status;
322 }
323
324 native_handle_close(bufferHandle);
325 native_handle_delete(bufferHandle);
326
327 return Error::NONE;
328 }
329
lock(void * buffer,uint64_t cpuUsage,const IMapper::Rect & accessRegion,const hidl_handle & acquireFence,IMapper::lock_cb hidl_cb)330 void lock(void* buffer, uint64_t cpuUsage, const IMapper::Rect& accessRegion,
331 const hidl_handle& acquireFence, IMapper::lock_cb hidl_cb)
332 {
333 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
334 if (!bufferHandle || private_handle_t::validate(bufferHandle) < 0)
335 {
336 MALI_GRALLOC_LOGE("Buffer to lock: %p is not valid", buffer);
337 hidl_cb(Error::BAD_BUFFER, nullptr);
338 return;
339 }
340
341 int fenceFd;
342 if (!getFenceFd(acquireFence, &fenceFd))
343 {
344 hidl_cb(Error::BAD_VALUE, nullptr);
345 return;
346 }
347
348 void* data = nullptr;
349 const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
350
351 hidl_cb(error, data);
352 }
353
unlock(void * buffer,IMapper::unlock_cb hidl_cb)354 void unlock(void* buffer, IMapper::unlock_cb hidl_cb)
355 {
356 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
357 if (!bufferHandle)
358 {
359 MALI_GRALLOC_LOGE("Buffer to unlock: %p has not been registered with Gralloc", buffer);
360 hidl_cb(Error::BAD_BUFFER, nullptr);
361 return;
362 }
363
364 int fenceFd;
365 const Error error = unlockBuffer(bufferHandle, &fenceFd);
366 if (error == Error::NONE)
367 {
368 NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
369 hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
370
371 if (fenceFd >= 0)
372 {
373 close(fenceFd);
374 }
375 }
376 else
377 {
378 hidl_cb(error, nullptr);
379 }
380 }
381
validateBufferSize(void * buffer,const IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t in_stride)382 Error validateBufferSize(void* buffer,
383 const IMapper::BufferDescriptorInfo& descriptorInfo,
384 uint32_t in_stride)
385 {
386 /* The buffer must have been allocated by Gralloc */
387 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
388 if (!bufferHandle)
389 {
390 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
391 return Error::BAD_BUFFER;
392 }
393
394 if (private_handle_t::validate(bufferHandle) < 0)
395 {
396 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
397 return Error::BAD_BUFFER;
398 }
399
400 buffer_descriptor_t grallocDescriptor;
401 grallocDescriptor.width = descriptorInfo.width;
402 grallocDescriptor.height = descriptorInfo.height;
403 grallocDescriptor.layer_count = descriptorInfo.layerCount;
404 grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
405 grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
406 grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
407 grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
408
409 /* Derive the buffer size for the given descriptor */
410 const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
411 if (result)
412 {
413 MALI_GRALLOC_LOGV("Unable to derive format and size for the given descriptor information. error: %d", result);
414 return Error::BAD_VALUE;
415 }
416
417 /* Validate the buffer parameters against descriptor info */
418 private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;
419
420 /* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
421 for (int i = 0; i < gralloc_buffer->fd_count; i++)
422 {
423 if (gralloc_buffer->alloc_sizes[i] < grallocDescriptor.alloc_sizes[i])
424 {
425 MALI_GRALLOC_LOGW("Buf size mismatch. fd_idx(%d) Buffer size = %" PRIu64 ", Descriptor (derived) size = %" PRIu64,
426 i, gralloc_buffer->alloc_sizes[i], grallocDescriptor.alloc_sizes[i]);
427 return Error::BAD_VALUE;
428 }
429 }
430
431 if (in_stride != 0 && (uint32_t)gralloc_buffer->stride != in_stride)
432 {
433 MALI_GRALLOC_LOGE("Stride mismatch. Expected stride = %d, Buffer stride = %d",
434 in_stride, gralloc_buffer->stride);
435 return Error::BAD_VALUE;
436 }
437
438 if (gralloc_buffer->alloc_format != grallocDescriptor.alloc_format)
439 {
440 MALI_GRALLOC_LOGE("Buffer alloc format: (%s, 0x%" PRIx64") does not match descriptor (derived) alloc format: (%s 0x%"
441 PRIx64 ")", format_name(gralloc_buffer->alloc_format), gralloc_buffer->alloc_format,
442 format_name(grallocDescriptor.alloc_format), grallocDescriptor.alloc_format);
443 return Error::BAD_VALUE;
444 }
445
446 const int format_idx = get_format_index(gralloc_buffer->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
447 if (format_idx == -1)
448 {
449 MALI_GRALLOC_LOGE("Invalid format to validate buffer descriptor");
450 return Error::BAD_VALUE;
451 }
452 else
453 {
454 for (int i = 0; i < formats[format_idx].npln; i++)
455 {
456 if (gralloc_buffer->plane_info[i].byte_stride != grallocDescriptor.plane_info[i].byte_stride)
457 {
458 MALI_GRALLOC_LOGE("Buffer byte stride 0x%x mismatch with desc byte stride 0x%x in plane %d ",
459 gralloc_buffer->plane_info[i].byte_stride, grallocDescriptor.plane_info[i].byte_stride, i);
460 return Error::BAD_VALUE;
461 }
462
463 if (gralloc_buffer->plane_info[i].alloc_width != grallocDescriptor.plane_info[i].alloc_width)
464 {
465 MALI_GRALLOC_LOGE("Buffer alloc width 0x%x mismatch with desc alloc width 0x%x in plane %d ",
466 gralloc_buffer->plane_info[i].alloc_width, grallocDescriptor.plane_info[i].alloc_width, i);
467 return Error::BAD_VALUE;
468 }
469
470 if (gralloc_buffer->plane_info[i].alloc_height != grallocDescriptor.plane_info[i].alloc_height)
471 {
472 MALI_GRALLOC_LOGE("Buffer alloc height 0x%x mismatch with desc alloc height 0x%x in plane %d ",
473 gralloc_buffer->plane_info[i].alloc_height, grallocDescriptor.plane_info[i].alloc_height, i);
474 return Error::BAD_VALUE;
475 }
476 }
477 }
478
479 if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
480 {
481 MALI_GRALLOC_LOGE("Width mismatch. Buffer width = %u, Descriptor width = %u",
482 gralloc_buffer->width, grallocDescriptor.width);
483 return Error::BAD_VALUE;
484 }
485
486 if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
487 {
488 MALI_GRALLOC_LOGE("Height mismatch. Buffer height = %u, Descriptor height = %u",
489 gralloc_buffer->height, grallocDescriptor.height);
490 return Error::BAD_VALUE;
491 }
492
493 if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
494 {
495 MALI_GRALLOC_LOGE("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
496 gralloc_buffer->layer_count, grallocDescriptor.layer_count);
497 return Error::BAD_VALUE;
498 }
499
500 return Error::NONE;
501 }
502
getTransportSize(void * buffer,IMapper::getTransportSize_cb hidl_cb)503 void getTransportSize(void* buffer, IMapper::getTransportSize_cb hidl_cb)
504 {
505 /* The buffer must have been allocated by Gralloc */
506 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
507 if (!bufferHandle)
508 {
509 MALI_GRALLOC_LOGE("Buffer %p is not registered with Gralloc", bufferHandle);
510 hidl_cb(Error::BAD_BUFFER, -1, -1);
511 return;
512 }
513
514 if (private_handle_t::validate(bufferHandle) < 0)
515 {
516 MALI_GRALLOC_LOGE("Buffer %p is corrupted", buffer);
517 hidl_cb(Error::BAD_BUFFER, -1, -1);
518 return;
519 }
520 hidl_cb(Error::NONE, bufferHandle->numFds, bufferHandle->numInts);
521 }
522
isSupported(const IMapper::BufferDescriptorInfo & description,IMapper::isSupported_cb hidl_cb)523 void isSupported(const IMapper::BufferDescriptorInfo& description, IMapper::isSupported_cb hidl_cb)
524 {
525 buffer_descriptor_t grallocDescriptor;
526 grallocDescriptor.width = description.width;
527 grallocDescriptor.height = description.height;
528 grallocDescriptor.layer_count = description.layerCount;
529 grallocDescriptor.hal_format = static_cast<uint64_t>(description.format);
530 grallocDescriptor.producer_usage = static_cast<uint64_t>(description.usage);
531 grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
532 grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
533
534 /* Check if it is possible to allocate a buffer for the given description */
535 const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
536 if (result != 0)
537 {
538 MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result);
539 hidl_cb(Error::NONE, false);
540 }
541 else
542 {
543 hidl_cb(Error::NONE, true);
544 }
545 }
546
flushLockedBuffer(void * buffer,IMapper::flushLockedBuffer_cb hidl_cb)547 void flushLockedBuffer(void *buffer, IMapper::flushLockedBuffer_cb hidl_cb)
548 {
549 buffer_handle_t handle = gRegisteredHandles->get(buffer);
550 if (private_handle_t::validate(handle) < 0)
551 {
552 MALI_GRALLOC_LOGE("Bandle: %p is corrupted", handle);
553 hidl_cb(Error::BAD_BUFFER, hidl_handle{});
554 return;
555 }
556
557 auto private_handle = static_cast<const private_handle_t *>(handle);
558 if (!private_handle->cpu_write && !private_handle->cpu_read)
559 {
560 MALI_GRALLOC_LOGE("Attempt to call flushLockedBuffer() on an unlocked buffer (%p)", handle);
561 hidl_cb(Error::BAD_BUFFER, hidl_handle{});
562 return;
563 }
564
565 mali_gralloc_ion_sync_end(private_handle, false, true);
566 hidl_cb(Error::NONE, hidl_handle{});
567 }
568
rereadLockedBuffer(void * buffer)569 Error rereadLockedBuffer(void *buffer)
570 {
571 buffer_handle_t handle = gRegisteredHandles->get(buffer);
572 if (private_handle_t::validate(handle) < 0)
573 {
574 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", handle);
575 return Error::BAD_BUFFER;
576 }
577
578 auto private_handle = static_cast<const private_handle_t *>(handle);
579 if (!private_handle->cpu_write && !private_handle->cpu_read)
580 {
581 MALI_GRALLOC_LOGE("Attempt to call rereadLockedBuffer() on an unlocked buffer (%p)", handle);
582 return Error::BAD_BUFFER;
583 }
584
585 mali_gralloc_ion_sync_start(private_handle, true, false);
586 return Error::NONE;
587 }
588
get(void * buffer,const IMapper::MetadataType & metadataType,IMapper::get_cb hidl_cb)589 void get(void *buffer, const IMapper::MetadataType &metadataType, IMapper::get_cb hidl_cb)
590 {
591 /* The buffer must have been allocated by Gralloc */
592 const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
593 if (handle == nullptr)
594 {
595 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
596 hidl_cb(Error::BAD_BUFFER, hidl_vec<uint8_t>());
597 return;
598 }
599
600 if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
601 {
602 MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
603 hidl_cb(Error::BAD_VALUE, hidl_vec<uint8_t>());
604 return;
605 }
606
607 get_metadata(handle, metadataType, hidl_cb);
608 }
609
set(void * buffer,const IMapper::MetadataType & metadataType,const hidl_vec<uint8_t> & metadata)610 Error set(void *buffer, const IMapper::MetadataType &metadataType, const hidl_vec<uint8_t> &metadata)
611 {
612 /* The buffer must have been allocated by Gralloc */
613 const private_handle_t *handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
614 if (handle == nullptr)
615 {
616 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
617 return Error::BAD_BUFFER;
618 }
619
620 if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
621 {
622 MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
623 return Error::BAD_VALUE;
624 }
625
626 return set_metadata(handle, metadataType, metadata);
627 }
628
listSupportedMetadataTypes(IMapper::listSupportedMetadataTypes_cb hidl_cb)629 void listSupportedMetadataTypes(IMapper::listSupportedMetadataTypes_cb hidl_cb)
630 {
631 /* Returns a vector of {metadata type, description, isGettable, isSettable}
632 * Only non-standardMetadataTypes require a description.
633 */
634 hidl_vec<IMapper::MetadataTypeDescription> descriptions = {
635 { android::gralloc4::MetadataType_BufferId, "", true, false },
636 { android::gralloc4::MetadataType_Name, "", true, false },
637 { android::gralloc4::MetadataType_Width, "", true, false },
638 { android::gralloc4::MetadataType_Height, "", true, false },
639 { android::gralloc4::MetadataType_LayerCount, "", true, false },
640 { android::gralloc4::MetadataType_PixelFormatRequested, "", true, false },
641 { android::gralloc4::MetadataType_PixelFormatFourCC, "", true, false },
642 { android::gralloc4::MetadataType_PixelFormatModifier, "", true, false },
643 { android::gralloc4::MetadataType_Usage, "", true, false },
644 { android::gralloc4::MetadataType_AllocationSize, "", true, false },
645 { android::gralloc4::MetadataType_ProtectedContent, "", true, false },
646 { android::gralloc4::MetadataType_Compression, "", true, false },
647 { android::gralloc4::MetadataType_Interlaced, "", true, false },
648 { android::gralloc4::MetadataType_ChromaSiting, "", true, false },
649 { android::gralloc4::MetadataType_PlaneLayouts, "", true, false },
650 { android::gralloc4::MetadataType_Dataspace, "", true, true },
651 { android::gralloc4::MetadataType_BlendMode, "", true, true },
652 { android::gralloc4::MetadataType_Smpte2086, "", true, true },
653 { android::gralloc4::MetadataType_Cta861_3, "", true, true },
654 { android::gralloc4::MetadataType_Smpte2094_40, "", true, true },
655 { android::gralloc4::MetadataType_Crop, "", true, true },
656 /* Arm vendor metadata */
657 { ArmMetadataType_PLANE_FDS,
658 "Vector of file descriptors of each plane", true, false },
659 };
660 hidl_cb(Error::NONE, descriptions);
661 return;
662 }
663
664
dumpBufferHelper(const private_handle_t * handle)665 static hidl_vec<IMapper::MetadataDump> dumpBufferHelper(const private_handle_t* handle)
666 {
667 hidl_vec<IMapper::MetadataType> standardMetadataTypes = {
668 android::gralloc4::MetadataType_BufferId,
669 android::gralloc4::MetadataType_Name,
670 android::gralloc4::MetadataType_Width,
671 android::gralloc4::MetadataType_Height,
672 android::gralloc4::MetadataType_LayerCount,
673 android::gralloc4::MetadataType_PixelFormatRequested,
674 android::gralloc4::MetadataType_PixelFormatFourCC,
675 android::gralloc4::MetadataType_PixelFormatModifier,
676 android::gralloc4::MetadataType_Usage,
677 android::gralloc4::MetadataType_AllocationSize,
678 android::gralloc4::MetadataType_ProtectedContent,
679 android::gralloc4::MetadataType_Compression,
680 android::gralloc4::MetadataType_Interlaced,
681 android::gralloc4::MetadataType_ChromaSiting,
682 android::gralloc4::MetadataType_PlaneLayouts,
683 android::gralloc4::MetadataType_Dataspace,
684 android::gralloc4::MetadataType_BlendMode,
685 android::gralloc4::MetadataType_Smpte2086,
686 android::gralloc4::MetadataType_Cta861_3,
687 android::gralloc4::MetadataType_Smpte2094_40,
688 android::gralloc4::MetadataType_Crop,
689 };
690
691 std::vector<IMapper::MetadataDump> metadataDumps;
692 for (const auto& metadataType: standardMetadataTypes)
693 {
694 get_metadata(handle, metadataType, [&metadataDumps, &metadataType](Error error, hidl_vec<uint8_t> metadata) {
695 switch(error)
696 {
697 case Error::NONE:
698 metadataDumps.push_back({metadataType, metadata});
699 break;
700 case Error::UNSUPPORTED:
701 default:
702 return;
703 }
704 });
705 }
706 return hidl_vec<IMapper::MetadataDump>(metadataDumps);
707 }
708
dumpBuffer(void * buffer,IMapper::dumpBuffer_cb hidl_cb)709 void dumpBuffer(void *buffer, IMapper::dumpBuffer_cb hidl_cb)
710 {
711 IMapper::BufferDump bufferDump{};
712 auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
713 if (handle == nullptr)
714 {
715 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
716 hidl_cb(Error::BAD_BUFFER, bufferDump);
717 return;
718 }
719
720 bufferDump.metadataDump = dumpBufferHelper(handle);
721 hidl_cb(Error::NONE, bufferDump);
722 }
723
dumpBuffers(IMapper::dumpBuffers_cb hidl_cb)724 void dumpBuffers(IMapper::dumpBuffers_cb hidl_cb)
725 {
726 std::vector<IMapper::BufferDump> bufferDumps;
727 gRegisteredHandles->for_each([&bufferDumps](buffer_handle_t buffer) {
728 IMapper::BufferDump bufferDump { dumpBufferHelper(static_cast<const private_handle_t *>(buffer)) };
729 bufferDumps.push_back(bufferDump);
730 });
731 hidl_cb(Error::NONE, hidl_vec<IMapper::BufferDump>(bufferDumps));
732 }
733
getReservedRegion(void * buffer,IMapper::getReservedRegion_cb hidl_cb)734 void getReservedRegion(void *buffer, IMapper::getReservedRegion_cb hidl_cb)
735 {
736 auto handle = static_cast<const private_handle_t *>(gRegisteredHandles->get(buffer));
737 if (handle == nullptr)
738 {
739 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
740 hidl_cb(Error::BAD_BUFFER, 0, 0);
741 return;
742 }
743 else if (handle->reserved_region_size == 0)
744 {
745 MALI_GRALLOC_LOGE("Buffer: %p has no reserved region", buffer);
746 hidl_cb(Error::BAD_BUFFER, 0, 0);
747 return;
748 }
749
750 auto metadata_addr_oe = mali_gralloc_reference_get_metadata_addr(handle);
751 if (!metadata_addr_oe.has_value()) {
752 hidl_cb(Error::BAD_BUFFER, 0, 0);
753 }
754
755 void *reserved_region = static_cast<std::byte *>(metadata_addr_oe.value())
756 + mapper::common::shared_metadata_size();
757 hidl_cb(Error::NONE, reserved_region, handle->reserved_region_size);
758 }
759
760 } // namespace common
761 } // namespace mapper
762 } // namespace arm
763