Merge "libdmabufheap: Add an API to check ION support"
diff --git a/BufferAllocator.cpp b/BufferAllocator.cpp
index 386ecc2..ce075d6 100644
--- a/BufferAllocator.cpp
+++ b/BufferAllocator.cpp
@@ -252,6 +252,38 @@
return fd;
}
+int BufferAllocator::AllocSystem(bool cpu_access_needed, size_t len, unsigned int heap_flags,
+ size_t legacy_align) {
+ if (!cpu_access_needed) {
+ /*
+ * CPU does not need to access allocated buffer so we try to allocate in
+ * the 'system-uncached' heap after querying for its existence.
+ */
+ static bool uncached_dmabuf_system_heap_support = [this]() -> bool {
+ auto dmabuf_heap_list = this->GetDmabufHeapList();
+ return (dmabuf_heap_list.find(kDmabufSystemUncachedHeapName) != dmabuf_heap_list.end());
+ }();
+
+ if (uncached_dmabuf_system_heap_support)
+ return DmabufAlloc(kDmabufSystemUncachedHeapName, len);
+
+ static bool uncached_ion_system_heap_support = [this]() -> bool {
+ IonHeapConfig heap_config;
+ auto ret = this->GetIonConfig(kDmabufSystemUncachedHeapName, heap_config);
+ return (ret == 0);
+ }();
+
+ if (uncached_ion_system_heap_support)
+ return IonAlloc(kDmabufSystemUncachedHeapName, len, heap_flags, legacy_align);
+ }
+
+ /*
+ * Either 1) CPU needs to access allocated buffer OR 2) CPU does not need to
+ * access allocated buffer but the "system-uncached" heap is unsupported.
+ */
+ return Alloc(kDmabufSystemHeapName, len, heap_flags, legacy_align);
+}
+
int BufferAllocator::LegacyIonCpuSync(unsigned int dmabuf_fd,
const CustomCpuSyncLegacyIon& legacy_ion_cpu_sync_custom,
void *legacy_ion_custom_data) {
diff --git a/BufferAllocatorWrapper.cpp b/BufferAllocatorWrapper.cpp
index a4ef981..6e2ebed 100644
--- a/BufferAllocatorWrapper.cpp
+++ b/BufferAllocatorWrapper.cpp
@@ -30,10 +30,16 @@
};
int DmabufHeapAlloc(BufferAllocator* buffer_allocator, const char* heap_name, size_t len,
- unsigned int heap_flags) {
+ unsigned int heap_flags, size_t legacy_align) {
if (!buffer_allocator)
return -EINVAL;
- return buffer_allocator->Alloc(heap_name, len, heap_flags);
+ return buffer_allocator->Alloc(heap_name, len, heap_flags, legacy_align);
+}
+
+int DmabufHeapAllocSystem(BufferAllocator* buffer_allocator, bool cpu_access, size_t len,
+ unsigned int heap_flags, size_t legacy_align) {
+ if (!buffer_allocator) return -EINVAL;
+ return buffer_allocator->AllocSystem(cpu_access, len, heap_flags, legacy_align);
}
int MapDmabufHeapNameToIonHeap(BufferAllocator* buffer_allocator, const char* heap_name,
diff --git a/include/BufferAllocator/BufferAllocator.h b/include/BufferAllocator/BufferAllocator.h
index 44c90fb..edc3143 100644
--- a/include/BufferAllocator/BufferAllocator.h
+++ b/include/BufferAllocator/BufferAllocator.h
@@ -81,6 +81,24 @@
*/
int Alloc(const std::string& heap_name, size_t len, unsigned int heap_flags = 0, size_t legacy_align = 0);
+ /* *
+ * Returns a dmabuf fd if the allocation in system heap(cached/uncached) is successful and
+ * an error code otherwise. Allocates in the 'system' heap if CPU access of
+ * the buffer is expected and 'system-uncached' otherwise. If the 'system-uncached'
+ * heap is not supported, falls back to the 'system' heap.
+ * For vendor defined heaps with a legacy ION interface(no heap query support),
+ * MapNameToIonMask() must be called prior to invocation of AllocSystem() to
+ * map names 'system'(and optionally 'system-uncached' if applicable) to an
+ * equivalent heap mask and heap flag configuration;
+ * configuration.
+ * @cpu_access: indicates if CPU access of the buffer is expected.
+ * @len: size of the allocation.
+ * @heap_flags: flags passed to heap.
+ * @legacy_align: alignment value used only by legacy ION
+ */
+ int AllocSystem(bool cpu_access, size_t len, unsigned int heap_flags = 0,
+ size_t legacy_align = 0);
+
/**
* Optional custom callback for legacy ion implementation that can be specified as a
* parameter to CpuSyncStart() and CpuSyncEnd(). Its first argument is an fd to /dev/ion.
diff --git a/include/BufferAllocator/BufferAllocatorWrapper.h b/include/BufferAllocator/BufferAllocatorWrapper.h
index c1c4b0c..5d62de6 100644
--- a/include/BufferAllocator/BufferAllocatorWrapper.h
+++ b/include/BufferAllocator/BufferAllocatorWrapper.h
@@ -18,6 +18,7 @@
#define BUFFER_ALLOCATOR_H_
#include <BufferAllocator/dmabufheap-defs.h>
+#include <stdbool.h>
#include <sys/types.h>
#ifdef __cplusplus
@@ -32,7 +33,9 @@
void FreeDmabufHeapBufferAllocator(BufferAllocator* buffer_allocator);
int DmabufHeapAlloc(BufferAllocator* buffer_allocator, const char* heap_name, size_t len,
- unsigned int heap_flags);
+ unsigned int heap_flags, size_t legacy_align);
+int DmabufHeapAllocSystem(BufferAllocator* buffer_allocator, bool cpu_access, size_t len,
+ unsigned int heap_flags, size_t legacy_align);
int MapDmabufHeapNameToIonHeap(BufferAllocator* buffer_allocator, const char* heap_name,
const char* ion_heap_name, unsigned int ion_heap_flags,
diff --git a/tests/dmabuf_heap_test.c b/tests/dmabuf_heap_test.c
index db880c8..55e6788 100644
--- a/tests/dmabuf_heap_test.c
+++ b/tests/dmabuf_heap_test.c
@@ -76,7 +76,24 @@
return;
}
- fd = DmabufHeapAlloc(bufferAllocator, kDmabufSystemHeapName, len, 0);
+ /*
+ * Test the DmabufHeapAllocSystem() APIs.
+ */
+ fd = DmabufHeapAllocSystem(bufferAllocator, true /* cpu_access */, len, 0, 0);
+ if (fd < 0) {
+ printf("DmabufHeapAllocSystem() failed: %d cpu_access: true\n", fd);
+ return;
+ }
+ close(fd);
+
+ fd = DmabufHeapAllocSystem(bufferAllocator, false /* cpu_access */, len, 0, 0);
+ if (fd < 0) {
+ printf("DmabufHeapAllocSystem() failed: %d cpu_access: false\n", fd);
+ return;
+ }
+ close(fd);
+
+ fd = DmabufHeapAlloc(bufferAllocator, kDmabufSystemHeapName, len, 0, 0);
if (fd < 0) {
printf("Alloc failed: %d\n", fd);
return;
diff --git a/tests/dmabuf_heap_test.cpp b/tests/dmabuf_heap_test.cpp
index fdb3c79..243f703 100644
--- a/tests/dmabuf_heap_test.cpp
+++ b/tests/dmabuf_heap_test.cpp
@@ -33,9 +33,9 @@
public:
virtual void SetUp() { allocator = new BufferAllocator(); }
- void DoAlloc(const std::string& heap_name) {
+ void DoAlloc(bool cpu_access_needed) {
static const size_t kAllocSizeInBytes = 4096;
- int map_fd = allocator->Alloc(heap_name, kAllocSizeInBytes);
+ int map_fd = allocator->AllocSystem(cpu_access_needed, kAllocSizeInBytes);
ASSERT_GE(map_fd, 0);
void* ptr = mmap(NULL, kAllocSizeInBytes, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
@@ -52,19 +52,19 @@
}
void DoConcurrentAlloc() {
- DoAlloc(kDmabufSystemHeapName);
- DoAlloc(kDmabufSystemUncachedHeapName);
+ DoAlloc(true /* cpu_access_needed */);
+ DoAlloc(false /* cpu_access_needed */);
}
void DoConcurrentAllocWithMapName() {
allocator->MapNameToIonHeap(kDmabufSystemHeapName, "" /* no mapping for non-legacy */,
0 /* no mapping for non-legacy ion */,
~0 /* legacy ion heap mask */, ION_FLAG_CACHED);
- DoAlloc(kDmabufSystemHeapName);
+ DoAlloc(true /* cpu_access_needed */);
allocator->MapNameToIonHeap(
kDmabufSystemUncachedHeapName, "" /* no mapping for non-legacy */,
0 /* no mapping for non-legacy ion */, ~0 /* legacy ion heap mask */);
- DoAlloc(kDmabufSystemUncachedHeapName);
+ DoAlloc(false /* cpu_access_needed */);
}
virtual void TearDown() { delete allocator; }
@@ -124,26 +124,16 @@
~0 /* legacy ion heap mask */);
}
-TEST_F(DmaBufHeapTest, AllocateUncached) {
+TEST_F(DmaBufHeapTest, Allocate) {
static const size_t allocationSizes[] = {4 * 1024, 64 * 1024, 1024 * 1024, 2 * 1024 * 1024};
- for (size_t size : allocationSizes) {
- SCOPED_TRACE(::testing::Message()
- << "heap: " << kDmabufSystemUncachedHeapName << " size: " << size);
- int fd = allocator->Alloc(kDmabufSystemUncachedHeapName, size);
- ASSERT_GE(fd, 0);
- ASSERT_EQ(close(fd), 0); // free the buffer
- }
-}
-
-TEST_F(DmaBufHeapTest, AllocateCached) {
- static const size_t allocationSizes[] = {4 * 1024, 64 * 1024, 1024 * 1024, 2 * 1024 * 1024};
- for (size_t size : allocationSizes) {
- SCOPED_TRACE(::testing::Message()
- << "heap: " << kDmabufSystemHeapName << " size: " << size);
- int fd = allocator->Alloc(kDmabufSystemHeapName, size, ION_FLAG_CACHED
- /* ion heap flags will be ignored if using dmabuf heaps */);
- ASSERT_GE(fd, 0);
- ASSERT_EQ(close(fd), 0); // free the buffer
+ for (bool cpu_access_needed : {false, true}) {
+ for (size_t size : allocationSizes) {
+ SCOPED_TRACE(::testing::Message()
+ << "cpu_access_needed: " << cpu_access_needed << " size: " << size);
+ int fd = allocator->AllocSystem(cpu_access_needed, size);
+ ASSERT_GE(fd, 0);
+ ASSERT_EQ(close(fd), 0); // free the buffer
+ }
}
}
@@ -159,30 +149,18 @@
}
}
-TEST_F(DmaBufHeapTest, RepeatedAllocateUncached) {
+TEST_F(DmaBufHeapTest, RepeatedAllocate) {
static const size_t allocationSizes[] = {4 * 1024, 64 * 1024, 1024 * 1024, 2 * 1024 * 1024};
- for (size_t size : allocationSizes) {
- SCOPED_TRACE(::testing::Message()
- << "heap: " << kDmabufSystemUncachedHeapName << " size: " << size);
- for (unsigned int i = 0; i < 1024; i++) {
- SCOPED_TRACE(::testing::Message() << "iteration " << i);
- int fd = allocator->Alloc(kDmabufSystemUncachedHeapName, size);
- ASSERT_GE(fd, 0);
- ASSERT_EQ(close(fd), 0); // free the buffer
- }
- }
-}
-
-TEST_F(DmaBufHeapTest, RepeatedAllocateCached) {
- static const size_t allocationSizes[] = {4 * 1024, 64 * 1024, 1024 * 1024, 2 * 1024 * 1024};
- for (size_t size : allocationSizes) {
- SCOPED_TRACE(::testing::Message()
- << "heap: " << kDmabufSystemHeapName << " size: " << size);
- for (unsigned int i = 0; i < 1024; i++) {
- SCOPED_TRACE(::testing::Message() << "iteration " << i);
- int fd = allocator->Alloc(kDmabufSystemHeapName, size);
- ASSERT_GE(fd, 0);
- ASSERT_EQ(close(fd), 0); // free the buffer
+ for (bool cpu_access_needed : {false, true}) {
+ for (size_t size : allocationSizes) {
+ SCOPED_TRACE(::testing::Message()
+ << "cpu_access_needed: " << cpu_access_needed << " size: " << size);
+ for (unsigned int i = 0; i < 1024; i++) {
+ SCOPED_TRACE(::testing::Message() << "iteration " << i);
+ int fd = allocator->AllocSystem(cpu_access_needed, size);
+ ASSERT_GE(fd, 0);
+ ASSERT_EQ(close(fd), 0); // free the buffer
+ }
}
}
}
@@ -305,7 +283,6 @@
TEST_F(DmaBufHeapTest, TestDmabufSystemHeapCompliance) {
using android::vintf::KernelVersion;
- static const size_t kAllocSizeInBytes = 4096;
if (android::base::GetIntProperty("ro.product.first_api_level", 0) < __ANDROID_API_S__) {
GTEST_SKIP();
}
@@ -322,30 +299,34 @@
auto heap_list = allocator->GetDmabufHeapList();
ASSERT_TRUE(heap_list.find("system") != heap_list.end());
- /*
- * Test that system heap can be allocated from.
- */
- int map_fd = allocator->Alloc(kDmabufSystemHeapName, kAllocSizeInBytes);
- ASSERT_GE(map_fd, 0);
+ for (bool cpu_access_needed : {false, true}) {
+ static const size_t kAllocSizeInBytes = 4096;
+ /*
+ * Test that system heap can be allocated from.
+ */
+ SCOPED_TRACE(::testing::Message() << "cpu_access_needed: " << cpu_access_needed);
+ int map_fd = allocator->AllocSystem(cpu_access_needed, kAllocSizeInBytes);
+ ASSERT_GE(map_fd, 0);
- /*
- * Test that system heap can be mmapped by the CPU.
- */
- void* ptr = mmap(NULL, kAllocSizeInBytes, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
- ASSERT_TRUE(ptr != MAP_FAILED);
+ /*
+ * Test that system heap can be mmapped by the CPU.
+ */
+ void* ptr = mmap(NULL, kAllocSizeInBytes, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
+ ASSERT_TRUE(ptr != MAP_FAILED);
- /*
- * Test that the allocated memory is zeroed.
- */
- auto zeroes_ptr = std::make_unique<char[]>(kAllocSizeInBytes);
- int ret = allocator->CpuSyncStart(map_fd);
- ASSERT_EQ(0, ret);
+ /*
+ * Test that the allocated memory is zeroed.
+ */
+ auto zeroes_ptr = std::make_unique<char[]>(kAllocSizeInBytes);
+ int ret = allocator->CpuSyncStart(map_fd);
+ ASSERT_EQ(0, ret);
- ASSERT_EQ(0, memcmp(ptr, zeroes_ptr.get(), kAllocSizeInBytes));
+ ASSERT_EQ(0, memcmp(ptr, zeroes_ptr.get(), kAllocSizeInBytes));
- ret = allocator->CpuSyncEnd(map_fd);
- ASSERT_EQ(0, ret);
+ ret = allocator->CpuSyncEnd(map_fd);
+ ASSERT_EQ(0, ret);
- ASSERT_EQ(0, munmap(ptr, kAllocSizeInBytes));
- ASSERT_EQ(0, close(map_fd));
+ ASSERT_EQ(0, munmap(ptr, kAllocSizeInBytes));
+ ASSERT_EQ(0, close(map_fd));
+ }
}