Merge "Allow GL_COMPONENT32_OES through"
diff --git a/BUILD.gn b/BUILD.gn
index 9e89881..9b1340c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -52,9 +52,9 @@
     "system/OpenglSystemCommon/ThreadInfo.h",
     "system/renderControl_enc/renderControl_enc.cpp",
     "system/renderControl_enc/renderControl_enc.h",
-    "system/vulkan/func_table.cpp",
-    "system/vulkan/func_table.h",
     "system/vulkan/goldfish_vulkan.cpp",
+    "system/vulkan_enc/CommandBufferStagingStream.cpp",
+    "system/vulkan_enc/CommandBufferStagingStream.h",
     "system/vulkan_enc/HostVisibleMemoryVirtualization.cpp",
     "system/vulkan_enc/HostVisibleMemoryVirtualization.h",
     "system/vulkan_enc/ResourceTracker.cpp",
@@ -69,12 +69,18 @@
     "system/vulkan_enc/VulkanHandleMapping.h",
     "system/vulkan_enc/VulkanStreamGuest.cpp",
     "system/vulkan_enc/VulkanStreamGuest.h",
+    "system/vulkan_enc/func_table.cpp",
+    "system/vulkan_enc/func_table.h",
+    "system/vulkan_enc/goldfish_vk_counting_guest.cpp",
+    "system/vulkan_enc/goldfish_vk_counting_guest.h",
     "system/vulkan_enc/goldfish_vk_deepcopy_guest.cpp",
     "system/vulkan_enc/goldfish_vk_deepcopy_guest.h",
     "system/vulkan_enc/goldfish_vk_extension_structs_guest.cpp",
     "system/vulkan_enc/goldfish_vk_extension_structs_guest.h",
     "system/vulkan_enc/goldfish_vk_marshaling_guest.cpp",
     "system/vulkan_enc/goldfish_vk_marshaling_guest.h",
+    "system/vulkan_enc/goldfish_vk_reserved_marshaling_guest.cpp",
+    "system/vulkan_enc/goldfish_vk_reserved_marshaling_guest.h",
     "system/vulkan_enc/goldfish_vk_transform_guest.cpp",
     "system/vulkan_enc/goldfish_vk_transform_guest.h",
   ]
@@ -127,7 +133,7 @@
       "shared/OpenglCodecCommon/goldfish_dma.h",
       "shared/qemupipe/qemu_pipe_common.cpp",
       "shared/qemupipe/qemu_pipe_guest.cpp",
