diff options
| -rw-r--r-- | libs/ui/Android.bp | 3 | ||||
| -rw-r--r-- | libs/ui/Gralloc4.cpp | 94 | ||||
| -rw-r--r-- | libs/ui/include/ui/Gralloc4.h | 3 |
3 files changed, 100 insertions, 0 deletions
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 006c4780ad..e9f3633e14 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -160,6 +160,7 @@ cc_library_shared { "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.allocator@4.0", + "android.hardware.graphics.allocator-V1-ndk", "android.hardware.graphics.common-V3-ndk", "android.hardware.graphics.common@1.2", "android.hardware.graphics.mapper@2.0", @@ -167,6 +168,7 @@ cc_library_shared { "android.hardware.graphics.mapper@3.0", "android.hardware.graphics.mapper@4.0", "libbase", + "libbinder_ndk", "libcutils", "libgralloctypes", "libhidlbase", @@ -183,6 +185,7 @@ cc_library_shared { ], static_libs: [ + "libaidlcommonsupport", "libarect", "libgrallocusage", "libmath", diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp index 8ac08fb70d..9241709c8c 100644 --- a/libs/ui/Gralloc4.cpp +++ b/libs/ui/Gralloc4.cpp @@ -16,6 +16,12 @@ #define LOG_TAG "Gralloc4" +#include <aidl/android/hardware/graphics/allocator/AllocationError.h> +#include <aidl/android/hardware/graphics/allocator/AllocationResult.h> +#include <aidl/android/hardware/graphics/common/BufferUsage.h> +#include <aidlcommonsupport/NativeHandle.h> +#include <android/binder_enums.h> +#include <android/binder_manager.h> #include <hidl/ServiceManagement.h> #include <hwbinder/IPCThreadState.h> #include <ui/Gralloc4.h> @@ -27,6 +33,8 @@ #include <sync/sync.h> #pragma clang diagnostic pop +using aidl::android::hardware::graphics::allocator::AllocationError; +using aidl::android::hardware::graphics::allocator::AllocationResult; using aidl::android::hardware::graphics::common::ExtendableType; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; using aidl::android::hardware::graphics::common::StandardMetadataType; @@ -36,7 +44,10 @@ using android::hardware::graphics::common::V1_2::BufferUsage; using android::hardware::graphics::mapper::V4_0::BufferDescriptor; using android::hardware::graphics::mapper::V4_0::Error; using android::hardware::graphics::mapper::V4_0::IMapper; +using AidlIAllocator = ::aidl::android::hardware::graphics::allocator::IAllocator; +using AidlBufferUsage = ::aidl::android::hardware::graphics::common::BufferUsage; using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace; +using AidlNativeHandle = ::aidl::android::hardware::common::NativeHandle; using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump; using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump; using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; @@ -48,6 +59,7 @@ namespace android { namespace { static constexpr Error kTransactionError = Error::NO_RESOURCES; +static const auto kAidlAllocatorServiceName = AidlIAllocator::descriptor + std::string("/default"); uint64_t getValidUsageBits() { static const uint64_t validUsageBits = []() -> uint64_t { @@ -61,6 +73,17 @@ uint64_t getValidUsageBits() { return validUsageBits; } +uint64_t getValidUsageBits41() { + static const uint64_t validUsageBits = []() -> uint64_t { + uint64_t bits = 0; + for (const auto bit : ndk::enum_range<AidlBufferUsage>{}) { + bits |= static_cast<int64_t>(bit); + } + return bits; + }(); + return validUsageBits; +} + static inline IMapper::Rect sGralloc4Rect(const Rect& rect) { IMapper::Rect outRect{}; outRect.left = rect.left; @@ -81,6 +104,21 @@ static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint3 outDescriptorInfo->reservedSize = 0; } +// See if gralloc "4.1" is available. +static bool hasIAllocatorAidl() { + // Avoid re-querying repeatedly for this information; + static bool sHasIAllocatorAidl = []() -> bool { + // TODO: Enable after landing sepolicy changes + if constexpr ((true)) return false; + + if (__builtin_available(android 31, *)) { + return AServiceManager_isDeclared(kAidlAllocatorServiceName.c_str()); + } + return false; + }(); + return sHasIAllocatorAidl; +} + } // anonymous namespace void Gralloc4Mapper::preload() { @@ -105,6 +143,9 @@ bool Gralloc4Mapper::isLoaded() const { status_t Gralloc4Mapper::validateBufferDescriptorInfo( IMapper::BufferDescriptorInfo* descriptorInfo) const { uint64_t validUsageBits = getValidUsageBits(); + if (hasIAllocatorAidl()) { + validUsageBits |= getValidUsageBits41(); + } if (descriptorInfo->usage & ~validUsageBits) { ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, @@ -1069,6 +1110,13 @@ Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(map ALOGW("allocator 4.x is not supported"); return; } + if (__builtin_available(android 31, *)) { + if (hasIAllocatorAidl()) { + mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder( + AServiceManager_waitForService(kAidlAllocatorServiceName.c_str()))); + ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service"); + } + } } bool Gralloc4Allocator::isLoaded() const { @@ -1093,6 +1141,52 @@ status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, return error; } + if (mAidlAllocator) { + AllocationResult result; + auto status = mAidlAllocator->allocate(descriptor, bufferCount, &result); + if (!status.isOk()) { + error = status.getExceptionCode(); + if (error == EX_SERVICE_SPECIFIC) { + error = status.getServiceSpecificError(); + } + if (error == OK) { + error = UNKNOWN_ERROR; + } + } else { + if (importBuffers) { + for (uint32_t i = 0; i < bufferCount; i++) { + error = mMapper.importBuffer(makeFromAidl(result.buffers[i]), + &outBufferHandles[i]); + if (error != NO_ERROR) { + for (uint32_t j = 0; j < i; j++) { + mMapper.freeBuffer(outBufferHandles[j]); + outBufferHandles[j] = nullptr; + } + break; + } + } + } else { + for (uint32_t i = 0; i < bufferCount; i++) { + outBufferHandles[i] = dupFromAidl(result.buffers[i]); + if (!outBufferHandles[i]) { + for (uint32_t j = 0; j < i; j++) { + auto buffer = const_cast<native_handle_t*>(outBufferHandles[j]); + native_handle_close(buffer); + native_handle_delete(buffer); + outBufferHandles[j] = nullptr; + } + } + } + } + } + *outStride = result.stride; + // Release all the resources held by AllocationResult (specifically any remaining FDs) + result = {}; + // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now + hardware::IPCThreadState::self()->flushCommands(); + return error; + } + auto ret = mAllocator->allocate(descriptor, bufferCount, [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h index 62f9e4a53f..6bafcd6c81 100644 --- a/libs/ui/include/ui/Gralloc4.h +++ b/libs/ui/include/ui/Gralloc4.h @@ -17,6 +17,7 @@ #ifndef ANDROID_UI_GRALLOC4_H #define ANDROID_UI_GRALLOC4_H +#include <aidl/android/hardware/graphics/allocator/IAllocator.h> #include <android/hardware/graphics/allocator/4.0/IAllocator.h> #include <android/hardware/graphics/common/1.1/types.h> #include <android/hardware/graphics/mapper/4.0/IMapper.h> @@ -204,6 +205,8 @@ public: private: const Gralloc4Mapper& mMapper; sp<hardware::graphics::allocator::V4_0::IAllocator> mAllocator; + // Optional "4.1" allocator + std::shared_ptr<aidl::android::hardware::graphics::allocator::IAllocator> mAidlAllocator; }; } // namespace android |