diff options
Diffstat (limited to 'cros_gralloc/aidl/Allocator.cpp')
-rw-r--r-- | cros_gralloc/aidl/Allocator.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/cros_gralloc/aidl/Allocator.cpp b/cros_gralloc/aidl/Allocator.cpp new file mode 100644 index 0000000..0d81d5c --- /dev/null +++ b/cros_gralloc/aidl/Allocator.cpp @@ -0,0 +1,163 @@ +/* + * Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Allocator.h" + +#include <aidl/android/hardware/graphics/allocator/AllocationError.h> +#include <aidlcommonsupport/NativeHandle.h> +#include <android-base/logging.h> +#include <android/binder_ibinder_platform.h> +#include <gralloctypes/Gralloc4.h> +#include <log/log.h> + +#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h" + +using aidl::android::hardware::common::NativeHandle; +using BufferDescriptorInfo = + android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo; + +namespace aidl::android::hardware::graphics::allocator::impl { +namespace { + +inline ndk::ScopedAStatus ToBinderStatus(AllocationError error) { + return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error)); +} + +} // namespace + +bool Allocator::init() { + mDriver = cros_gralloc_driver::get_instance(); + return mDriver != nullptr; +} + +// TODO(natsu): deduplicate with CrosGralloc4Allocator after the T release. +ndk::ScopedAStatus Allocator::initializeMetadata( + cros_gralloc_handle_t crosHandle, + const struct cros_gralloc_buffer_descriptor& crosDescriptor) { + if (!mDriver) { + ALOGE("Failed to initializeMetadata. Driver is uninitialized.\n"); + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + if (!crosHandle) { + ALOGE("Failed to initializeMetadata. Invalid handle.\n"); + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + void* addr; + uint64_t size; + int ret = mDriver->get_reserved_region(crosHandle, &addr, &size); + if (ret) { + ALOGE("Failed to getReservedRegion.\n"); + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr); + + snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s", + crosDescriptor.name.c_str()); + crosMetadata->dataspace = common::Dataspace::UNKNOWN; + crosMetadata->blendMode = common::BlendMode::INVALID; + + return ndk::ScopedAStatus::ok(); +} + +void Allocator::releaseBufferAndHandle(native_handle_t* handle) { + mDriver->release(handle); + native_handle_close(handle); + native_handle_delete(handle); +} + +ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count, + allocator::AllocationResult* outResult) { + if (!mDriver) { + ALOGE("Failed to allocate. Driver is uninitialized.\n"); + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + BufferDescriptorInfo description; + + int ret = ::android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description); + if (ret) { + ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret); + return ToBinderStatus(AllocationError::BAD_DESCRIPTOR); + } + + std::vector<native_handle_t*> handles; + handles.resize(count, nullptr); + + for (int32_t i = 0; i < count; i++) { + ndk::ScopedAStatus status = allocate(description, &outResult->stride, &handles[i]); + if (!status.isOk()) { + for (int32_t j = 0; j < i; j++) { + releaseBufferAndHandle(handles[j]); + } + return status; + } + } + + outResult->buffers.resize(count); + for (int32_t i = 0; i < count; i++) { + auto handle = handles[i]; + outResult->buffers[i] = ::android::dupToAidl(handle); + releaseBufferAndHandle(handle); + } + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfo& descriptor, int32_t* outStride, + native_handle_t** outHandle) { + if (!mDriver) { + ALOGE("Failed to allocate. Driver is uninitialized.\n"); + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + struct cros_gralloc_buffer_descriptor crosDescriptor; + if (convertToCrosDescriptor(descriptor, &crosDescriptor)) { + return ToBinderStatus(AllocationError::UNSUPPORTED); + } + + crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata); + + if (!mDriver->is_supported(&crosDescriptor)) { + const std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format); + const std::string pixelFormatString = getPixelFormatString(descriptor.format); + const std::string usageString = getUsageString(descriptor.usage); + ALOGE("Failed to allocate. Unsupported combination: pixel format:%s, drm format:%s, " + "usage:%s\n", + pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str()); + return ToBinderStatus(AllocationError::UNSUPPORTED); + } + + native_handle_t* handle; + int ret = mDriver->allocate(&crosDescriptor, &handle); + if (ret) { + return ToBinderStatus(AllocationError::NO_RESOURCES); + } + + cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle); + + auto status = initializeMetadata(crosHandle, crosDescriptor); + if (!status.isOk()) { + ALOGE("Failed to allocate. Failed to initialize gralloc buffer metadata."); + releaseBufferAndHandle(handle); + return status; + } + + *outStride = static_cast<int32_t>(crosHandle->pixel_stride); + *outHandle = handle; + + return ndk::ScopedAStatus::ok(); +} + +::ndk::SpAIBinder Allocator::createBinder() { + auto binder = BnAllocator::createBinder(); + AIBinder_setInheritRt(binder.get(), true); + return binder; +} + +} // namespace aidl::android::hardware::graphics::allocator::impl
\ No newline at end of file |