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