Use the shared slots host memory allocator

Bug: 149254427
Test: boot
Signed-off-by: Roman Kiryanov <rkir@google.com>
Merged-In: I6bb166e46007e868a67144e404af5b6a5e31cd74
Change-Id: I16f537bddc448b05a3910f15107023352158cdb3
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index 064f601..4216bb9 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -48,6 +48,7 @@
     Graphics = 0,
     Media = 1,
     HostMemoryAllocator = 5,
+    SharedSlotsHostMemoryAllocator = 6,
 };
 
 class GoldfishAddressSpaceBlockProvider {
@@ -55,6 +56,8 @@
     GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice);
     ~GoldfishAddressSpaceBlockProvider();
 
+    bool open(GoldfishAddressSpaceSubdeviceType subdevice);
+
 private:
     GoldfishAddressSpaceBlockProvider(const GoldfishAddressSpaceBlockProvider &rhs);
     GoldfishAddressSpaceBlockProvider &operator=(const GoldfishAddressSpaceBlockProvider &rhs);
@@ -114,7 +117,7 @@
 
 class GoldfishAddressSpaceHostMemoryAllocator {
 public:
-    GoldfishAddressSpaceHostMemoryAllocator();
+    GoldfishAddressSpaceHostMemoryAllocator(bool trySharedSlots = true);
 
     long hostMalloc(GoldfishAddressSpaceBlock *block, size_t size);
     void hostFree(GoldfishAddressSpaceBlock *block);
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index 646695f..96194bd 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -58,6 +58,7 @@
 
 const int HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID = 1;
 const int HOST_MEMORY_ALLOCATOR_COMMAND_UNALLOCATE_ID = 2;
+const int HOST_MEMORY_ALLOCATOR_COMMAND_CHECK_IF_SHARED_SLOTS_SUPPORTED_ID = 3;
 
 int create_address_space_fd()
 {
@@ -86,7 +87,12 @@
     request.version = sizeof(request);
     request.metadata = type;
 
-    return ioctl_ping(fd, &request);
+    long ret = ioctl_ping(fd, &request);
+    if (ret) {
+        return ret;
+    }
+
+    return request.metadata;
 }
 
 long ioctl_claim_shared(int fd, struct goldfish_address_space_claim_shared *request)
@@ -102,16 +108,8 @@
 }  // namespace
 
 GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice)
-  : m_handle(create_address_space_fd())
 {
-    if ((subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) && is_opened()) {
-        const long ret = set_address_space_subdevice_type(m_handle, subdevice);
-        if (ret) {
-            ALOGE("%s: set_address_space_subdevice_type failed for device_type=%lu, ret=%ld",
-                  __func__, static_cast<unsigned long>(subdevice), ret);
-            close();
-        }
-    }
+    open(subdevice);
 }
 
 GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
@@ -126,6 +124,24 @@
     return m_handle >= 0;
 }
 
