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