-      "system/OpenglSystemCommon/QemuPipeStream.cpp"
+      "system/OpenglSystemCommon/QemuPipeStream.cpp",
     ]
     sources += [
       "fuchsia/fuchsia_stdio.cc",
diff --git a/system/hals/allocator3.cpp b/system/hals/allocator3.cpp
index 8b433c2..c91bafd 100644
--- a/system/hals/allocator3.cpp
+++ b/system/hals/allocator3.cpp
@@ -200,6 +200,15 @@
             break;
 
         default:
+            if (static_cast<android::hardware::graphics::common::V1_1::PixelFormat>(format) ==
+                    android::hardware::graphics::common::V1_1::PixelFormat::YCBCR_P010) {
+                yuv_format = true;
+                glFormat = GL_RGBA;
+                glType = GL_UNSIGNED_BYTE;
+                bpp = 2;
+                break;
+            }
+
             ALOGE("%s:%d Unsupported format: format=%d, frameworkFormat=%d, usage=%x",
                   __func__, __LINE__, format, descriptor.format, usage);
             RETURN_ERROR(Error3::UNSUPPORTED);
@@ -309,6 +318,11 @@
     }
 
     static bool needHostCb(const uint32_t usage, const PixelFormat format) {
+        if (static_cast<android::hardware::graphics::common::V1_1::PixelFormat>(format) ==
+                android::hardware::graphics::common::V1_1::PixelFormat::YCBCR_P010) {
+            return false;
+        }
+
         return ((usage & BufferUsage::GPU_DATA_BUFFER)
                    || (format != PixelFormat::BLOB &&
                        format != PixelFormat::RAW16 &&
diff --git a/system/hals/mapper3.cpp b/system/hals/mapper3.cpp
index 3221350..f2116fe 100644
--- a/system/hals/mapper3.cpp
+++ b/system/hals/mapper3.cpp
@@ -342,6 +342,16 @@
             break;
 
         default:
+            if (static_cast<android::hardware::graphics::common::V1_1::PixelFormat>(cb->format) ==
+                    android::hardware::graphics::common::V1_1::PixelFormat::YCBCR_P010) {
+                yStride = cb->width * 2;
+                cStride = yStride;
+                uOffset = cb->height * yStride;
+                vOffset = uOffset + 2;
+                cStep = 4;
+                break;
+            }
+
             ALOGE("%s:%d unexpected format (%d)", __func__, __LINE__, cb->format);
             RETURN_ERROR(Error3::BAD_BUFFER);
         }
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 7138c01..c04703e 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -239,6 +239,16 @@
     std::vector<CommandBufferStagingStream*> streams;
     std::vector<VkEncoder*> encoders;
 
+    ~StagingInfo() {
+        for (auto stream : streams) {
+            delete stream;
+        }
+
+        for (auto encoder : encoders) {
+            delete encoder;
+        }
+    }
+
     void pushStaging(CommandBufferStagingStream* stream, VkEncoder* encoder) {
         AutoLock lock(mLock);
         stream->reset();
@@ -410,6 +420,16 @@
         uint32_t unused;
     };
 
+    struct VkBufferCollectionFUCHSIA_Info {
+#ifdef VK_USE_PLATFORM_FUCHSIA
+        android::base::Optional<
+            llcpp::fuchsia::sysmem::BufferCollectionConstraints>
+            constraints;
+        android::base::Optional<VkBufferCollectionProperties2FUCHSIA>
+            properties;
+#endif  // VK_USE_PLATFORM_FUCHSIA
+    };
+
 #define HANDLE_REGISTER_IMPL_IMPL(type) \
     std::unordered_map<type, type##_Info> info_##type; \
     void register_##type(type obj) { \
@@ -588,6 +608,14 @@
         info_VkFence.erase(fence);
     }
 
+#ifdef VK_USE_PLATFORM_FUCHSIA
+    void unregister_VkBufferCollectionFUCHSIA(
+        VkBufferCollectionFUCHSIA collection) {
+        AutoLock lock(mLock);
+        info_VkBufferCollectionFUCHSIA.erase(collection);
+    }
+#endif
+
     void unregister_VkDescriptorSet_locked(VkDescriptorSet set) {
         auto it = info_VkDescriptorSet.find(set);
         if (it == info_VkDescriptorSet.end()) return;
@@ -1838,6 +1866,7 @@
                 std::move(collection_client));
         *pCollection = reinterpret_cast<VkBufferCollectionFUCHSIA>(sysmem_collection);
 
+        register_VkBufferCollectionFUCHSIA(*pCollection);
         return VK_SUCCESS;
     }
 
@@ -1851,6 +1880,8 @@
             sysmem_collection->Close();
         }
         delete sysmem_collection;
+
+        unregister_VkBufferCollectionFUCHSIA(collection);
     }
 
     inline llcpp::fuchsia::sysmem::BufferCollectionConstraints defaultBufferCollectionConstraints(
@@ -2065,12 +2096,24 @@
         const char* kName = "GoldfishSysmemShared";
         collection->SetName(kVulkanPriority, fidl::unowned_str(kName, strlen(kName)));
 
-        auto result = collection->SetConstraints(true, std::move(constraints));
+        auto result = collection->SetConstraints(true, constraints);
         if (!result.ok()) {
             ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
                   result.status());
             return VK_ERROR_OUT_OF_DEVICE_MEMORY;
         }
+
+        // copy constraints to info_VkBufferCollectionFUCHSIA if
+        // |collection| is a valid VkBufferCollectionFUCHSIA handle.
+        AutoLock lock(mLock);
+        VkBufferCollectionFUCHSIA buffer_collection =
+            reinterpret_cast<VkBufferCollectionFUCHSIA>(collection);
+        if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
+            info_VkBufferCollectionFUCHSIA.end()) {
+            info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
+                android::base::makeOptional(std::move(constraints));
+        }
+
         return VK_SUCCESS;
     }
 
@@ -2096,12 +2139,24 @@
         const char* kName = "GoldfishBufferSysmemShared";
         collection->SetName(kVulkanPriority, fidl::unowned_str(kName, strlen(kName)));
 