+bool GoldfishAddressSpaceBlockProvider::open(GoldfishAddressSpaceSubdeviceType subdevice)
+{
+    close();
+
+    m_handle = create_address_space_fd();
+    if ((subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) && is_opened()) {
+        const long ret = set_address_space_subdevice_type(m_handle, subdevice);
+        if (ret) {
+            ALOGE("%s: set_address_space_subdevice_type failed for device_type=%lu, ret=%ld",
+                  __func__, static_cast<unsigned long>(subdevice), ret);
+            close();
+            return false;
+        }
+    }
+
+    return true;
+}
+
 void GoldfishAddressSpaceBlockProvider::close()
 {
     if (is_opened()) {
@@ -337,8 +353,13 @@
     ::munmap(ptr, size);
 }
 
-GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
-  : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {}
+GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator(bool trySharedSlots)
+  : m_provider(trySharedSlots ? GoldfishAddressSpaceSubdeviceType::SharedSlotsHostMemoryAllocator
+                              : GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {
+    if (trySharedSlots && !m_provider.is_opened()) {
+        m_provider.open(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator);
+    }
+}
 
 bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const { return m_provider.is_opened(); }
 
@@ -353,24 +374,52 @@
     if (!m_provider.is_opened()) {
         return -ENODEV;
     }
-    if (!block->allocate(&m_provider, size)) {
-        return -ENOMEM;
-    }
 
     struct goldfish_address_space_ping request;
     ::memset(&request, 0, sizeof(request));
-    request.version = sizeof(request);
-    request.offset = block->offset();
-    request.size = block->size();
-    request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID;
-
+    request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_CHECK_IF_SHARED_SLOTS_SUPPORTED_ID;
     long ret = ioctl_ping(m_provider.m_handle, &request);
     if (ret) {
         return ret;
     }
-    ret = static_cast<long>(request.metadata);
-    if (ret) {
-        return ret;
+
+    if (request.metadata) {
+        // shared memory slots are not supported
+        if (!block->allocate(&m_provider, size)) {
+            return -ENOMEM;
+        }
+
+        ::memset(&request, 0, sizeof(request));
+        request.version = sizeof(request);
+        request.offset = block->offset();
+        request.size = block->size();
+        request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID;
+
+        long ret = ioctl_ping(m_provider.m_handle, &request);
+        if (ret) {
+            return ret;
+        }
+        ret = static_cast<long>(request.metadata);
+        if (ret) {
+            return ret;
+        }
+    } else {
+        // shared memory slots are supported
+        ::memset(&request, 0, sizeof(request));
+        request.version = sizeof(request);
+        request.size = size;
+        request.metadata = HOST_MEMORY_ALLOCATOR_COMMAND_ALLOCATE_ID;
+
+        long ret = ioctl_ping(m_provider.m_handle, &request);
+        if (ret) {
+            return ret;
+        }
+        ret = static_cast<long>(request.metadata);
+        if (ret) {
+            return ret;
+        }
+
+        block->claimShared(&m_provider, request.offset, request.size);
     }
 
     block->mmap(0);
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
index 4d54eed..cb2ce93 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
@@ -228,7 +228,7 @@
     }
 }
 
-GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
+GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator(bool trySharedSlots)
   : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) { }
 
 long GoldfishAddressSpaceHostMemoryAllocator::hostMalloc(GoldfishAddressSpaceBlock *block, size_t size)
@@ -240,6 +240,18 @@
 {
 }
 
+bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const {
+    return false;
+}
+
+address_space_handle_t GoldfishAddressSpaceHostMemoryAllocator::release() {
+    return m_provider.release();
+}
+
+void GoldfishAddressSpaceHostMemoryAllocator::closeHandle(address_space_handle_t handle) {
+    GoldfishAddressSpaceBlockProvider::closeHandle(handle);
+}
+
 class VmoStore {
 public:
     struct Info {
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_host.impl b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
index 6630ed7..5a5ee75 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_host.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
@@ -231,8 +231,13 @@
 
 void GoldfishAddressSpaceBlock::memoryUnmap(void *ptr, size_t size) {}
 
-GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
-  : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {}
+GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator(bool trySharedSlots)
+  : m_provider(trySharedSlots ? GoldfishAddressSpaceSubdeviceType::SharedSlotsHostMemoryAllocator
+                              : GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {
+    if (trySharedSlots && !m_provider.is_opened()) {
+        m_provider.open(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator);
+    }
+}
 
 bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const { return m_provider.is_opened(); }
 
diff --git a/system/hals/allocator3.cpp b/system/hals/allocator3.cpp
index 8be88ff..9d9ef7b 100644
--- a/system/hals/allocator3.cpp
+++ b/system/hals/allocator3.cpp
@@ -329,7 +329,7 @@
                       const int32_t bytesPerPixel,
                       const int32_t stride,
                       cb_handle_30_t** cb) {
-        GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+        GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator(true);
         if (!host_memory_allocator.is_opened()) {
             RETURN_ERROR(Error3::NO_RESOURCES);
         }
diff --git a/system/hals/mapper3.cpp b/system/hals/mapper3.cpp
index b48e497..cbfff9a 100644
--- a/system/hals/mapper3.cpp
+++ b/system/hals/mapper3.cpp
@@ -77,7 +77,7 @@
 class GoldfishMapper : public IMapper3 {
 public:
     GoldfishMapper() : m_hostConn(HostConnection::createUnique()) {
-        GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+        GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator(false);
         CRASH_IF(!host_memory_allocator.is_opened(),
                  "GoldfishAddressSpaceHostMemoryAllocator failed to open");
 
@@ -86,6 +86,8 @@
                  "hostMalloc failed");
 
         m_physAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
+
+        host_memory_allocator.hostFree(&bufferBits);
     }
 
     Return<void> importBuffer(const hidl_handle& hh,