[vulkan] VK_ANDROID_native_buffer: encoder generation

bug: 111137294
bug: 119426975

This provides a mechanism for the encoder to do custom things in the
course of filling out the local copies to send over.

The first use case of this is to edit the local copy of any
VkNativeBufferANDROID extension struct so that instead of the full
native_handle we just pass the host ColorBuffer, and a custom wrapper
around the nativeFenceFd in vkAcquireImageANDROID so we can wait on it
in the guest.

Change-Id: Id5a2b9721287d9698460f1cb3847276438b22e13
diff --git a/registry/vulkan/xml/cereal/encoder.py b/registry/vulkan/xml/cereal/encoder.py
index c61d6b3..ec0359d 100644
--- a/registry/vulkan/xml/cereal/encoder.py
+++ b/registry/vulkan/xml/cereal/encoder.py
@@ -192,12 +192,34 @@
     cgen.stmt("%s->setHandleMapping(%s->unwrapMapping())" % (STREAM, RESOURCES))
 
     encodingParams = EncodingParameters(api)
+    for (_, localCopyParam) in encodingParams.localCopied:
+        cgen.stmt(cgen.makeRichCTypeDecl(localCopyParam))
+
+def emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen, customUnwrap=None):
+    encodingParams = EncodingParameters(api)
 
     for (origParam, localCopyParam) in encodingParams.localCopied:
-        cgen.stmt(cgen.makeRichCTypeDecl(localCopyParam))
-        emit_deepcopy(typeInfo, origParam, cgen)
-        if localCopyParam.typeName == "VkAllocationCallbacks":
-            cgen.stmt("%s = nullptr" % localCopyParam.paramName)
+        shouldCustomCopy = \
+            customUnwrap and \
+            origParam.paramName in customUnwrap and \
+            "copyOp" in customUnwrap[origParam.paramName]
+
+        if shouldCustomCopy:
+            customUnwrap[origParam.paramName]["copyOp"](cgen, origParam, localCopyParam)
+        else:
+            emit_deepcopy(typeInfo, origParam, cgen)
+
+    for (origParam, localCopyParam) in encodingParams.localCopied:
+        shouldCustomMap = \
+            customUnwrap and \
+            origParam.paramName in customUnwrap and \
+            "mapOp" in customUnwrap[origParam.paramName]
+
+        if shouldCustomMap:
+            customUnwrap[origParam.paramName]["mapOp"](cgen, origParam, localCopyParam)
+        else:
+            if localCopyParam.typeName == "VkAllocationCallbacks":
+                cgen.stmt("%s = nullptr" % localCopyParam.paramName)
 
     cgen.stmt("%s->rewind()" % COUNTING_STREAM)
     cgen.beginBlock()
@@ -268,6 +290,7 @@
 
 def emit_default_encoding(typeInfo, api, cgen):
     emit_parameter_encode_preamble_write(typeInfo, api, cgen)
+    emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
     emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
     emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
     emit_parameter_encode_read(typeInfo, api, cgen)
@@ -275,6 +298,8 @@
     emit_custom_create_destroy(typeInfo, api, cgen)
     emit_return(typeInfo, api, cgen)
 
+## Custom encoding definitions##################################################
+
 def emit_only_goldfish_custom(typeInfo, api, cgen):
     cgen.vkApiCall( \
         api,
@@ -283,10 +308,21 @@
             [p.paramName for p in api.parameters])
     emit_return(typeInfo, api, cgen)
 
-## Custom encoding definitions##################################################
+def emit_with_custom_unwrap(custom):
+    def call(typeInfo, api, cgen):
+        emit_parameter_encode_preamble_write(typeInfo, api, cgen)
+        emit_parameter_encode_copy_unwrap_count(
+            typeInfo, api, cgen, customUnwrap=custom)
+        emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
+        emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
+        emit_parameter_encode_read(typeInfo, api, cgen)
+        emit_return_unmarshal(typeInfo, api, cgen)
+        emit_return(typeInfo, api, cgen)
+    return call
 
 def encode_vkFlushMappedMemoryRanges(typeInfo, api, cgen):
     emit_parameter_encode_preamble_write(typeInfo, api, cgen)
+    emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
 
     def emit_flush_ranges(streamVar):
         cgen.beginFor("uint32_t i = 0", "i < memoryRangeCount", "++i")
@@ -319,6 +355,7 @@
 
 def encode_vkInvalidateMappedMemoryRanges(typeInfo, api, cgen):
     emit_parameter_encode_preamble_write(typeInfo, api, cgen)
+    emit_parameter_encode_copy_unwrap_count(typeInfo, api, cgen)
     emit_parameter_encode_write_packet_info(typeInfo, api, cgen)
     emit_parameter_encode_do_parameter_write(typeInfo, api, cgen)
     emit_parameter_encode_read(typeInfo, api, cgen)
@@ -346,6 +383,18 @@
 
     emit_return(typeInfo, api, cgen)
 
+def unwrap_VkNativeBufferANDROID():
+    def mapOp(cgen, orig, local):
+        cgen.stmt("goldfish_unwrap_VkNativeBufferANDROID(%s, %s)" %
+                  (orig.paramName, local.paramName))
+    return { "pCreateInfo" : { "mapOp" : mapOp } }
+
+def unwrap_vkAcquireImageANDROID_nativeFenceFd():
+    def mapOp(cgen, orig, local):
+        cgen.stmt("goldfish_unwrap_vkAcquireImageANDROID_nativeFenceFd(%s, &%s)" %
+                  (orig.paramName, local.paramName))
+    return { "nativeFenceFd" : { "mapOp" : mapOp } }
+
 custom_encodes = {
     "vkEnumerateInstanceVersion" : emit_only_goldfish_custom,
     "vkEnumerateDeviceExtensionProperties" : emit_only_goldfish_custom,
@@ -354,6 +403,8 @@
     "vkUnmapMemory" : emit_only_goldfish_custom,
     "vkFlushMappedMemoryRanges" : encode_vkFlushMappedMemoryRanges,
     "vkInvalidateMappedMemoryRanges" : encode_vkInvalidateMappedMemoryRanges,
+    "vkCreateImage" : emit_with_custom_unwrap(unwrap_VkNativeBufferANDROID()),
+    "vkAcquireImageANDROID" : emit_with_custom_unwrap(unwrap_vkAcquireImageANDROID_nativeFenceFd()),
 }
 
 class VulkanEncoder(VulkanWrapperGenerator):
diff --git a/registry/vulkan/xml/cerealgenerator.py b/registry/vulkan/xml/cerealgenerator.py
index 104de99..39b80e1 100644
--- a/registry/vulkan/xml/cerealgenerator.py
+++ b/registry/vulkan/xml/cerealgenerator.py
@@ -158,6 +158,12 @@
     ResourceTracker.cpp \\
     %s
 
+ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
+$(call emugl-export,SHARED_LIBRARIES,libgui)
+else
+$(call emugl-export,SHARED_LIBRARIES,libsync)
+endif
+
 $(call emugl-end-module)
 """% (autogeneratedMkTemplate % banner_command(sys.argv), cppFiles)