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