-        auto result = collection->SetConstraints(true, std::move(constraints));
+        auto result = collection->SetConstraints(true, constraints);
         if (!result.ok()) {
             ALOGE("setBufferCollectionConstraints: SetConstraints failed: %d",
                   result.status());
             return VK_ERROR_OUT_OF_DEVICE_MEMORY;
         }
+
+        // copy constraints to info_VkBufferCollectionFUCHSIA if
+        // |collection| is a valid VkBufferCollectionFUCHSIA handle.
+        AutoLock lock(mLock);
+        VkBufferCollectionFUCHSIA buffer_collection =
+            reinterpret_cast<VkBufferCollectionFUCHSIA>(collection);
+        if (info_VkBufferCollectionFUCHSIA.find(buffer_collection) !=
+            info_VkBufferCollectionFUCHSIA.end()) {
+            info_VkBufferCollectionFUCHSIA[buffer_collection].constraints =
+                android::base::makeOptional(std::move(constraints));
+        }
+
         return VK_SUCCESS;
     }
 
@@ -3345,6 +3400,15 @@
                               GET_STATUS_SAFE(result, res));
                     }
                 }
+
+                if (info.settings.buffer_settings.heap ==
+                    llcpp::fuchsia::sysmem::HeapType::GOLDFISH_HOST_VISIBLE) {
+                    ALOGD(
+                        "%s: Image uses host visible memory heap; set tiling "
+                        "to linear to match host ImageCreateInfo",
+                        __func__);
+                    localCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
+                }
             }
             isSysmemBackedMemory = true;
         }
@@ -4807,7 +4871,7 @@
 
             std::vector<WorkPool::Task> tasks;
 
-            tasks.push_back([this, queue, externalFenceFdToSignal,
+            tasks.push_back([queue, externalFenceFdToSignal,
                              post_wait_events /* copy of zx handles */,
                              post_wait_sync_fds /* copy of sync fds */] {
                 auto hostConn = ResourceTracker::threadingCallbacks.hostConnectionGetFunc();
@@ -5590,7 +5654,7 @@
         }
 
         if (alsoResetPrimaries) {
-            forAllObjects(cb->superObjects, [this, cb, alsoResetPrimaries](void* obj) {
+            forAllObjects(cb->superObjects, [this, alsoResetPrimaries](void* obj) {
                 VkCommandBuffer superCommandBuffer = (VkCommandBuffer)obj;
                 struct goldfish_VkCommandBuffer* superCb = as_goldfish_VkCommandBuffer(superCommandBuffer);
                 this->resetCommandBufferStagingInfo(superCommandBuffer, alsoResetPrimaries);
diff --git a/system/vulkan_enc/VulkanHandles.h b/system/vulkan_enc/VulkanHandles.h
index 78f346e..9341085 100644
--- a/system/vulkan_enc/VulkanHandles.h
+++ b/system/vulkan_enc/VulkanHandles.h
@@ -38,6 +38,17 @@
 
 #endif // VK_NVX_device_generated_commands
 
+#ifdef VK_USE_PLATFORM_FUCHSIA
+
+#define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
+    f(VkBufferCollectionFUCHSIA)
+
+#else
+
+#define __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f)
+
+#endif  // VK_USE_PLATFORM_FUCHSIA
+
 #define GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
     f(VkBufferView) \
     f(VkImageView) \
@@ -71,6 +82,7 @@
     f(VkDescriptorSet) \
     f(VkDescriptorSetLayout) \
     f(VkCommandPool) \
+    __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \
     GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) \
 
 #define GOLDFISH_VK_LIST_HANDLE_TYPES(f) \
diff --git a/system/vulkan_enc/VulkanStreamGuest.h b/system/vulkan_enc/VulkanStreamGuest.h
index 66eded0..6d2dac1 100644
--- a/system/vulkan_enc/VulkanStreamGuest.h
+++ b/system/vulkan_enc/VulkanStreamGuest.h
@@ -78,7 +78,6 @@
     uint8_t* reserve(size_t size);
 private:
     android::base::BumpPool mPool;
-    size_t mWritePos = 0;
     std::vector<uint8_t> mWriteBuffer;
     IOStream* mStream = nullptr;
     DefaultHandleMapping mDefaultHandleMapping;