1 #include "GrallocAllocator.h"
2
3 #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
4 #include <aidlcommonsupport/NativeHandle.h>
5 #include <android/binder_ibinder.h>
6 #include <android/binder_status.h>
7 #include <hidl/HidlSupport.h>
8
9 #include "allocator/mali_gralloc_ion.h"
10 #include "hidl_common/Allocator.h"
11
12 namespace pixel::allocator {
13
14 namespace AidlAllocator = aidl::android::hardware::graphics::allocator;
15 namespace HidlAllocator = android::hardware::graphics::allocator::V4_0;
16
17 using android::hardware::hidl_handle;
18 using android::hardware::hidl_vec;
19 using HidlError = android::hardware::graphics::mapper::V4_0::Error;
20
callingPid()21 unsigned long callingPid() {
22 return static_cast<unsigned long>(AIBinder_getCallingPid());
23 }
24
GrallocAllocator()25 GrallocAllocator::GrallocAllocator() {}
26
~GrallocAllocator()27 GrallocAllocator::~GrallocAllocator() {}
28
allocate(const std::vector<uint8_t> & descriptor,int32_t count,AidlAllocator::AllocationResult * result)29 ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
30 AidlAllocator::AllocationResult* result) {
31 MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
32
33 buffer_descriptor_t bufferDescriptor;
34 if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor),
35 bufferDescriptor)) {
36 return ndk::ScopedAStatus::fromServiceSpecificError(
37 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
38 }
39
40 // TODO(layog@): This dependency between AIDL and HIDL backends is not good.
41 // Ideally common::allocate should return the result and it should be encoded
42 // by this interface into HIDL or AIDL.
43 HidlError error = HidlError::NONE;
44 auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
45 if (_error != HidlError::NONE) {
46 error = _error;
47 return;
48 }
49
50 const uint32_t size = _buffers.size();
51
52 result->stride = _stride;
53 result->buffers.resize(size);
54 for (uint32_t i = 0; i < size; i++) {
55 // Dup here is necessary. After this callback returns common::allocate
56 // will free the buffer which will destroy the older fd.
57 result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
58 }
59 };
60
61 arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
62
63 switch (error) {
64 case HidlError::NONE:
65 break;
66
67 case HidlError::BAD_DESCRIPTOR:
68 return ndk::ScopedAStatus::fromServiceSpecificError(
69 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
70
71 case HidlError::NO_RESOURCES:
72 return ndk::ScopedAStatus::fromServiceSpecificError(
73 static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
74
75 case HidlError::UNSUPPORTED:
76 return ndk::ScopedAStatus::fromServiceSpecificError(
77 static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
78
79 default:
80 return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
81 }
82
83 return ndk::ScopedAStatus::ok();
84 }
85
86 } // namespace pixel::allocator
87