(Reland) Revert "Revert "[vulkan] create resources with requirements (guest)""

This reverts commit 842c59b99c645a2c9f7ad7c60ce29ce17acdb9c2.

Change-Id: I1ca873a07a08c3ed4843d1e013c7c2d083e6704f
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 9cd8a79..d085ca4 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -265,6 +265,8 @@
         VkDeviceMemory currentBacking = VK_NULL_HANDLE;
         VkDeviceSize currentBackingOffset = 0;
         VkDeviceSize currentBackingSize = 0;
+        bool baseRequirementsKnown = false;
+        VkMemoryRequirements baseRequirements;
     };
 
     struct VkBuffer_Info {
@@ -275,6 +277,8 @@
         VkDeviceMemory currentBacking = VK_NULL_HANDLE;
         VkDeviceSize currentBackingOffset = 0;
         VkDeviceSize currentBackingSize = 0;
+        bool baseRequirementsKnown = false;
+        VkMemoryRequirements baseRequirements;
     };
 
     struct VkSemaphore_Info {
@@ -611,6 +615,11 @@
         return mFeatureInfo->hasDeferredVulkanCommands;
     }
 
+    bool supportsCreateResourcesWithRequirements() const {
+        if (!mFeatureInfo) return false;
+        return mFeatureInfo->hasVulkanCreateResourcesWithRequirements;
+    }
+
     int getHostInstanceExtensionIndex(const std::string& extName) const {
         int i = 0;
         for (const auto& prop : mHostInstanceExtensions) {
@@ -2060,12 +2069,10 @@
         dedicatedReqs->requiresDedicatedAllocation = VK_TRUE;
     }
 
-    void transformImageMemoryRequirementsForGuest(
+    void transformImageMemoryRequirementsForGuestLocked(
         VkImage image,
         VkMemoryRequirements* reqs) {
 
-        AutoLock lock(mLock);
-
         auto it = info_VkImage.find(image);
         if (it == info_VkImage.end()) return;
 
@@ -2080,12 +2087,10 @@
         transformExternalResourceMemoryRequirementsForGuest(reqs);
     }
 
-    void transformBufferMemoryRequirementsForGuest(
+    void transformBufferMemoryRequirementsForGuestLocked(
         VkBuffer buffer,
         VkMemoryRequirements* reqs) {
 
-        AutoLock lock(mLock);
-
         auto it = info_VkBuffer.find(buffer);
         if (it == info_VkBuffer.end()) return;
 
@@ -2238,7 +2243,14 @@
         }
 #endif
 
-        VkResult res = enc->vkCreateImage(device, &localCreateInfo, pAllocator, pImage);
+        VkResult res;
+        VkMemoryRequirements memReqs;
+
+        if (supportsCreateResourcesWithRequirements()) {
+            res = enc->vkCreateImageWithRequirementsGOOGLE(device, &localCreateInfo, pAllocator, pImage, &memReqs);
+        } else {
+            res = enc->vkCreateImage(device, &localCreateInfo, pAllocator, pImage);
+        }
 
         if (res != VK_SUCCESS) return res;
 
@@ -2253,10 +2265,19 @@
         info.createInfo = *pCreateInfo;
         info.createInfo.pNext = nullptr;
 
-        if (!extImgCiPtr) return res;
+        if (supportsCreateResourcesWithRequirements()) {
+            info.baseRequirementsKnown = true;
+        }
 
-        info.external = true;
-        info.externalCreateInfo = *extImgCiPtr;
+        if (extImgCiPtr) {
+            info.external = true;
+            info.externalCreateInfo = *extImgCiPtr;
+        }
+
+        if (info.baseRequirementsKnown) {
+            transformImageMemoryRequirementsForGuestLocked(*pImage, &memReqs);
+            info.baseRequirements = memReqs;
+        }
 
         return res;
     }
@@ -2321,11 +2342,32 @@
     void on_vkGetImageMemoryRequirements(
         void *context, VkDevice device, VkImage image,
         VkMemoryRequirements *pMemoryRequirements) {
+
+        AutoLock lock(mLock);
+
+        auto it = info_VkImage.find(image);
+        if (it == info_VkImage.end()) return;
+
+        auto& info = it->second;
+
+        if (info.baseRequirementsKnown) {
+            *pMemoryRequirements = info.baseRequirements;
+            return;
+        }
+
+        lock.unlock();
+
         VkEncoder* enc = (VkEncoder*)context;
+
         enc->vkGetImageMemoryRequirements(
             device, image, pMemoryRequirements);
-        transformImageMemoryRequirementsForGuest(
+
+        lock.lock();
+
+        transformImageMemoryRequirementsForGuestLocked(
             image, pMemoryRequirements);
+        info.baseRequirementsKnown = true;
+        info.baseRequirements = *pMemoryRequirements;
     }
 
     void on_vkGetImageMemoryRequirements2(
@@ -2377,7 +2419,14 @@
         VkBuffer *pBuffer) {
         VkEncoder* enc = (VkEncoder*)context;
 
-        VkResult res = enc->vkCreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+        VkResult res;
+        VkMemoryRequirements memReqs;
+
+        if (supportsCreateResourcesWithRequirements()) {
+            res = enc->vkCreateBufferWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pBuffer, &memReqs);
+        } else {
+            res = enc->vkCreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+        }
 
         if (res != VK_SUCCESS) return res;
 
@@ -2391,13 +2440,22 @@
         info.createInfo = *pCreateInfo;
         info.createInfo.pNext = nullptr;
 
+        if (supportsCreateResourcesWithRequirements()) {
+            info.baseRequirementsKnown = true;
+        }
+
         const VkExternalMemoryBufferCreateInfo* extBufCi =
             vk_find_struct<VkExternalMemoryBufferCreateInfo>(pCreateInfo);
 
-        if (!extBufCi) return res;
+        if (extBufCi) {
+            info.external = true;
+            info.externalCreateInfo = *extBufCi;
+        }
 
-        info.external = true;
-        info.externalCreateInfo = *extBufCi;
+        if (info.baseRequirementsKnown) {
+            transformBufferMemoryRequirementsForGuestLocked(*pBuffer, &memReqs);
+            info.baseRequirements = memReqs;
+        }
 
         return res;
     }
@@ -2411,11 +2469,31 @@
 
     void on_vkGetBufferMemoryRequirements(
         void* context, VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements) {
+
+        AutoLock lock(mLock);
+
+        auto it = info_VkBuffer.find(buffer);
+        if (it == info_VkBuffer.end()) return;
+
+        auto& info = it->second;
+
+        if (info.baseRequirementsKnown) {
+            *pMemoryRequirements = info.baseRequirements;
+            return;
+        }
+
+        lock.unlock();
+
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetBufferMemoryRequirements(
             device, buffer, pMemoryRequirements);
-        transformBufferMemoryRequirementsForGuest(
+
+        lock.lock();
+
+        transformBufferMemoryRequirementsForGuestLocked(
             buffer, pMemoryRequirements);
+        info.baseRequirementsKnown = true;
+        info.baseRequirements = *pMemoryRequirements;
     }
 
     void on_vkGetBufferMemoryRequirements2(