Snap for 5798008 from 26ca8405fbc1e7e742fce6723f342ff975064329 to sdk-release

Change-Id: I629b1c3ea2d99e06d62c225ad4a6d93448b03563
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index 4926cf9..2f5e37d 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -228,7 +228,7 @@
 
         const long ret = ioctl_ping(m_provider.m_fd, &request);
         if (ret) {
-            ALOGE("%s: ioctl_ping failed for device_type=%llu, ret=%ld",
+            ALOGE("%s: ioctl_ping failed for device_type=%d, ret=%ld",
                   __func__, DEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID, ret);
             m_provider.close();
         }
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 5e81ead..be6a84e 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -118,6 +118,11 @@
 
 HostConnection::~HostConnection()
 {
+    // round-trip to ensure that queued commands have been processed
+    // before process pipe closure is detected.
+    if (m_rcEnc) {
+        (void) m_rcEnc->rcGetRendererVersion(m_rcEnc);
+    }
     delete m_stream;
     delete m_glEnc;
     delete m_gl2Enc;
diff --git a/system/gralloc/gralloc.cpp b/system/gralloc/gralloc.cpp
index 39e7e16..b3d48ea 100644
--- a/system/gralloc/gralloc.cpp
+++ b/system/gralloc/gralloc.cpp
@@ -545,6 +545,12 @@
     bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
     bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
     const bool hw_texture = usage & GRALLOC_USAGE_HW_TEXTURE;
+    const bool hw_render = usage & GRALLOC_USAGE_HW_RENDER;
+    const bool hw_2d = usage & GRALLOC_USAGE_HW_2D;
+    const bool hw_composer = usage & GRALLOC_USAGE_HW_COMPOSER;
+    const bool hw_fb = usage & GRALLOC_USAGE_HW_FB;
+    const bool rgb888_unsupported_usage =
+        hw_texture || hw_render || hw_2d || hw_composer || hw_fb;
 #if PLATFORM_SDK_VERSION >= 17
     bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
     bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
@@ -608,8 +614,8 @@
             glType = GL_UNSIGNED_BYTE;
             break;
         case HAL_PIXEL_FORMAT_RGB_888:
-            if (hw_texture) {
-                return -EINVAL;  // we dont support RGB_888 for HW textures
+            if (rgb888_unsupported_usage) {
+                return -EINVAL;  // we dont support RGB_888 for HW usage
             } else {
                 bpp = 3;
                 glFormat = GL_RGB;
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 2663c65..2ff4ee5 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -123,9 +123,8 @@
 #include "android/utils/tempfile.h"
 #endif
 
-#ifndef HAVE_MEMFD_CREATE
 static inline int
-memfd_create(const char *name, unsigned int flags) {
+inline_memfd_create(const char *name, unsigned int flags) {
 #ifdef HOST_BUILD
     TempFile* tmpFile = tempfile_create();
     return open(tempfile_path(tmpFile), O_RDWR);
@@ -134,7 +133,7 @@
     return syscall(SYS_memfd_create, name, flags);
 #endif
 }
-#endif // !HAVE_MEMFD_CREATE
+#define memfd_create inline_memfd_create
 #endif // !VK_USE_PLATFORM_ANDROID_KHR
 
 #define RESOURCE_TRACKER_DEBUG 0
@@ -797,9 +796,6 @@
         }
 
         VkExtensionProperties anbExtProps[] = {
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-            { "VK_ANDROID_native_buffer", 7 },
-#endif
 #ifdef VK_USE_PLATFORM_FUCHSIA
             { "VK_KHR_external_memory_capabilities", 1},
             { "VK_KHR_external_semaphore_capabilities", 1},
@@ -810,17 +806,41 @@
             filteredExts.push_back(anbExtProp);
         }
 
-        if (pPropertyCount) {
-            *pPropertyCount = filteredExts.size();
-        }
+        // Spec:
+        //
+        // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
+        //
+        // If pProperties is NULL, then the number of extensions properties
+        // available is returned in pPropertyCount. Otherwise, pPropertyCount
+        // must point to a variable set by the user to the number of elements
+        // in the pProperties array, and on return the variable is overwritten
+        // with the number of structures actually written to pProperties. If
+        // pPropertyCount is less than the number of extension properties
+        // available, at most pPropertyCount structures will be written. If
+        // pPropertyCount is smaller than the number of extensions available,
+        // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
+        // that not all the available properties were returned.
+        //
+        // pPropertyCount must be a valid pointer to a uint32_t value
+        if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;
 
-        if (pPropertyCount && pProperties) {
-            for (size_t i = 0; i < *pPropertyCount; ++i) {
+        if (!pProperties) {
+            *pPropertyCount = (uint32_t)filteredExts.size();
+            return VK_SUCCESS;
+        } else {
+            auto actualExtensionCount = (uint32_t)filteredExts.size();
+            auto toWrite = actualExtensionCount < *pPropertyCount ? actualExtensionCount : *pPropertyCount;
+
+            for (uint32_t i = 0; i < toWrite; ++i) {
                 pProperties[i] = filteredExts[i];
             }
-        }
 
-        return VK_SUCCESS;
+            if (actualExtensionCount > *pPropertyCount) {
+                return VK_INCOMPLETE;
+            }
+
+            return VK_SUCCESS;
+        }
     }
 
     VkResult on_vkEnumerateDeviceExtensionProperties(
@@ -930,6 +950,9 @@
             filteredExts.push_back({
                 "VK_ANDROID_external_memory_android_hardware_buffer", 7
             });
+            filteredExts.push_back({
+                "VK_EXT_queue_family_foreign", 1
+            });
 #endif
 #ifdef VK_USE_PLATFORM_FUCHSIA
             filteredExts.push_back({
@@ -938,18 +961,49 @@
 #endif
         }
 
-        if (pPropertyCount) {
-            *pPropertyCount = filteredExts.size();
-        }
+        // Spec:
+        //
+        // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateDeviceExtensionProperties.html
+        //
+        // pPropertyCount is a pointer to an integer related to the number of
+        // extension properties available or queried, and is treated in the
+        // same fashion as the
+        // vkEnumerateInstanceExtensionProperties::pPropertyCount parameter.
+        //
+        // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
+        //
+        // If pProperties is NULL, then the number of extensions properties
+        // available is returned in pPropertyCount. Otherwise, pPropertyCount
+        // must point to a variable set by the user to the number of elements
+        // in the pProperties array, and on return the variable is overwritten
+        // with the number of structures actually written to pProperties. If
+        // pPropertyCount is less than the number of extension properties
+        // available, at most pPropertyCount structures will be written. If
+        // pPropertyCount is smaller than the number of extensions available,
+        // VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate
+        // that not all the available properties were returned.
+        //
+        // pPropertyCount must be a valid pointer to a uint32_t value
 
-        if (pPropertyCount && pProperties) {
-            for (size_t i = 0; i < *pPropertyCount; ++i) {
+        if (!pPropertyCount) return VK_ERROR_INITIALIZATION_FAILED;
+
+        if (!pProperties) {
+            *pPropertyCount = (uint32_t)filteredExts.size();
+            return VK_SUCCESS;
+        } else {
+            auto actualExtensionCount = (uint32_t)filteredExts.size();
+            auto toWrite = actualExtensionCount < *pPropertyCount ? actualExtensionCount : *pPropertyCount;
+
+            for (uint32_t i = 0; i < toWrite; ++i) {
                 pProperties[i] = filteredExts[i];
             }
+
+            if (actualExtensionCount > *pPropertyCount) {
+                return VK_INCOMPLETE;
+            }
+
+            return VK_SUCCESS;
         }
-
-
-        return VK_SUCCESS;
     }
 
     VkResult on_vkEnumeratePhysicalDevices(
@@ -965,18 +1019,26 @@
 
         AutoLock lock(mLock);
 
+        // When this function is called, we actually need to do two things:
+        // - Get full information about physical devices from the host,
+        // even if the guest did not ask for it
+        // - Serve the guest query according to the spec:
+        //
+        // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html
+
         auto it = info_VkInstance.find(instance);
 
         if (it == info_VkInstance.end()) return VK_ERROR_INITIALIZATION_FAILED;
 
         auto& info = it->second;
 
+        // Get the full host information here if it doesn't exist already.
         if (info.physicalDevices.empty()) {
-            uint32_t physdevCount = 0;
+            uint32_t hostPhysicalDeviceCount = 0;
 
             lock.unlock();
             VkResult countRes = enc->vkEnumeratePhysicalDevices(
-                instance, &physdevCount, nullptr);
+                instance, &hostPhysicalDeviceCount, nullptr);
             lock.lock();
 
             if (countRes != VK_SUCCESS) {
@@ -985,11 +1047,11 @@
                 return countRes;
             }
 
-            info.physicalDevices.resize(physdevCount);
+            info.physicalDevices.resize(hostPhysicalDeviceCount);
 
             lock.unlock();
             VkResult enumRes = enc->vkEnumeratePhysicalDevices(
-                instance, &physdevCount, info.physicalDevices.data());
+                instance, &hostPhysicalDeviceCount, info.physicalDevices.data());
             lock.lock();
 
             if (enumRes != VK_SUCCESS) {
@@ -999,16 +1061,41 @@
             }
         }
 
-        *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
+        // Serve the guest query according to the spec.
+        //
+        // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumeratePhysicalDevices.html
+        //
+        // If pPhysicalDevices is NULL, then the number of physical devices
+        // available is returned in pPhysicalDeviceCount. Otherwise,
+        // pPhysicalDeviceCount must point to a variable set by the user to the
+        // number of elements in the pPhysicalDevices array, and on return the
+        // variable is overwritten with the number of handles actually written
+        // to pPhysicalDevices. If pPhysicalDeviceCount is less than the number
+        // of physical devices available, at most pPhysicalDeviceCount
+        // structures will be written.  If pPhysicalDeviceCount is smaller than
+        // the number of physical devices available, VK_INCOMPLETE will be
+        // returned instead of VK_SUCCESS, to indicate that not all the
+        // available physical devices were returned.
 
-        if (pPhysicalDevices && *pPhysicalDeviceCount) {
-            memcpy(pPhysicalDevices,
-                   info.physicalDevices.data(),
-                   sizeof(VkPhysicalDevice) *
-                   info.physicalDevices.size());
+        if (!pPhysicalDevices) {
+            *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
+            return VK_SUCCESS;
+        } else {
+            uint32_t actualDeviceCount = (uint32_t)info.physicalDevices.size();
+            uint32_t toWrite = actualDeviceCount < *pPhysicalDeviceCount ? actualDeviceCount : *pPhysicalDeviceCount;
+
+            for (uint32_t i = 0; i < toWrite; ++i) {
+                pPhysicalDevices[i] = info.physicalDevices[i];
+            }
+
+            *pPhysicalDeviceCount = toWrite;
+
+            if (actualDeviceCount > *pPhysicalDeviceCount) {
+                return VK_INCOMPLETE;
+            }
+
+            return VK_SUCCESS;
         }
-
-        return VK_SUCCESS;
     }
 
     void on_vkGetPhysicalDeviceMemoryProperties(
@@ -2866,7 +2953,17 @@
         if (input_result != VK_SUCCESS) return input_result;
 
         if (!post_wait_events.empty() || !post_wait_sync_fds.empty()) {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+            // Super bad hack: Just signal stuff early :D
+            // The reason is that it is better than freezing up.
+            // The VK CTS tests external semaphores by queueing up vkCmdWaitEvent
+            // in vkQueueSubmit, which would mean vkQueueWaitIdle here would time out.
+            //
+            // TODO (b/139194471): Have proper sync fd implementation for Android
+            // enc->vkQueueWaitIdle(queue);
+#else
             enc->vkQueueWaitIdle(queue);
+#endif
         }
 
 #ifdef VK_USE_PLATFORM_FUCHSIA
@@ -2916,7 +3013,20 @@
 
     void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {
         if (fd != -1) {
+            // Implicit Synchronization
             sync_wait(fd, 3000);
+            // From libvulkan's swapchain.cpp:
+            // """
+            // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
+            // even if the call fails. We could close it ourselves on failure, but
+            // that would create a race condition if the driver closes it on a
+            // failure path: some other thread might create an fd with the same
+            // number between the time the driver closes it and the time we close
+            // it. We must assume one of: the driver *always* closes it even on
+            // failure, or *never* closes it on failure.
+            // """
+            // Therefore, assume contract where we need to close fd in this driver
+            close(fd);
         }
     }
 
diff --git a/system/vulkan_enc/VkEncoder.cpp b/system/vulkan_enc/VkEncoder.cpp
index 6f43f7a..3b57678 100644
--- a/system/vulkan_enc/VkEncoder.cpp
+++ b/system/vulkan_enc/VkEncoder.cpp
@@ -7355,13 +7355,13 @@
     VkCommandBuffer local_commandBuffer;
     float local_blendConstants[4];
     local_commandBuffer = commandBuffer;
-    memcpy(&local_blendConstants, &blendConstants, 4 * sizeof(const float));
+    memcpy(local_blendConstants, blendConstants, 4 * sizeof(const float));
     countingStream->rewind();
     {
         uint64_t cgen_var_517;
         countingStream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_517, 1);
         countingStream->write((uint64_t*)&cgen_var_517, 1 * 8);
-        countingStream->write((float*)&local_blendConstants, 4 * sizeof(float));
+        countingStream->write((float*)local_blendConstants, 4 * sizeof(float));
     }
     uint32_t packetSize_vkCmdSetBlendConstants = 4 + 4 + (uint32_t)countingStream->bytesWritten();
     countingStream->rewind();
@@ -7371,7 +7371,7 @@
     uint64_t cgen_var_518;
     stream->handleMapping()->mapHandles_VkCommandBuffer_u64(&local_commandBuffer, &cgen_var_518, 1);
     stream->write((uint64_t*)&cgen_var_518, 1 * 8);
-    stream->write((float*)&local_blendConstants, 4 * sizeof(float));
+    stream->write((float*)local_blendConstants, 4 * sizeof(float));
     AEMU_SCOPED_TRACE("vkCmdSetBlendConstants readParams");
     AEMU_SCOPED_TRACE("vkCmdSetBlendConstants returnUnmarshal");
     mImpl->log("finish vkCmdSetBlendConstants");;