• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 BufferDescriptorInfo =
20         android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
21 
22 namespace aidl::android::hardware::graphics::allocator::impl {
23 namespace {
24 
ToBinderStatus(AllocationError error)25 inline ndk::ScopedAStatus ToBinderStatus(AllocationError error) {
26     return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error));
27 }
28 
29 }  // namespace
30 
init()31 bool Allocator::init() {
32     mDriver = cros_gralloc_driver::get_instance();
33     return mDriver != nullptr;
34 }
35 
36 // TODO(natsu): deduplicate with CrosGralloc4Allocator after the T release.
initializeMetadata(cros_gralloc_handle_t crosHandle,const struct cros_gralloc_buffer_descriptor & crosDescriptor)37 ndk::ScopedAStatus Allocator::initializeMetadata(
38         cros_gralloc_handle_t crosHandle,
39         const struct cros_gralloc_buffer_descriptor& crosDescriptor) {
40     if (!mDriver) {
41         ALOGE("Failed to initializeMetadata. Driver is uninitialized.\n");
42         return ToBinderStatus(AllocationError::NO_RESOURCES);
43     }
44 
45     if (!crosHandle) {
46         ALOGE("Failed to initializeMetadata. Invalid handle.\n");
47         return ToBinderStatus(AllocationError::NO_RESOURCES);
48     }
49 
50     void* addr;
51     uint64_t size;
52     int ret = mDriver->get_reserved_region(crosHandle, &addr, &size);
53     if (ret) {
54         ALOGE("Failed to getReservedRegion.\n");
55         return ToBinderStatus(AllocationError::NO_RESOURCES);
56     }
57 
58     CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
59 
60     snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s",
61              crosDescriptor.name.c_str());
62     crosMetadata->dataspace = common::Dataspace::UNKNOWN;
63     crosMetadata->blendMode = common::BlendMode::INVALID;
64 
65     return ndk::ScopedAStatus::ok();
66 }
67 
releaseBufferAndHandle(native_handle_t * handle)68 void Allocator::releaseBufferAndHandle(native_handle_t* handle) {
69     mDriver->release(handle);
70     native_handle_close(handle);
71     native_handle_delete(handle);
72 }
73 
allocate(const std::vector<uint8_t> & descriptor,int32_t count,allocator::AllocationResult * outResult)74 ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
75                                        allocator::AllocationResult* outResult) {
76     if (!mDriver) {
77         ALOGE("Failed to allocate. Driver is uninitialized.\n");
78         return ToBinderStatus(AllocationError::NO_RESOURCES);
79     }
80 
81     BufferDescriptorInfo description;
82 
83     int ret = ::android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
84     if (ret) {
85         ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
86         return ToBinderStatus(AllocationError::BAD_DESCRIPTOR);
87     }
88 
89     std::vector<native_handle_t*> handles;
90     handles.resize(count, nullptr);
91 
92     for (int32_t i = 0; i < count; i++) {
93         ndk::ScopedAStatus status = allocate(description, &outResult->stride, &handles[i]);
94         if (!status.isOk()) {
95             for (int32_t j = 0; j < i; j++) {
96                 releaseBufferAndHandle(handles[j]);
97             }
98             return status;
99         }
100     }
101 
102     outResult->buffers.resize(count);
103     for (int32_t i = 0; i < count; i++) {
104         auto handle = handles[i];
105         outResult->buffers[i] = ::android::dupToAidl(handle);
106         releaseBufferAndHandle(handle);
107     }
108 
109     return ndk::ScopedAStatus::ok();
110 }
111 
allocate(const BufferDescriptorInfo & descriptor,int32_t * outStride,native_handle_t ** outHandle)112 ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfo& descriptor, int32_t* outStride,
113                                        native_handle_t** outHandle) {
114     if (!mDriver) {
115         ALOGE("Failed to allocate. Driver is uninitialized.\n");
116         return ToBinderStatus(AllocationError::NO_RESOURCES);
117     }
118 
119     struct cros_gralloc_buffer_descriptor crosDescriptor;
120     if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
121         return ToBinderStatus(AllocationError::UNSUPPORTED);
122     }
123 
124     crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
125 
126     if (!mDriver->is_supported(&crosDescriptor)) {
127         const std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format);
128         const std::string pixelFormatString = getPixelFormatString(descriptor.format);
129         const std::string usageString = getUsageString(descriptor.usage);
130         ALOGE("Failed to allocate. Unsupported combination: pixel format:%s, drm format:%s, "
131               "usage:%s\n",
132               pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
133         return ToBinderStatus(AllocationError::UNSUPPORTED);
134     }
135 
136     native_handle_t* handle;
137     int ret = mDriver->allocate(&crosDescriptor, &handle);
138     if (ret) {
139         return ToBinderStatus(AllocationError::NO_RESOURCES);
140     }
141 
142     cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
143 
144     auto status = initializeMetadata(crosHandle, crosDescriptor);
145     if (!status.isOk()) {
146         ALOGE("Failed to allocate. Failed to initialize gralloc buffer metadata.");
147         releaseBufferAndHandle(handle);
148         return status;
149     }
150 
151     *outStride = static_cast<int32_t>(crosHandle->pixel_stride);
152     *outHandle = handle;
153 
154     return ndk::ScopedAStatus::ok();
155 }
156 
createBinder()157 ::ndk::SpAIBinder Allocator::createBinder() {
158     auto binder = BnAllocator::createBinder();
159     AIBinder_setInheritRt(binder.get(), true);
160     return binder;
161 }
162 
163 }  // namespace aidl::android::hardware::graphics::allocator::impl