Add front buffer gralloc usage
Test: builds & boots, still needs real tests
Bug: 193558894
Change-Id: Iaf0421ad897966d13a4c231edf9ce78056e059a2
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 8ac08fb..9241709 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::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 {
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 @@
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 @@
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 @@
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 @@
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 @@
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) {