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