xref: /aosp_15_r20/external/minigbm/cros_gralloc/aidl/Allocator.cpp (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1 /*
2  * Copyright 2022 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #include "Allocator.h"
8 
9 #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
10 #include <aidlcommonsupport/NativeHandle.h>
11 #include <android-base/logging.h>
12 #include <android/binder_ibinder_platform.h>
13 #include <gralloctypes/Gralloc4.h>
14 #include <log/log.h>
15 
16 #include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
17 
18 using aidl::android::hardware::common::NativeHandle;
19 using BufferDescriptorInfoV4 =
20         android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
21 
22 static const std::string STANDARD_METADATA_DATASPACE = "android.hardware.graphics.common.Dataspace";
23 
24 namespace aidl::android::hardware::graphics::allocator::impl {
25 namespace {
26 
ToBinderStatus(AllocationError error)27 inline ndk::ScopedAStatus ToBinderStatus(AllocationError error) {
28     return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error));
29 }
30 
convertToCrosDescriptor(const BufferDescriptorInfo & info,struct cros_gralloc_buffer_descriptor & crosDescriptor)31 ndk::ScopedAStatus convertToCrosDescriptor(const BufferDescriptorInfo& info,
32                                            struct cros_gralloc_buffer_descriptor& crosDescriptor) {
33     const BufferDescriptorInfoV4 mapperV4Descriptor = {
34         .name{reinterpret_cast<const char*>(info.name.data())},
35         .width = static_cast<uint32_t>(info.width),
36         .height = static_cast<uint32_t>(info.height),
37         .layerCount = static_cast<uint32_t>(info.layerCount),
38         .format = static_cast<::android::hardware::graphics::common::V1_2::PixelFormat>(info.format),
39         .usage = static_cast<uint64_t>(info.usage),
40         .reservedSize = 0,
41     };
42     if (convertToCrosDescriptor(mapperV4Descriptor, &crosDescriptor)) {
43         return ToBinderStatus(AllocationError::UNSUPPORTED);
44     }
45 
46     for (const auto& option : info.additionalOptions) {
47         if (option.name != STANDARD_METADATA_DATASPACE) {
48             return ToBinderStatus(AllocationError::UNSUPPORTED);
49         }
50         crosDescriptor.dataspace = static_cast<common::Dataspace>(option.value);
51     }
52 
53     return ndk::ScopedAStatus::ok();
54 }
55 
56 }  // namespace
57 
init()58 bool Allocator::init() {
59     mDriver = cros_gralloc_driver::get_instance();
60     return mDriver != nullptr;
61 }
62 
releaseBufferAndHandle(native_handle_t * handle)63 void Allocator::releaseBufferAndHandle(native_handle_t* handle) {
64     mDriver->release(handle);
65     native_handle_close(handle);
66     native_handle_delete(handle);
67 }
68 
allocate(const std::vector<uint8_t> & encodedDescriptor,int32_t count,allocator::AllocationResult * outResult)69 ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& encodedDescriptor, int32_t count,
70                                        allocator::AllocationResult* outResult) {
71     if (!mDriver) {
72         ALOGE("Failed to allocate. Driver is uninitialized.\n");
73         return ToBinderStatus(AllocationError::NO_RESOURCES);
74     }
75 
76     BufferDescriptorInfoV4 mapperV4Descriptor;
77 
78     int ret = ::android::gralloc4::decodeBufferDescriptorInfo(encodedDescriptor, &mapperV4Descriptor);
79     if (ret) {
80         ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
81         return ToBinderStatus(AllocationError::BAD_DESCRIPTOR);
82     }
83 
84     struct cros_gralloc_buffer_descriptor crosDescriptor = {};
85     if (convertToCrosDescriptor(mapperV4Descriptor, &crosDescriptor)) {
86         return ToBinderStatus(AllocationError::UNSUPPORTED);
87     }
88 
89     return allocate(crosDescriptor, count, outResult);
90 }
91 
allocate2(const BufferDescriptorInfo & descriptor,int32_t count,allocator::AllocationResult * outResult)92 ndk::ScopedAStatus Allocator::allocate2(const BufferDescriptorInfo& descriptor, int32_t count,
93                             allocator::AllocationResult* outResult) {
94     if (!mDriver) {
95         ALOGE("Failed to allocate. Driver is uninitialized.\n");
96         return ToBinderStatus(AllocationError::NO_RESOURCES);
97     }
98 
99     struct cros_gralloc_buffer_descriptor crosDescriptor = {};
100 
101     ndk::ScopedAStatus status = convertToCrosDescriptor(descriptor, crosDescriptor);
102     if (!status.isOk()) {
103         return status;
104     }
105 
106     return allocate(crosDescriptor, count, outResult);
107 }
108 
allocate(const struct cros_gralloc_buffer_descriptor & descriptor,int32_t count,allocator::AllocationResult * outResult)109 ndk::ScopedAStatus Allocator::allocate(const struct cros_gralloc_buffer_descriptor& descriptor, int32_t count,
110                                        allocator::AllocationResult* outResult) {
111     if (!mDriver) {
112         ALOGE("Failed to allocate. Driver is uninitialized.\n");
113         return ToBinderStatus(AllocationError::NO_RESOURCES);
114     }
115 
116     std::vector<native_handle_t*> handles;
117     handles.resize(count, nullptr);
118 
119     for (int32_t i = 0; i < count; i++) {
120         ndk::ScopedAStatus status = allocateBuffer(descriptor, &outResult->stride, &handles[i]);
121         if (!status.isOk()) {
122             for (int32_t j = 0; j < i; j++) {
123                 releaseBufferAndHandle(handles[j]);
124             }
125             return status;
126         }
127     }
128 
129     outResult->buffers.resize(count);
130     for (int32_t i = 0; i < count; i++) {
131         auto handle = handles[i];
132         outResult->buffers[i] = ::android::dupToAidl(handle);
133         releaseBufferAndHandle(handle);
134     }
135 
136     return ndk::ScopedAStatus::ok();
137 }
138 
allocateBuffer(const struct cros_gralloc_buffer_descriptor & descriptor,int32_t * outStride,native_handle_t ** outHandle)139 ndk::ScopedAStatus Allocator::allocateBuffer(const struct cros_gralloc_buffer_descriptor& descriptor, int32_t* outStride,
140                                              native_handle_t** outHandle) {
141     if (!mDriver) {
142         ALOGE("Failed to allocate. Driver is uninitialized.\n");
143         return ToBinderStatus(AllocationError::NO_RESOURCES);
144     }
145 
146     if (!mDriver->is_supported(&descriptor)) {
147         const std::string drmFormatString =
148             get_drm_format_string(descriptor.drm_format);
149         const std::string pixelFormatString = ::android::hardware::graphics::common::V1_2::toString(
150             static_cast<::android::hardware::graphics::common::V1_2::PixelFormat>(
151                 descriptor.droid_format));
152         const std::string usageString = ::android::hardware::graphics::common::V1_2::toString<::android::hardware::graphics::common::V1_2::BufferUsage>(
153             static_cast<uint64_t>(descriptor.droid_usage));
154         ALOGE("Failed to allocate. Unsupported combination: pixel format:%s, drm format:%s, "
155               "usage:%s\n",
156               pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
157         return ToBinderStatus(AllocationError::UNSUPPORTED);
158     }
159 
160     native_handle_t* handle;
161     int ret = mDriver->allocate(&descriptor, &handle);
162     if (ret) {
163         return ToBinderStatus(AllocationError::NO_RESOURCES);
164     }
165 
166     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
167     *outStride = static_cast<int32_t>(crosHandle->pixel_stride);
168     *outHandle = handle;
169 
170     return ndk::ScopedAStatus::ok();
171 }
172 
isSupported(const BufferDescriptorInfo & descriptor,bool * outResult)173 ndk::ScopedAStatus Allocator::isSupported(const BufferDescriptorInfo& descriptor,
174                             bool* outResult) {
175     if (!mDriver) {
176         ALOGE("Failed to allocate. Driver is uninitialized.\n");
177         return ToBinderStatus(AllocationError::NO_RESOURCES);
178     }
179 
180     for (const auto& option : descriptor.additionalOptions) {
181         if (option.name != STANDARD_METADATA_DATASPACE) {
182             *outResult = false;
183             return ndk::ScopedAStatus::ok();
184         }
185     }
186 
187     struct cros_gralloc_buffer_descriptor crosDescriptor = {};
188     ndk::ScopedAStatus status = convertToCrosDescriptor(descriptor, crosDescriptor);
189     if (!status.isOk()) {
190         // Failing to convert the descriptor means the layer count, pixel format, or usage is
191         // unsupported, thus isSupported() = false
192         *outResult = false;
193         return ndk::ScopedAStatus::ok();
194     }
195 
196     *outResult = mDriver->is_supported(&crosDescriptor);
197     return ndk::ScopedAStatus::ok();
198 }
199 
getIMapperLibrarySuffix(std::string * outResult)200 ndk::ScopedAStatus Allocator::getIMapperLibrarySuffix(std::string* outResult) {
201     *outResult = "minigbm";
202     return ndk::ScopedAStatus::ok();
203 }
204 
createBinder()205 ::ndk::SpAIBinder Allocator::createBinder() {
206     auto binder = BnAllocator::createBinder();
207     AIBinder_setInheritRt(binder.get(), true);
208     return binder;
209 }
210 
211 }  // namespace aidl::android::hardware::graphics::allocator::impl