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
34 #include "MapperMetadata.h"
35 #include "SharedMetadata.h"
36
37 #include "drmutils.h"
38
39 #include <cstdio>
40
41 /* GraphicBufferMapper is expected to be valid (and leaked) during process
42 * termination. IMapper, and in turn, gRegisteredHandles must be valid as
43 * well. Create the registered handle pool on the heap, and let
44 * it leak for simplicity.
45 *
46 * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
47 * of static/global object in gralloc0/gralloc1 that may have been destructed
48 * is potentially broken.
49 */
50 RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;
51
52 namespace arm {
53 namespace mapper {
54 namespace common {
55
getBuffer(void * buffer)56 buffer_handle_t getBuffer(void *buffer) {
57 return gRegisteredHandles->get(buffer);
58 }
59
60 using PixelMetadataType = ::pixel::graphics::MetadataType;
61
62 #ifdef GRALLOC_MAPPER_5
63
64 template <typename F, StandardMetadataType metadataType>
getStandardMetadataHelper(const private_handle_t * hnd,F && provide,StandardMetadata<metadataType>)65 int32_t getStandardMetadataHelper(const private_handle_t *hnd, F &&provide,
66 StandardMetadata<metadataType>) {
67 if constexpr (metadataType == StandardMetadataType::BUFFER_ID) {
68 return provide(hnd->backing_store_id);
69 }
70 if constexpr (metadataType == StandardMetadataType::WIDTH) {
71 return provide(hnd->width);
72 }
73 if constexpr (metadataType == StandardMetadataType::HEIGHT) {
74 return provide(hnd->height);
75 }
76 if constexpr (metadataType == StandardMetadataType::LAYER_COUNT) {
77 return provide(hnd->layer_count);
78 }
79 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_REQUESTED) {
80 return provide(static_cast<PixelFormat>(hnd->req_format));
81 }
82 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_FOURCC) {
83 return provide(drm_fourcc_from_handle(hnd));
84 }
85 if constexpr (metadataType == StandardMetadataType::PIXEL_FORMAT_MODIFIER) {
86 return provide(drm_modifier_from_handle(hnd));
87 }
88 if constexpr (metadataType == StandardMetadataType::USAGE) {
89 return provide(static_cast<BufferUsage>(hnd->consumer_usage | hnd->producer_usage));
90 }
91 if constexpr (metadataType == StandardMetadataType::ALLOCATION_SIZE) {
92 uint64_t total_size = 0;
93 for (int fidx = 0; fidx < hnd->fd_count; fidx++) {
94 total_size += hnd->alloc_sizes[fidx];
95 }
96 return provide(total_size);
97 }
98 if constexpr (metadataType == StandardMetadataType::PROTECTED_CONTENT) {
99 return provide((((hnd->consumer_usage | hnd->producer_usage) &
100 static_cast<uint64_t>(BufferUsage::PROTECTED)) == 0)
101 ? 0
102 : 1);
103 }
104 if constexpr (metadataType == StandardMetadataType::COMPRESSION) {
105 ExtendableType compression = android::gralloc4::Compression_None;
106 if (hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
107 compression = common::Compression_AFBC;
108 return provide(compression);
109 }
110 if constexpr (metadataType == StandardMetadataType::INTERLACED) {
111 return provide(android::gralloc4::Interlaced_None);
112 }
113 if constexpr (metadataType == StandardMetadataType::CHROMA_SITING) {
114 ExtendableType siting = android::gralloc4::ChromaSiting_None;
115 int format_index = get_format_index(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
116 if (formats[format_index].is_yuv) siting = android::gralloc4::ChromaSiting_Unknown;
117 return provide(siting);
118 }
119 if constexpr (metadataType == StandardMetadataType::PLANE_LAYOUTS) {
120 std::vector<PlaneLayout> layouts;
121 Error err = static_cast<Error>(common::get_plane_layouts(hnd, &layouts));
122 return provide(layouts);
123 }
124 if constexpr (metadataType == StandardMetadataType::NAME) {
125 std::string name;
126 common::get_name(hnd, &name);
127 return provide(name);
128 }
129 if constexpr (metadataType == StandardMetadataType::CROP) {
130 const int num_planes = common::get_num_planes(hnd);
131 std::vector<Rect> crops(num_planes);
132 for (size_t plane_index = 0; plane_index < num_planes; ++plane_index) {
133 Rect rect = {.top = 0,
134 .left = 0,
135 .right = static_cast<int32_t>(hnd->plane_info[plane_index].alloc_width),
136 .bottom = static_cast<int32_t>(hnd->plane_info[plane_index].alloc_height)};
137 if (plane_index == 0) {
138 std::optional<Rect> crop_rect;
139 common::get_crop_rect(hnd, &crop_rect);
140 if (crop_rect.has_value()) {
141 rect = crop_rect.value();
142 } else {
143 rect = {.top = 0, .left = 0, .right = hnd->width, .bottom = hnd->height};
144 }
145 }
146 crops[plane_index] = rect;
147 }
148 return provide(crops);
149 }
150 if constexpr (metadataType == StandardMetadataType::DATASPACE) {
151 std::optional<Dataspace> dataspace;
152 common::get_dataspace(hnd, &dataspace);
153 return provide(dataspace.value_or(Dataspace::UNKNOWN));
154 }
155 if constexpr (metadataType == StandardMetadataType::BLEND_MODE) {
156 std::optional<BlendMode> blendmode;
157 common::get_blend_mode(hnd, &blendmode);
158 return provide(blendmode.value_or(BlendMode::INVALID));
159 }
160 if constexpr (metadataType == StandardMetadataType::SMPTE2086) {
161 std::optional<Smpte2086> smpte2086;
162 common::get_smpte2086(hnd, &smpte2086);
163 return provide(smpte2086);
164 }
165 if constexpr (metadataType == StandardMetadataType::CTA861_3) {
166 std::optional<Cta861_3> cta861_3;
167 common::get_cta861_3(hnd, &cta861_3);
168 return provide(cta861_3);
169 }
170 if constexpr (metadataType == StandardMetadataType::SMPTE2094_40) {
171 std::optional<std::vector<uint8_t>> smpte2094_40;
172 common::get_smpte2094_40(hnd, &smpte2094_40);
173 return provide(smpte2094_40);
174 }
175 if constexpr (metadataType == StandardMetadataType::STRIDE) {
176 std::vector<PlaneLayout> layouts;
177 Error err = static_cast<Error>(common::get_plane_layouts(hnd, &layouts));
178 uint64_t stride = 0;
179 switch (hnd->get_alloc_format()) {
180 case HAL_PIXEL_FORMAT_RAW10:
181 case HAL_PIXEL_FORMAT_RAW12:
182 stride = layouts[0].strideInBytes;
183 break;
184 default:
185 stride = hnd->plane_info[0].alloc_width;
186 break;
187 }
188 return provide(stride);
189 }
190 return -AIMapper_Error::AIMAPPER_ERROR_UNSUPPORTED;
191 }
192
getPixelMetadataHelper(const private_handle_t * handle,const PixelMetadataType meta,void * outData,size_t outDataSize)193 int32_t getPixelMetadataHelper(const private_handle_t *handle, const PixelMetadataType meta,
194 void *outData, size_t outDataSize) {
195 switch (meta) {
196 case PixelMetadataType::VIDEO_HDR: {
197 auto result = ::pixel::graphics::utils::encode(common::get_video_hdr(handle));
198 if (result.size() <= outDataSize) std::memcpy(outData, result.data(), result.size());
199 return result.size();
200 }
201 case PixelMetadataType::VIDEO_ROI: {
202 auto result = ::pixel::graphics::utils::encode(common::get_video_roiinfo(handle));
203 if (result.size() <= outDataSize) std::memcpy(outData, result.data(), result.size());
204 return result.size();
205 }
206 case PixelMetadataType::VIDEO_GMV: {
207 auto result = ::pixel::graphics::utils::encode(common::get_video_gmv(handle));
208 if (result.size() <= outDataSize) std::memcpy(outData, result.data(), result.size());
209 return result.size();
210 }
211 case PixelMetadataType::PLANE_DMA_BUFS: {
212 std::vector<int> plane_fds(MAX_BUFFER_FDS, -1);
213 for (int i = 0; i < get_num_planes(handle); i++) {
214 plane_fds[i] = handle->fds[handle->plane_info[i].fd_idx];
215 }
216 auto result = ::pixel::graphics::utils::encode(plane_fds);
217 if (result.size() <= outDataSize) std::memcpy(outData, result.data(), result.size());
218 return result.size();
219 }
220 default:
221 return -AIMapper_Error::AIMAPPER_ERROR_BAD_VALUE;
222 }
223 }
224
getStandardMetadata(const private_handle_t * handle,StandardMetadataType metadata_type,void * _Nonnull outData,size_t outDataSize)225 int32_t getStandardMetadata(const private_handle_t *handle, StandardMetadataType metadata_type,
226 void *_Nonnull outData, size_t outDataSize) {
227 if (handle == nullptr) return -AIMapper_Error::AIMAPPER_ERROR_BAD_BUFFER;
228
229 auto provider = [&]<StandardMetadataType meta>(auto &&provide) -> int32_t {
230 return common::getStandardMetadataHelper(handle, provide, StandardMetadata<meta>{});
231 };
232 return android::hardware::graphics::mapper::provideStandardMetadata(metadata_type, outData,
233 outDataSize, provider);
234 }
235
236 #endif
237
238 /*
239 * Translates the register buffer API into existing gralloc implementation
240 *
241 * @param bufferHandle [in] Private handle for the buffer to be imported
242 *
243 * @return Error::BAD_BUFFER for an invalid buffer
244 * Error::NO_RESOURCES when unable to import the given buffer
245 * Error::NONE on successful import
246 */
registerBuffer(buffer_handle_t bufferHandle)247 static Error registerBuffer(buffer_handle_t bufferHandle)
248 {
249 if (private_handle_t::validate(bufferHandle) < 0)
250 {
251 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
252 return Error::BAD_BUFFER;
253 }
254
255 if (mali_gralloc_reference_retain(bufferHandle) < 0)
256 {
257 return Error::NO_RESOURCES;
258 }
259
260 return Error::NONE;
261 }
262
263 /*
264 * Translates the unregister buffer API into existing gralloc implementation
265 *
266 * @param bufferHandle [in] Private handle for the buffer to be released
267 *
268 * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released
269 * Error::NONE on successful release of the buffer
270 */
unregisterBuffer(buffer_handle_t bufferHandle)271 static Error unregisterBuffer(buffer_handle_t bufferHandle)
272 {
273 if (private_handle_t::validate(bufferHandle) < 0)
274 {
275 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
276 return Error::BAD_BUFFER;
277 }
278
279 const int status = mali_gralloc_reference_release(bufferHandle);
280 if (status != 0)
281 {
282 MALI_GRALLOC_LOGE("Unable to release buffer:%p", bufferHandle);
283 return Error::BAD_BUFFER;
284 }
285
286 return Error::NONE;
287 }
288
289 /*
290 * Converts a gralloc error code to a mapper error code
291 *
292 * @param grallocError [in] Gralloc error as integer.
293 *
294 * @return Corresponding Mapper error code
295 *
296 * @note There is no full 1:1 correspondence, several gralloc errors may map to Error::UNSUPPORTED.
297 * @note -EINVAL is mapped to Error::BAD_VALUE.
298 */
grallocErrorToMapperError(int grallocError)299 static Error grallocErrorToMapperError(int grallocError)
300 {
301 switch(grallocError)
302 {
303 case GRALLOC1_ERROR_NONE:
304 return Error::NONE;
305 case GRALLOC1_ERROR_BAD_DESCRIPTOR:
306 return Error::BAD_DESCRIPTOR;
307 case GRALLOC1_ERROR_BAD_HANDLE:
308 return Error::BAD_BUFFER;
309 case GRALLOC1_ERROR_BAD_VALUE:
310 case -EINVAL:
311 return Error::BAD_VALUE;
312 case GRALLOC1_ERROR_NO_RESOURCES:
313 return Error::NO_RESOURCES;
314 default:
315 /* Covers NOT_SHARED, UNDEFINED, UNSUPPORTED */
316 return Error::UNSUPPORTED;
317 }
318 }
319
320 /*
321 * Locks the given buffer for the specified CPU usage.
322 *
323 * @param bufferHandle [in] Buffer to lock.
324 * @param cpuUsage [in] Specifies one or more CPU usage flags to request
325 * @param accessRegion [in] Portion of the buffer that the client intends to
326 * access.
327 * @param fenceFd [in] Fence file descriptor
328 * @param outData [out] CPU accessible buffer address
329 *
330 * @return Error::BAD_BUFFER for an invalid buffer
331 * Error::NO_RESOURCES when unable to duplicate fence
332 * Error::BAD_VALUE when locking fails
333 * Error::UNSUPPORTED when locking fails on unsupported image formats
334 * Error::NONE on successful buffer lock
335 */
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const GrallocRect & accessRegion,int fenceFd,void ** outData)336 static Error lockBuffer(buffer_handle_t bufferHandle,
337 uint64_t cpuUsage,
338 const GrallocRect& accessRegion, int fenceFd,
339 void** outData)
340 {
341 /* dup fenceFd as it is going to be owned by gralloc. Note that it is
342 * gralloc's responsibility to close it, even on locking errors.
343 */
344 if (fenceFd >= 0)
345 {
346 fenceFd = dup(fenceFd);
347 if (fenceFd < 0)
348 {
349 MALI_GRALLOC_LOGE("Error encountered while duplicating fence file descriptor");
350 return Error::NO_RESOURCES;
351 }
352 }
353
354 if (private_handle_t::validate(bufferHandle) < 0)
355 {
356 if (fenceFd >= 0)
357 {
358 close(fenceFd);
359 }
360 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
361 return Error::BAD_BUFFER;
362 }
363
364 if (mali_gralloc_reference_validate(bufferHandle) < 0)
365 {
366 if (fenceFd >= 0)
367 {
368 close(fenceFd);
369 }
370 MALI_GRALLOC_LOGE("Buffer: %p is not imported", bufferHandle);
371 return Error::BAD_VALUE;
372 }
373
374 auto private_handle = private_handle_t::dynamicCast(bufferHandle);
375 if (private_handle->cpu_write != 0 && (cpuUsage & static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK)))
376 {
377 if (fenceFd >= 0)
378 {
379 close(fenceFd);
380 }
381 #if 0
382 MALI_GRALLOC_LOGW("Attempt to call lock*() for writing on an already locked buffer (%p)", bufferHandle);
383 #endif
384
385 /* TODO: handle simulatneous locks differently. May be keep a global lock count per buffer? */
386 }
387 else if (fenceFd >= 0)
388 {
389 sync_wait(fenceFd, -1);
390 close(fenceFd);
391 }
392
393 void* data = nullptr;
394 const int gralloc_err =
395 mali_gralloc_lock(bufferHandle, cpuUsage, accessRegion.left, accessRegion.top,
396 accessRegion.right - accessRegion.left,
397 accessRegion.bottom - accessRegion.top, &data);
398 const Error lock_err = grallocErrorToMapperError(gralloc_err);
399
400 if(Error::NONE == lock_err)
401 {
402 *outData = data;
403 }
404 else
405 {
406 MALI_GRALLOC_LOGE("Locking failed with error: %d", gralloc_err);
407 }
408
409 return lock_err;
410 }
411
412 /*
413 * Unlocks a buffer to indicate all CPU accesses to the buffer have completed
414 *
415 * @param bufferHandle [in] Buffer to lock.
416 * @param outFenceFd [out] Fence file descriptor
417 *
418 * @return Error::BAD_BUFFER for an invalid buffer
419 * Error::BAD_VALUE when unlocking failed
420 * Error::NONE on successful buffer unlock
421 */
unlockBuffer(buffer_handle_t bufferHandle,int * outFenceFd)422 static Error unlockBuffer(buffer_handle_t bufferHandle,
423 int* outFenceFd)
424 {
425 if (private_handle_t::validate(bufferHandle) < 0)
426 {
427 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
428 return Error::BAD_BUFFER;
429 }
430
431 const int gralloc_err = mali_gralloc_unlock(bufferHandle);
432 const Error unlock_err = grallocErrorToMapperError(gralloc_err);
433
434 if (Error::NONE == unlock_err)
435 {
436 *outFenceFd = -1;
437 }
438 else
439 {
440 MALI_GRALLOC_LOGE("Unlocking failed with error: %d",
441 gralloc_err);
442 return Error::BAD_BUFFER;
443 }
444
445 return unlock_err;
446 }
447
importBuffer(const native_handle_t * inBuffer,buffer_handle_t * outBuffer)448 Error importBuffer(const native_handle_t *inBuffer, buffer_handle_t *outBuffer)
449 {
450 *outBuffer = const_cast<buffer_handle_t>(native_handle_clone(inBuffer));
451 const Error error = registerBuffer(*outBuffer);
452 if (error != Error::NONE)
453 {
454 return error;
455 }
456
457 if (gRegisteredHandles->add(*outBuffer) == false)
458 {
459 /* The newly cloned handle is already registered. This can only happen
460 * when a handle previously registered was native_handle_delete'd instead
461 * of freeBuffer'd.
462 */
463 MALI_GRALLOC_LOGE("Handle %p has already been imported; potential fd leaking",
464 outBuffer);
465 unregisterBuffer(*outBuffer);
466 return Error::NO_RESOURCES;
467 }
468
469 return Error::NONE;
470 }
471
freeBuffer(buffer_handle_t bufferHandle)472 Error freeBuffer(buffer_handle_t bufferHandle)
473 {
474 native_handle_t *handle = gRegisteredHandles->remove(bufferHandle);
475 if (handle == nullptr)
476 {
477 MALI_GRALLOC_LOGE("Invalid buffer handle %p to freeBuffer", bufferHandle);
478 return Error::BAD_BUFFER;
479 }
480
481 const Error status = unregisterBuffer(handle);
482 if (status != Error::NONE)
483 {
484 return status;
485 }
486
487 native_handle_close(handle);
488 native_handle_delete(handle);
489
490 return Error::NONE;
491 }
492
lock(buffer_handle_t bufferHandle,uint64_t cpuUsage,const GrallocRect & accessRegion,int acquireFence,void ** outData)493 Error lock(buffer_handle_t bufferHandle, uint64_t cpuUsage, const GrallocRect &accessRegion, int acquireFence, void **outData)
494 {
495 *outData = nullptr;
496 if (!bufferHandle || private_handle_t::validate(bufferHandle) < 0)
497 {
498 MALI_GRALLOC_LOGE("Buffer to lock: %p is not valid",
499 bufferHandle);
500 return Error::BAD_BUFFER;
501 }
502
503 const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion,
504 acquireFence, outData);
505 return error;
506 }
507
unlock(buffer_handle_t bufferHandle,int * releaseFence)508 Error unlock(buffer_handle_t bufferHandle, int *releaseFence) {
509 if(bufferHandle == nullptr) return Error::BAD_BUFFER;
510 if(!gRegisteredHandles->isRegistered(bufferHandle)) {
511 MALI_GRALLOC_LOGE("Buffer to unlock: %p has not been registered with Gralloc",
512 bufferHandle);
513 return Error::BAD_BUFFER;
514 }
515
516 const Error error = unlockBuffer(bufferHandle, releaseFence);
517 return error;
518 }
519 #ifdef GRALLOC_MAPPER_4
validateBufferSize(void * buffer,const IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t in_stride)520 Error validateBufferSize(void* buffer,
521 const IMapper::BufferDescriptorInfo& descriptorInfo,
522 uint32_t in_stride)
523 {
524 /* The buffer must have been allocated by Gralloc */
525 buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
526 if (!bufferHandle)
527 {
528 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
529 return Error::BAD_BUFFER;
530 }
531
532 if (private_handle_t::validate(bufferHandle) < 0)
533 {
534 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", bufferHandle);
535 return Error::BAD_BUFFER;
536 }
537
538 buffer_descriptor_t grallocDescriptor;
539 grallocDescriptor.width = descriptorInfo.width;
540 grallocDescriptor.height = descriptorInfo.height;
541 grallocDescriptor.layer_count = descriptorInfo.layerCount;
542 grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
543 grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
544 grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
545 grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
546
547 /* Derive the buffer size for the given descriptor */
548 const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
549 if (result)
550 {
551 MALI_GRALLOC_LOGV("Unable to derive format and size for the given descriptor information. error: %d", result);
552 return Error::BAD_VALUE;
553 }
554
555 /* Validate the buffer parameters against descriptor info */
556 private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;
557
558 /* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
559 for (int i = 0; i < gralloc_buffer->fd_count; i++)
560 {
561 if (gralloc_buffer->alloc_sizes[i] < grallocDescriptor.alloc_sizes[i])
562 {
563 MALI_GRALLOC_LOGW("Buf size mismatch. fd_idx(%d) Buffer size = %" PRIu64 ", Descriptor (derived) size = %" PRIu64,
564 i, gralloc_buffer->alloc_sizes[i], grallocDescriptor.alloc_sizes[i]);
565 return Error::BAD_VALUE;
566 }
567 }
568
569 if (in_stride != 0 && (uint32_t)gralloc_buffer->stride != in_stride)
570 {
571 MALI_GRALLOC_LOGE("Stride mismatch. Expected stride = %d, Buffer stride = %" PRIu64,
572 in_stride, gralloc_buffer->stride);
573 return Error::BAD_VALUE;
574 }
575
576 if (gralloc_buffer->alloc_format != grallocDescriptor.alloc_format)
577 {
578 MALI_GRALLOC_LOGE("Buffer alloc format: (%s, 0x%" PRIx64") does not match descriptor (derived) alloc format: (%s 0x%"
579 PRIx64 ")", format_name(gralloc_buffer->alloc_format), gralloc_buffer->alloc_format,
580 format_name(grallocDescriptor.alloc_format), grallocDescriptor.alloc_format);
581 return Error::BAD_VALUE;
582 }
583
584 const int format_idx = get_format_index(gralloc_buffer->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
585 if (format_idx == -1)
586 {
587 MALI_GRALLOC_LOGE("Invalid format to validate buffer descriptor");
588 return Error::BAD_VALUE;
589 }
590 else
591 {
592 for (int i = 0; i < formats[format_idx].npln; i++)
593 {
594 if (gralloc_buffer->plane_info[i].byte_stride != grallocDescriptor.plane_info[i].byte_stride)
595 {
596 MALI_GRALLOC_LOGE("Buffer byte stride %" PRIu64 " mismatch with desc byte stride %" PRIu64 " in plane %d ",
597 gralloc_buffer->plane_info[i].byte_stride, grallocDescriptor.plane_info[i].byte_stride, i);
598 return Error::BAD_VALUE;
599 }
600
601 if (gralloc_buffer->plane_info[i].alloc_width != grallocDescriptor.plane_info[i].alloc_width)
602 {
603 MALI_GRALLOC_LOGE("Buffer alloc width %" PRIu64 " mismatch with desc alloc width %" PRIu64 " in plane %d ",
604 gralloc_buffer->plane_info[i].alloc_width, grallocDescriptor.plane_info[i].alloc_width, i);
605 return Error::BAD_VALUE;
606 }
607
608 if (gralloc_buffer->plane_info[i].alloc_height != grallocDescriptor.plane_info[i].alloc_height)
609 {
610 MALI_GRALLOC_LOGE("Buffer alloc height %" PRIu64 " mismatch with desc alloc height %" PRIu64 " in plane %d ",
611 gralloc_buffer->plane_info[i].alloc_height, grallocDescriptor.plane_info[i].alloc_height, i);
612 return Error::BAD_VALUE;
613 }
614 }
615 }
616
617 if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
618 {
619 MALI_GRALLOC_LOGE("Width mismatch. Buffer width = %u, Descriptor width = %u",
620 gralloc_buffer->width, grallocDescriptor.width);
621 return Error::BAD_VALUE;
622 }
623
624 if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
625 {
626 MALI_GRALLOC_LOGE("Height mismatch. Buffer height = %u, Descriptor height = %u",
627 gralloc_buffer->height, grallocDescriptor.height);
628 return Error::BAD_VALUE;
629 }
630
631 if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
632 {
633 MALI_GRALLOC_LOGE("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
634 gralloc_buffer->layer_count, grallocDescriptor.layer_count);
635 return Error::BAD_VALUE;
636 }
637
638 return Error::NONE;
639 }
640 #endif
641
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts)642 Error getTransportSize(buffer_handle_t bufferHandle, uint32_t *outNumFds, uint32_t *outNumInts)
643 {
644 *outNumFds = 0;
645 *outNumInts = 0;
646 /* The buffer must have been allocated by Gralloc */
647 if (!bufferHandle)
648 {
649 MALI_GRALLOC_LOGE("Buffer %p is not registered with Gralloc",
650 bufferHandle);
651 return Error::BAD_BUFFER;
652 }
653
654 if (private_handle_t::validate(bufferHandle) < 0)
655 {
656 MALI_GRALLOC_LOGE("Buffer %p is corrupted", bufferHandle);
657 return Error::BAD_BUFFER;
658 }
659 *outNumFds = bufferHandle->numFds;
660 *outNumInts = bufferHandle->numInts;
661 return Error::NONE;
662 }
663
664 #ifdef GRALLOC_MAPPER_4
isSupported(const IMapper::BufferDescriptorInfo & description)665 bool isSupported(const IMapper::BufferDescriptorInfo &description)
666 {
667 buffer_descriptor_t grallocDescriptor;
668 grallocDescriptor.width = description.width;
669 grallocDescriptor.height = description.height;
670 grallocDescriptor.layer_count = description.layerCount;
671 grallocDescriptor.hal_format = static_cast<uint64_t>(description.format);
672 grallocDescriptor.producer_usage = static_cast<uint64_t>(description.usage);
673 grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
674 grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
675
676 /* Check if it is possible to allocate a buffer for the given description */
677 const int result = mali_gralloc_derive_format_and_size(&grallocDescriptor);
678 if (result != 0)
679 {
680 MALI_GRALLOC_LOGV("Allocation for the given description will not succeed. error: %d", result);
681 return false;
682 }
683 else
684 {
685 return true;
686 }
687 }
688
689 #endif
flushLockedBuffer(buffer_handle_t handle)690 Error flushLockedBuffer(buffer_handle_t handle)
691 {
692 if (private_handle_t::validate(handle) < 0)
693 {
694 MALI_GRALLOC_LOGE("Handle: %p is corrupted", handle);
695 return Error::BAD_BUFFER;
696 }
697
698 auto private_handle = static_cast<const private_handle_t *>(handle);
699 if (!private_handle->cpu_write && !private_handle->cpu_read)
700 {
701 MALI_GRALLOC_LOGE("Attempt to call flushLockedBuffer() on an unlocked buffer (%p)", handle);
702 return Error::BAD_BUFFER;
703 }
704
705 mali_gralloc_ion_sync_end(private_handle, false, true);
706 return Error::NONE;
707 }
708
rereadLockedBuffer(buffer_handle_t handle)709 Error rereadLockedBuffer(buffer_handle_t handle)
710 {
711 if (private_handle_t::validate(handle) < 0)
712 {
713 MALI_GRALLOC_LOGE("Buffer: %p is corrupted", handle);
714 return Error::BAD_BUFFER;
715 }
716
717 auto private_handle = static_cast<const private_handle_t *>(handle);
718 if (!private_handle->cpu_write && !private_handle->cpu_read)
719 {
720 MALI_GRALLOC_LOGE("Attempt to call rereadLockedBuffer() on an unlocked buffer (%p)", handle);
721 return Error::BAD_BUFFER;
722 }
723
724 mali_gralloc_ion_sync_start(private_handle, true, false);
725 return Error::NONE;
726 }
727
get(buffer_handle_t buffer,const MetadataType & metadataType,std::vector<uint8_t> & vec)728 Error get(buffer_handle_t buffer, const MetadataType &metadataType, std::vector<uint8_t> &vec)
729 {
730 /* The buffer must have been allocated by Gralloc */
731 const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
732 if (handle == nullptr)
733 {
734 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
735 return Error::BAD_BUFFER;
736 }
737
738 if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
739 {
740 MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
741 return Error::BAD_VALUE;
742 }
743
744 return get_metadata(handle, metadataType, vec);
745 }
746
set(buffer_handle_t buffer,const MetadataType & metadataType,const hidl_vec<uint8_t> & metadata)747 Error set(buffer_handle_t buffer, const MetadataType &metadataType, const hidl_vec<uint8_t> &metadata)
748 {
749 /* The buffer must have been allocated by Gralloc */
750 const private_handle_t *handle = static_cast<const private_handle_t *>(buffer);
751 if (handle == nullptr)
752 {
753 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
754 return Error::BAD_BUFFER;
755 }
756
757 if (mali_gralloc_reference_validate((buffer_handle_t)handle) < 0)
758 {
759 MALI_GRALLOC_LOGE("Buffer: %p is not imported", handle);
760 return Error::BAD_VALUE;
761 }
762
763 return set_metadata(handle, metadataType, metadata);
764 }
765
describeStandard(StandardMetadataType meta,bool isGettable,bool isSettable)766 MetadataTypeDescription describeStandard(StandardMetadataType meta, bool isGettable, bool isSettable)
767 {
768 return MetadataTypeDescription(MetadataType(GRALLOC4_STANDARD_METADATA_TYPE,
769 static_cast<uint64_t>(meta)), "", isGettable, isSettable);
770 }
771
listSupportedMetadataTypes()772 std::vector<MetadataTypeDescription> listSupportedMetadataTypes()
773 {
774 /* Returns a vector of {metadata type, description, isGettable, isSettable}
775 * Only non-standardMetadataTypes require a description.
776 */
777 std::array<MetadataTypeDescription, 23> descriptions = {
778 describeStandard(StandardMetadataType::BUFFER_ID, true, false ),
779 describeStandard(StandardMetadataType::NAME, true, false ),
780 describeStandard(StandardMetadataType::WIDTH, true, false ),
781 describeStandard(StandardMetadataType::STRIDE, true, false ),
782 describeStandard(StandardMetadataType::HEIGHT, true, false ),
783 describeStandard(StandardMetadataType::LAYER_COUNT, true, false ),
784 describeStandard(StandardMetadataType::PIXEL_FORMAT_REQUESTED, true, false ),
785 describeStandard(StandardMetadataType::PIXEL_FORMAT_FOURCC, true, false ),
786 describeStandard(StandardMetadataType::PIXEL_FORMAT_MODIFIER, true, false ),
787 describeStandard(StandardMetadataType::USAGE, true, false ),
788 describeStandard(StandardMetadataType::ALLOCATION_SIZE, true, false ),
789 describeStandard(StandardMetadataType::PROTECTED_CONTENT, true, false ),
790 describeStandard(StandardMetadataType::COMPRESSION, true, false ),
791 describeStandard(StandardMetadataType::INTERLACED, true, false ),
792 describeStandard(StandardMetadataType::CHROMA_SITING, true, false ),
793 describeStandard(StandardMetadataType::PLANE_LAYOUTS, true, false ),
794 describeStandard(StandardMetadataType::DATASPACE, true, true ),
795 describeStandard(StandardMetadataType::BLEND_MODE, true, true ),
796 describeStandard(StandardMetadataType::SMPTE2086, true, true ),
797 describeStandard(StandardMetadataType::CTA861_3, true, true ),
798 describeStandard(StandardMetadataType::SMPTE2094_40, true, true ),
799 describeStandard(StandardMetadataType::CROP, true, true ),
800 /* Arm vendor metadata */
801 { ArmMetadataType_PLANE_FDS,
802 "Vector of file descriptors of each plane", true, false},
803 };
804 return std::vector<MetadataTypeDescription>(descriptions.begin(), descriptions.end());
805 }
806
807
dumpBufferHelper(const private_handle_t * handle)808 static BufferDump dumpBufferHelper(const private_handle_t *handle)
809 {
810 static std::array<MetadataType, 21> standardMetadataTypes = {
811 MetadataType(StandardMetadataType::BUFFER_ID),
812 MetadataType(StandardMetadataType::NAME),
813 MetadataType(StandardMetadataType::WIDTH),
814 MetadataType(StandardMetadataType::HEIGHT),
815 MetadataType(StandardMetadataType::LAYER_COUNT),
816 MetadataType(StandardMetadataType::PIXEL_FORMAT_REQUESTED),
817 MetadataType(StandardMetadataType::PIXEL_FORMAT_FOURCC),
818 MetadataType(StandardMetadataType::PIXEL_FORMAT_MODIFIER),
819 MetadataType(StandardMetadataType::USAGE),
820 MetadataType(StandardMetadataType::ALLOCATION_SIZE),
821 MetadataType(StandardMetadataType::PROTECTED_CONTENT),
822 MetadataType(StandardMetadataType::COMPRESSION),
823 MetadataType(StandardMetadataType::INTERLACED),
824 MetadataType(StandardMetadataType::CHROMA_SITING),
825 MetadataType(StandardMetadataType::PLANE_LAYOUTS),
826 MetadataType(StandardMetadataType::DATASPACE),
827 MetadataType(StandardMetadataType::BLEND_MODE),
828 MetadataType(StandardMetadataType::SMPTE2086),
829 MetadataType(StandardMetadataType::CTA861_3),
830 MetadataType(StandardMetadataType::SMPTE2094_40),
831 MetadataType(StandardMetadataType::CROP),
832 };
833
834 std::vector<MetadataDump> metadataDumps;
835 for (const auto& metadataType: standardMetadataTypes)
836 {
837 std::vector<uint8_t> metadata;
838 #ifdef GRALLOC_MAPPER_4
839 Error error = get_metadata(handle, metadataType, metadata);
840 #else
841 Error error;
842 auto tmp_err =
843 ::arm::mapper::common::getStandardMetadata(handle,
844 static_cast<
845 StandardMetadataType>(
846 metadataType.value),
847 metadata.data(), metadata.size());
848 if (tmp_err > 0) {
849 metadata.resize(tmp_err);
850 ::arm::mapper::common::getStandardMetadata(handle,
851 static_cast<StandardMetadataType>(
852 metadataType.value),
853 metadata.data(), metadata.size());
854 }
855 error = static_cast<Error>(-1 * tmp_err);
856 #endif
857 if (error == Error::NONE)
858 {
859 metadataDumps.push_back(MetadataDump(MetadataType(metadataType), metadata));
860 }
861 else
862 {
863 return BufferDump();
864 }
865 }
866 return BufferDump(metadataDumps);
867 }
868
dumpBuffer(buffer_handle_t buffer,BufferDump & bufferDump)869 Error dumpBuffer(buffer_handle_t buffer, BufferDump &bufferDump)
870 {
871 auto handle = static_cast<const private_handle_t *>(buffer);
872 if (handle == nullptr)
873 {
874 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
875 return Error::BAD_BUFFER;
876 }
877
878 bufferDump = dumpBufferHelper(handle);
879 return Error::NONE;
880 }
881
dumpBuffers()882 std::vector<BufferDump> dumpBuffers()
883 {
884 std::vector<BufferDump> bufferDumps;
885 gRegisteredHandles->for_each([&bufferDumps](buffer_handle_t buffer) {
886 BufferDump bufferDump;
887 auto err = dumpBuffer(buffer, bufferDump);
888 bufferDumps.push_back(bufferDump);
889 });
890 return bufferDumps;
891 }
892
getReservedRegion(buffer_handle_t buffer,void ** outReservedRegion,uint64_t & outReservedSize)893 Error getReservedRegion(buffer_handle_t buffer, void **outReservedRegion, uint64_t &outReservedSize)
894 {
895 auto handle = static_cast<const private_handle_t *>(buffer);
896 if (handle == nullptr)
897 {
898 MALI_GRALLOC_LOGE("Buffer: %p has not been registered with Gralloc", buffer);
899 return Error::BAD_BUFFER;
900 }
901 else if (handle->reserved_region_size == 0)
902 {
903 MALI_GRALLOC_LOGE("Buffer: %p has no reserved region", buffer);
904 return Error::BAD_BUFFER;
905 }
906
907 auto metadata_addr_oe = mali_gralloc_reference_get_metadata_addr(handle);
908 if (!metadata_addr_oe.has_value()) {
909 return Error::BAD_BUFFER;
910 }
911
912 *outReservedRegion = static_cast<std::byte *>(metadata_addr_oe.value())
913 + mapper::common::shared_metadata_size();
914 outReservedSize = handle->reserved_region_size;
915 return Error::NONE;
916 }
917
918 } // namespace common
919 } // namespace mapper
920 } // namespace arm
921