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