1 /*
2  * Copyright (C) 2018-2019 ARM Limited. All rights reserved.
3  *
4  * Copyright 2016 The Android Open Source Project
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <inttypes.h>
19 #include <log/log.h>
20 #include <sync/sync.h>
21 #include <mutex>
22 #include <unordered_set>
23 #include <system/window.h>
24 
25 #include "GrallocMapper.h"
26 #include "GrallocBufferDescriptor.h"
27 #include "mali_gralloc_bufferallocation.h"
28 #include "mali_gralloc_bufferdescriptor.h"
29 #include "mali_gralloc_bufferaccess.h"
30 #include "mali_gralloc_reference.h"
31 #include "mali_gralloc_ion.h"
32 #include "mali_gralloc_buffer.h"
33 
34 namespace android {
35 namespace hardware {
36 namespace graphics {
37 namespace mapper {
38 namespace HIDL_IMAPPER_NAMESPACE {
39 namespace implementation {
40 
41 /* Default definitions for IMapper 2.x interface */
42 using V2_0::Error;
43 using V2_0::BufferDescriptor;
44 
45 namespace {
46 
47 /* An unordered set to internally store / retrieve imported buffer handles */
48 class RegisteredHandlePool
49 {
50 public:
51 	/* Stores the buffer handle in the internal list */
add(buffer_handle_t bufferHandle)52 	bool add(buffer_handle_t bufferHandle)
53 	{
54 		std::lock_guard<std::mutex> lock(mutex);
55 		return bufPool.insert(bufferHandle).second;
56 	}
57 
58 	/* Retrieves and removes the buffer handle from internal list */
remove(void * buffer)59 	native_handle_t* remove(void* buffer)
60 	{
61 		auto bufferHandle = static_cast<native_handle_t*>(buffer);
62 
63 		std::lock_guard<std::mutex> lock(mutex);
64 		return bufPool.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
65 	}
66 
67 	/* Retrieves the buffer handle from internal list */
get(const void * buffer)68 	buffer_handle_t get(const void* buffer)
69 	{
70 		auto bufferHandle = static_cast<buffer_handle_t>(buffer);
71 
72 		std::lock_guard<std::mutex> lock(mutex);
73 		return bufPool.count(bufferHandle) == 1 ? bufferHandle : nullptr;
74 	}
75 
76 private:
77 	std::mutex mutex;
78 	std::unordered_set<buffer_handle_t> bufPool;
79 };
80 
81 /* GraphicBufferMapper is expected to be valid (and leaked) during process
82  * termination. IMapper, and in turn, gRegisteredHandles must be valid as
83  * well. Create the registered handle pool on the heap, and let
84  * it leak for simplicity.
85  *
86  * However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
87  * of static/global object in gralloc0/gralloc1 that may have been destructed
88  * is potentially broken.
89  */
90 RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;
91 
92 }  /* anonymous namespace */
93 
94 /**
95  *  IMapper constructor. All the state information required for the Gralloc
96  *  private module is populated in its default constructor. Gralloc 2.0 specific
97  *  state information can be populated here.
98  *
99  * @return None
100  */
GrallocMapper()101 GrallocMapper::GrallocMapper()
102 {
103 }
104 
105 /*
106  *  IMapper destructor. All the resources aquired for Gralloc private module
107  *  (in the IMapper context) are released
108  *
109  * @return None
110  */
~GrallocMapper()111 GrallocMapper::~GrallocMapper()
112 {
113 	mali_gralloc_ion_close();
114 }
115 
116 /*
117  * Validates incoming IMapper descriptor attributes
118  *
119  * @param descriptor_attr [in]  Specifies the attributes of the descriptor.
120  *
121  * @return false, for invalid buffer attributes
122  *         true, otherwise
123  * Note:   Latest IMapper version encapsulates all previous versions, hence all
124  *         incoming descriptor information is mapped to the latest IMapper for validation
125  */
validateDescriptorInfo(void * descriptor_attr) const126 bool GrallocMapper::validateDescriptorInfo(void *descriptor_attr) const
127 {
128 	BufferDescriptorInfo * const descriptorInfo = (BufferDescriptorInfo *)descriptor_attr;
129 
130 	using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::BufferUsage;
131 	using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::PixelFormat;
132 
133 	const uint64_t validUsageBits =
134 #if HIDL_MAPPER_VERSION_SCALED >= 210
135 		BufferUsage::GPU_CUBE_MAP |
136 		BufferUsage::GPU_MIPMAP_COMPLETE |
137 #endif
138 		BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
139 		BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
140 		BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
141 		BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT |
142 		BufferUsage::PROTECTED |
143 		BufferUsage::COMPOSER_CURSOR |
144 		BufferUsage::VIDEO_ENCODER |
145 		BufferUsage::RENDERSCRIPT |
146 		BufferUsage::VIDEO_DECODER |
147 		BufferUsage::SENSOR_DIRECT_DATA |
148 		BufferUsage::GPU_DATA_BUFFER |
149 		BufferUsage::VENDOR_MASK;
150 
151 	if (!descriptorInfo->width || !descriptorInfo->height ||
152 	    !descriptorInfo->layerCount)
153 	{
154 		AERR("Invalid buffer descriptor (2.x mapper) attributes, width = %d height = %d  layerCount = %d ",
155 		      descriptorInfo->width, descriptorInfo->height, descriptorInfo->layerCount);
156 		return false;
157 	}
158 
159 	if (descriptorInfo->format == static_cast<PixelFormat>(0))
160 	{
161 		return false;
162 	}
163 
164 	if (descriptorInfo->usage & ~validUsageBits)
165 	{
166 		/* It is possible that application uses private usage bits. */
167 		ALOGW("Buffer descriptor with invalid usage bits 0x%" PRIx64,
168 		       descriptorInfo->usage & ~validUsageBits);
169 	}
170 
171 	return true;
172 }
173 
174 /*
175  * Creates a buffer descriptor from incoming descriptor attributes
176  *
177  * @param descriptorInfo [in]  Specifies the (2.0 IMapper) attributes of
178  *                             the descriptor.
179  * @param hidl_cb        [in]  HIDL callback function generating -
180  *                             error:      NONE upon success. Otherwise,
181  *                                         BAD_VALUE when any of the specified attributes are invalid
182  *                             descriptor: Newly created buffer descriptor.
183  *
184  * @return Void
185  */
createDescriptor(const V2_0::IMapper::BufferDescriptorInfo & descriptorInfo,createDescriptor_cb hidl_cb)186 Return<void> GrallocMapper::createDescriptor(
187              const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo,
188              createDescriptor_cb hidl_cb)
189 {
190 	if (validateDescriptorInfo((void *)&descriptorInfo))
191 	{
192 		hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
193 	}
194 	else
195 	{
196 		AERR("Invalid attributes to create descriptor for Mapper 2.0");
197 		hidl_cb(Error::BAD_VALUE, BufferDescriptor());
198 	}
199 
200 	return Void();
201 }
202 
203 /*
204  * Imports a raw buffer handle to create an imported buffer handle for use with
205  * the rest of the mapper or with other in-process libraries.
206  *
207  * @param rawHandle [in] Raw buffer handle to import.
208  * @param hidl_cb   [in] HIDL Callback function to export output information
209  * @param hidl_cb   [in]  HIDL callback function generating -
210  *                  error  : NONE upon success. Otherwise,
211  *                           BAD_BUFFER for an invalid buffer
212  *                           NO_RESOURCES when the raw handle cannot be imported
213  *                           BAD_VALUE when any of the specified attributes are invalid
214  *                  buffer : Imported buffer handle
215  *
216  * @return Void
217  */
importBuffer(const hidl_handle & rawHandle,importBuffer_cb hidl_cb)218 Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
219                                          importBuffer_cb hidl_cb)
220 {
221 	if (!rawHandle.getNativeHandle())
222 	{
223 		AERR("Invalid buffer handle to import");
224 		hidl_cb(Error::BAD_BUFFER, nullptr);
225 		return Void();
226 	}
227 
228 	native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
229 	if (!bufferHandle)
230 	{
231 		AERR("Failed to clone buffer handle");
232 		hidl_cb(Error::NO_RESOURCES, nullptr);
233 		return Void();
234 	}
235 
236 	const Error error = registerBuffer(bufferHandle);
237 	if (error != Error::NONE)
238 	{
239 		native_handle_close(bufferHandle);
240 		native_handle_delete(bufferHandle);
241 
242 		hidl_cb(error, nullptr);
243 		return Void();
244 	}
245 
246 	if (gRegisteredHandles->add(bufferHandle) == false)
247 	{
248 		/* The newly cloned handle is already registered. This can only happen
249 		 * when a handle previously registered was native_handle_delete'd instead
250 		 * of freeBuffer'd.
251 		 */
252 		AERR("Handle %p has already been imported; potential fd leaking",
253 		       bufferHandle);
254 		unregisterBuffer(bufferHandle);
255 		native_handle_close(bufferHandle);
256 		native_handle_delete(bufferHandle);
257 
258 		hidl_cb(Error::NO_RESOURCES, nullptr);
259 		return Void();
260 	}
261 
262 	hidl_cb(Error::NONE, bufferHandle);
263 	return Void();
264 }
265 
266 /*
267  * Frees a buffer handle and releases all the resources associated with it
268  *
269  * @param buffer [in] Imported buffer to free
270  *
271  * @return Error::BAD_BUFFER for an invalid buffer / when failed to free the buffer
272  *         Error::NONE on successful free
273  */
freeBuffer(void * buffer)274 Return<Error> GrallocMapper::freeBuffer(void* buffer)
275 {
276 	native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer);
277 	if (!bufferHandle)
278 	{
279 		AERR("Invalid buffer handle %p to freeBuffer", buffer);
280 		return Error::BAD_BUFFER;
281 	}
282 
283 	const Error status = unregisterBuffer(bufferHandle);
284 	if (status != Error::NONE)
285 	{
286 		return status;
287 	}
288 
289 	native_handle_close(bufferHandle);
290 	native_handle_delete(bufferHandle);
291 
292 	return Error::NONE;
293 }
294 
295 /*
296  * Retrieves the file descriptor referring to a sync fence object
297  *
298  * @param fenceHandle [in]  HIDL fence handle
299  * @param outFenceFd  [out] Fence file descriptor. '-1' indicates no fence
300  *
301  * @return false, for an invalid HIDL fence handle
302  *         true, otherwise
303  */
getFenceFd(const hidl_handle & fenceHandle,int * outFenceFd) const304 bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
305                                int* outFenceFd) const
306 {
307 	auto const handle = fenceHandle.getNativeHandle();
308 	if (handle && handle->numFds > 1)
309 	{
310 		AERR("Invalid fence handle with %d fds", handle->numFds);
311 		return false;
312 	}
313 
314 	*outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
315 	return true;
316 }
317 
318 /*
319  * Populates the HIDL fence handle for the given fence object
320  *
321  * @param fenceFd       [in] Fence file descriptor
322  * @param handleStorage [in] HIDL handle storage for fence
323  *
324  * @return HIDL fence handle
325  */
getFenceHandle(int fenceFd,char * handleStorage) const326 hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) const
327 {
328 	native_handle_t* handle = nullptr;
329 	if (fenceFd >= 0)
330 	{
331 		handle = native_handle_init(handleStorage, 1, 0);
332 		handle->data[0] = fenceFd;
333 	}
334 
335 	return hidl_handle(handle);
336 }
337 
338 /*
339  * Locks the given buffer for the specified CPU usage.
340  *
341  * @param buffer       [in] Buffer to lock
342  * @param cpuUsage     [in] Specifies one or more CPU usage flags to request
343  * @param accessRegion [in] Portion of the buffer that the client intends to access
344  * @param acquireFence [in] Handle for aquire fence object
345  * @param hidl_cb      [in] HIDL callback function generating -
346  *                          error: NONE upon success. Otherwise,
347  *                                 BAD_BUFFER for an invalid buffer
348  *                                 BAD_VALUE for an invalid input parameters
349  *                          data:  CPU-accessible pointer to the buffer data
350  *
351  * @return Void
352  */
lock(void * buffer,uint64_t cpuUsage,const IMapper::Rect & accessRegion,const hidl_handle & acquireFence,lock_cb hidl_cb)353 Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
354                                  const IMapper::Rect& accessRegion,
355                                  const hidl_handle& acquireFence,
356                                  lock_cb hidl_cb)
357 {
358 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
359 	if (!bufferHandle)
360 	{
361 		AERR("Buffer to lock: %p has not been registered with Gralloc", buffer);
362 		hidl_cb(Error::BAD_BUFFER, nullptr);
363 		return Void();
364 	}
365 
366 	int fenceFd;
367 	if (!getFenceFd(acquireFence, &fenceFd))
368 	{
369 		hidl_cb(Error::BAD_VALUE, nullptr);
370 		return Void();
371 	}
372 
373 	void* data = nullptr;
374 	const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
375 	hidl_cb(error, data);
376 	return Void();
377 }
378 
379 /*
380  * Locks the given buffer for the specified CPU usage and exports cpu accessible
381  * data in YCbCr structure.
382  *
383  * @param buffer       [in] Buffer to lock.
384  * @param cpuUsage     [in] Specifies one or more CPU usage flags to request
385  * @param accessRegion [in] Portion of the buffer that the client intends to access.
386  * @param acquireFence [in] Handle for aquire fence object
387  * @param hidl_cb      [in] HIDL callback function generating -
388  *                          error:  NONE upon success. Otherwise,
389  *                                  BAD_BUFFER for an invalid buffer
390  *                                  BAD_VALUE for an invalid input parameters
391  *                          layout: Data layout of the buffer
392  *
393  * @return Void
394  */
lockYCbCr(void * buffer,uint64_t cpuUsage,const IMapper::Rect & accessRegion,const hidl_handle & acquireFence,lockYCbCr_cb hidl_cb)395 Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
396                                       const IMapper::Rect& accessRegion,
397                                       const hidl_handle& acquireFence,
398                                       lockYCbCr_cb hidl_cb)
399 {
400 	YCbCrLayout layout = {};
401 
402 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
403 	if (!bufferHandle)
404 	{
405 		AERR("Buffer to lock(YCbCr): %p has not been registered with Gralloc", buffer);
406 		hidl_cb(Error::BAD_BUFFER, layout);
407 		return Void();
408 	}
409 
410 	int fenceFd;
411 	if (!getFenceFd(acquireFence, &fenceFd))
412 	{
413 		hidl_cb(Error::BAD_VALUE, layout);
414 		return Void();
415 	}
416 
417 	const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
418 	hidl_cb(error, layout);
419 	return Void();
420 }
421 
422 /*
423  * Unlocks a buffer to indicate all CPU accesses to the buffer have completed
424  *
425  * @param buffer       [in] Buffer to lock.
426  * @param hidl_cb      [in] HIDL callback function generating -
427  *                          error:        NONE upon success. Otherwise,
428  *                                        BAD_BUFFER for an invalid buffer
429  *                          releaseFence: Referrs to a sync fence object
430  *
431  * @return Void
432  */
unlock(void * buffer,unlock_cb hidl_cb)433 Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb)
434 {
435 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
436 	if (!bufferHandle)
437 	{
438 		AERR("Buffer to unlock: %p has not been registered with Gralloc", buffer);
439 		hidl_cb(Error::BAD_BUFFER, nullptr);
440 		return Void();
441 	}
442 
443 	int fenceFd;
444 	const Error error = unlockBuffer(bufferHandle, &fenceFd);
445 	if (error == Error::NONE)
446 	{
447 		NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
448 		hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
449 
450 		if (fenceFd >= 0)
451 		{
452 			close(fenceFd);
453 		}
454 	}
455 	else
456 	{
457 		hidl_cb(error, nullptr);
458 	}
459 
460 	return Void();
461 }
462 
463 /*
464  * Translates the register buffer API into existing gralloc implementation
465  *
466  * @param bufferHandle [in] Private handle for the buffer to be imported
467  *
468  * @return Error::BAD_BUFFER for an invalid buffer
469  *         Error::NO_RESOURCES when unable to import the given buffer
470  *         Error::NONE on successful import
471  */
registerBuffer(buffer_handle_t bufferHandle) const472 Error GrallocMapper::registerBuffer(buffer_handle_t bufferHandle) const
473 {
474 	if (private_handle_t::validate(bufferHandle) < 0)
475 	{
476 		AERR("Buffer: %p is corrupted", bufferHandle);
477 		return Error::BAD_BUFFER;
478 	}
479 
480 	if (mali_gralloc_reference_retain(&privateModule, bufferHandle) < 0)
481 	{
482 		return Error::NO_RESOURCES;
483 	}
484 
485 	return Error::NONE;
486 }
487 
488 /*
489  * Translates the unregister buffer API into existing gralloc implementation
490  *
491  * @param bufferHandle [in] Private handle for the buffer to be released
492  *
493  * @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released
494  *         Error::NONE on successful release of the buffer
495  */
unregisterBuffer(buffer_handle_t bufferHandle) const496 Error GrallocMapper::unregisterBuffer(buffer_handle_t bufferHandle) const
497 {
498 	if (private_handle_t::validate(bufferHandle) < 0)
499 	{
500 		AERR("Buffer: %p is corrupted", bufferHandle);
501 		return Error::BAD_BUFFER;
502 	}
503 
504 	const int status = mali_gralloc_reference_release(&privateModule, bufferHandle, true);
505 	if (status != 0)
506 	{
507 		AERR("Unable to release buffer:%p", bufferHandle);
508 		return Error::BAD_BUFFER;
509 	}
510 
511 	return Error::NONE;
512 }
513 
514 /*
515  * Locks the given buffer for the specified CPU usage.
516  *
517  * @param bufferHandle [in]  Buffer to lock.
518  * @param cpuUsage     [in]  Specifies one or more CPU usage flags to request
519  * @param accessRegion [in]  Portion of the buffer that the client intends to access.
520  * @param fenceFd      [in]  Fence file descriptor
521  * @param outData      [out] CPU accessible buffer address
522  *
523  * @return Error::BAD_BUFFER for an invalid buffer
524  *         Error::NO_RESOURCES when unable to duplicate fence
525  *         Error::BAD_VALUE when locking fails
526  *         Error::NONE on successful buffer lock
527  */
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int fenceFd,void ** outData) const528 Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle,
529                                 uint64_t cpuUsage,
530                                 const IMapper::Rect& accessRegion, int fenceFd,
531                                 void** outData) const
532 {
533 	/* dup fenceFd as it is going to be owned by gralloc. Note that it is
534 	 * gralloc's responsibility to close it, even on locking errors.
535 	 */
536 	if (fenceFd >= 0)
537 	{
538 		fenceFd = dup(fenceFd);
539 		if (fenceFd < 0)
540 		{
541 			AERR("Error encountered while duplicating fence file descriptor");
542 			return Error::NO_RESOURCES;
543 		}
544 	}
545 
546 	if (private_handle_t::validate(bufferHandle) < 0)
547 	{
548 		AERR("Buffer: %p is corrupted", bufferHandle);
549 		return Error::BAD_BUFFER;
550 	}
551 
552 	void* data = nullptr;
553 	if (mali_gralloc_lock_async(&privateModule, bufferHandle, cpuUsage,
554 	                            accessRegion.left, accessRegion.top,
555 	                            accessRegion.width, accessRegion.height,
556 	                           &data, fenceFd) < 0)
557 	{
558 		return Error::BAD_VALUE;
559 	}
560 
561 	*outData = data;
562 	return Error::NONE;
563 }
564 
565 /*
566  * Locks the given buffer for the specified CPU usage and exports cpu accessible
567  * data in YCbCr structure.
568  *
569  * @param bufferHandle [in]  Buffer to lock.
570  * @param cpuUsage     [in]  Specifies one or more CPU usage flags to request
571  * @param accessRegion [in]  Portion of the buffer that the client intends to access.
572  * @param fenceFd      [in]  Fence file descriptor
573  * @param outLayout    [out] Describes CPU accessible information in YCbCr format
574  *
575  * @return Error::BAD_BUFFER for an invalid buffer
576  *         Error::NO_RESOURCES when unable to duplicate fence
577  *         Error::BAD_VALUE when locking fails
578  *         Error::NONE on successful buffer lock
579  */
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int fenceFd,YCbCrLayout * outLayout) const580 Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle,
581                                  uint64_t cpuUsage,
582                                  const IMapper::Rect& accessRegion, int fenceFd,
583                                  YCbCrLayout* outLayout) const
584 {
585 	int result;
586 	android_ycbcr ycbcr = {};
587 
588 	if (private_handle_t::validate(bufferHandle) < 0)
589 	{
590 		AERR("Buffer: %p is corrupted", bufferHandle);
591 		return Error::BAD_BUFFER;
592 	}
593 
594 	if (fenceFd >= 0)
595 	{
596 		fenceFd = dup(fenceFd);
597 		if (fenceFd < 0)
598 		{
599 			AERR("Error encountered while duplicating fence file descriptor");
600 			return Error::NO_RESOURCES;
601 		}
602 	}
603 
604 	result = mali_gralloc_lock_ycbcr_async(&privateModule, bufferHandle, cpuUsage,
605 	                                       accessRegion.left, accessRegion.top,
606 	                                       accessRegion.width, accessRegion.height,
607 	                                       &ycbcr, fenceFd);
608 	if (result)
609 	{
610 		AERR("Locking(YCbCr) failed with error: %d", result);
611 		return Error::BAD_VALUE;
612 	}
613 
614 	outLayout->y = ycbcr.y;
615 	outLayout->cb = ycbcr.cb;
616 	outLayout->cr = ycbcr.cr;
617 	outLayout->yStride = ycbcr.ystride;
618 	outLayout->cStride = ycbcr.cstride;
619 	outLayout->chromaStep = ycbcr.chroma_step;
620 
621 	return Error::NONE;
622 }
623 
624 /*
625  * Unlocks a buffer to indicate all CPU accesses to the buffer have completed
626  *
627  * @param bufferHandle [in]  Buffer to lock.
628  * @param outFenceFd   [out] Fence file descriptor
629  *
630  * @return Error::BAD_BUFFER for an invalid buffer
631  *         Error::BAD_VALUE when unlocking failed
632  *         Error::NONE on successful buffer unlock
633  */
unlockBuffer(buffer_handle_t bufferHandle,int * outFenceFd) const634 Error GrallocMapper::unlockBuffer(buffer_handle_t bufferHandle,
635                                   int* outFenceFd) const
636 {
637 	if (private_handle_t::validate(bufferHandle) < 0)
638 	{
639 		AERR("Buffer: %p is corrupted", bufferHandle);
640 		return Error::BAD_BUFFER;
641 	}
642 
643 	int fenceFd = -1;
644 	const int result = mali_gralloc_unlock_async(&privateModule, bufferHandle, &fenceFd);
645 	if (result)
646 	{
647 		AERR("Unlocking failed with error: %d", result);
648 		return Error::BAD_VALUE;
649 	}
650 
651 	*outFenceFd = fenceFd;
652 
653 	return Error::NONE;
654 }
655 
656 #if HIDL_MAPPER_VERSION_SCALED >= 210
657 
658 /*
659  * Validates the buffer against specified descriptor attributes
660  *
661  * @param buffer          [in] Buffer which needs to be validated.
662  * @param descriptorInfo  [in] Required attributes of the buffer
663  * @param in_stride       [in] Buffer stride returned by IAllocator::allocate
664  *
665  * @return Error::NONE upon success. Otherwise,
666  *         Error::BAD_BUFFER upon bad buffer input
667  *         Error::BAD_VALUE when any of the specified attributes are invalid
668  */
validateBufferSize(void * buffer,const V2_1::IMapper::BufferDescriptorInfo & descriptorInfo,uint32_t in_stride)669 Return<Error> GrallocMapper::validateBufferSize(void* buffer,
670                                                 const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo,
671                                                 uint32_t in_stride)
672 {
673 	/* The buffer must have been allocated by Gralloc */
674 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
675 	if (!bufferHandle)
676 	{
677 		AERR("Buffer: %p has not been registered with Gralloc", buffer);
678 		return Error::BAD_BUFFER;
679 	}
680 
681 	if (private_handle_t::validate(bufferHandle) < 0)
682 	{
683 		AERR("Buffer: %p is corrupted", bufferHandle);
684 		return Error::BAD_BUFFER;
685 	}
686 
687 	/* All Gralloc allocated buffers must be conform to local descriptor validation */
688 	if (!validateDescriptorInfo((void *)&descriptorInfo))
689 	{
690 		AERR("Invalid descriptor attributes for validating buffer size");
691 		return Error::BAD_VALUE;
692 	}
693 
694 	buffer_descriptor_t grallocDescriptor;
695 	grallocDescriptor.width = descriptorInfo.width;
696 	grallocDescriptor.height = descriptorInfo.height;
697 	grallocDescriptor.layer_count = descriptorInfo.layerCount;
698 	grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
699 	grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
700 	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
701 	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
702 
703 	/* Derive the buffer size for the given descriptor */
704 	const int result = mali_gralloc_derive_format_and_size(&privateModule,
705 	                                                       &grallocDescriptor);
706 	if (result)
707 	{
708 		AERR("Unable to derive format and size for the given descriptor information. error: %d", result);
709 		return Error::BAD_VALUE;
710 	}
711 
712 	/* Validate the buffer parameters against descriptor info */
713 	private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;
714 
715 	/* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
716 	if ((size_t)gralloc_buffer->size < grallocDescriptor.size)
717 	{
718 		ALOGW("Buf size mismatch. Buffer size = %u, Descriptor (derived) size = %zu",
719 		       gralloc_buffer->size, grallocDescriptor.size);
720 		return Error::BAD_VALUE;
721 	}
722 
723 	if ((uint32_t)gralloc_buffer->stride != in_stride)
724 	{
725 		AERR("Stride mismatch. Expected stride = %d, Buffer stride = %d",
726 		                       in_stride, gralloc_buffer->stride);
727 		return Error::BAD_VALUE;
728 	}
729 
730 	if (gralloc_buffer->internal_format != grallocDescriptor.internal_format)
731 	{
732 		AERR("Buffer format :0x%" PRIx64" does not match descriptor (derived) format :0x%"
733 		      PRIx64, gralloc_buffer->internal_format, grallocDescriptor.internal_format);
734 		return Error::BAD_VALUE;
735 	}
736 
737 	if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
738 	{
739 		AERR("Width mismatch. Buffer width = %u, Descriptor width = %u",
740 		      gralloc_buffer->width, grallocDescriptor.width);
741 		return Error::BAD_VALUE;
742 	}
743 
744 	if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
745 	{
746 		AERR("Height mismatch. Buffer height = %u, Descriptor height = %u",
747 		      gralloc_buffer->height, grallocDescriptor.height);
748 		return Error::BAD_VALUE;
749 	}
750 
751 	if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
752 	{
753 		AERR("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
754 		      gralloc_buffer->layer_count, grallocDescriptor.layer_count);
755 		return Error::BAD_VALUE;
756 	}
757 
758 	return Error::NONE;
759 }
760 
761 /*
762  * Get the transport size of a buffer
763  *
764  * @param buffer       [in] Buffer for computing transport size
765  * @param hidl_cb      [in] HIDL callback function generating -
766  *                          error:   NONE upon success. Otherwise,
767  *                                   BAD_BUFFER for an invalid buffer
768  *                          numFds:  Number of file descriptors needed for transport
769  *                          numInts: Number of integers needed for transport
770  *
771  * @return Void
772  */
getTransportSize(void * buffer,getTransportSize_cb hidl_cb)773 Return<void> GrallocMapper::getTransportSize(void* buffer, getTransportSize_cb hidl_cb)
774 {
775 	/* The buffer must have been allocated by Gralloc */
776 	buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
777 	if (!bufferHandle)
778 	{
779 		AERR("Buffer %p is not registered with Gralloc", bufferHandle);
780 		hidl_cb(Error::BAD_BUFFER, -1, -1);
781 		return Void();
782 	}
783 
784 	if (private_handle_t::validate(bufferHandle) < 0)
785 	{
786 		AERR("Buffer %p is corrupted", buffer);
787 		hidl_cb(Error::BAD_BUFFER, -1, -1);
788 		return Void();
789 	}
790 
791 	hidl_cb(Error::NONE, GRALLOC_ARM_NUM_FDS, NUM_INTS_IN_PRIVATE_HANDLE);
792 
793 	return Void();
794 }
795 
796 /*
797  * Creates a buffer descriptor from incoming descriptor attributes
798  *
799  * @param descriptorInfo [in]  Specifies the (2.1 IMapper) attributes of
800  *                             the descriptor.
801  * @param hidl_cb        [in]  HIDL callback function generating -
802  *                             error:      NONE upon success. Otherwise,
803  *                                         BAD_VALUE when any of the specified attributes are invalid
804  *                             descriptor: Newly created buffer descriptor.
805  *
806  * @return Void
807  */
createDescriptor_2_1(const V2_1::IMapper::BufferDescriptorInfo & descriptorInfo,createDescriptor_2_1_cb hidl_cb)808 Return<void> GrallocMapper::createDescriptor_2_1(const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo,
809                                                  createDescriptor_2_1_cb hidl_cb)
810 {
811 	if (validateDescriptorInfo((void *)&descriptorInfo))
812 	{
813 		hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
814 	}
815 	else
816 	{
817 		AERR("Invalid (IMapper 2.1) attributes to create descriptor");
818 		hidl_cb(Error::BAD_VALUE, V2_0::BufferDescriptor());
819 	}
820 
821 	return Void();
822 }
823 #endif /* HIDL_MAPPER_VERSION_SCALED >= 210 */
824 
HIDL_FETCH_IMapper(const char *)825 IMapper* HIDL_FETCH_IMapper(const char* /* name */)
826 {
827 	ALOGV("Arm Module IMapper %d.%d , pid = %d ppid = %d ", GRALLOC_VERSION_MAJOR,
828 	       (HIDL_MAPPER_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid());
829 
830 	return new GrallocMapper();
831 }
832 
833 } // namespace implementation
834 } // namespace HIDL_IMAPPER_NAMESPACE
835 } // namespace mapper
836 } // namespace graphics
837 } // namespace hardware
838 } // namespace android
839