summaryrefslogtreecommitdiff
path: root/cros_gralloc/aidl/Allocator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cros_gralloc/aidl/Allocator.cpp')
-rw-r--r--cros_gralloc/aidl/Allocator.cpp163
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