layers: Migrate OT layer to use layer chassis

Add changes to support layer chassis-based build of the
object_tracker layer which replaces the legacy object-
tracker build, including cmake and Android updates.

Change-Id: If914cc3094fcf17b0f2e1002842d0b58b876d2b0
diff --git a/scripts/object_tracker_generator.py b/scripts/object_tracker_generator.py
index 3588c28..2ca353b 100644
--- a/scripts/object_tracker_generator.py
+++ b/scripts/object_tracker_generator.py
@@ -127,71 +127,38 @@
                  diagFile = sys.stdout):
         OutputGenerator.__init__(self, errFile, warnFile, diagFile)
         self.INDENT_SPACES = 4
-        self.intercepts = []
+        self.prototypes = []
         self.instance_extensions = []
         self.device_extensions = []
         # Commands which are not autogenerated but still intercepted
         self.no_autogen_list = [
             'vkDestroyInstance',
-            'vkDestroyDevice',
-            'vkUpdateDescriptorSets',
-            'vkDestroyDebugReportCallbackEXT',
-            'vkDebugReportMessageEXT',
-            'vkGetPhysicalDeviceQueueFamilyProperties',
-            'vkFreeCommandBuffers',
-            'vkDestroySwapchainKHR',
-            'vkDestroyDescriptorPool',
-            'vkDestroyCommandPool',
-            'vkGetPhysicalDeviceQueueFamilyProperties2',
-            'vkGetPhysicalDeviceQueueFamilyProperties2KHR',
-            'vkResetDescriptorPool',
-            'vkBeginCommandBuffer',
-            'vkCreateDebugReportCallbackEXT',
-            'vkEnumerateInstanceLayerProperties',
-            'vkEnumerateDeviceLayerProperties',
-            'vkEnumerateInstanceExtensionProperties',
-            'vkEnumerateDeviceExtensionProperties',
-            'vkCreateDevice',
             'vkCreateInstance',
             'vkEnumeratePhysicalDevices',
+            'vkGetPhysicalDeviceQueueFamilyProperties',
+            'vkGetPhysicalDeviceQueueFamilyProperties2',
+            'vkGetPhysicalDeviceQueueFamilyProperties2KHR',
+            'vkGetDeviceQueue',
+            'vkGetDeviceQueue2',
+            'vkCreateDescriptorSetLayout',
+            'vkDestroyDescriptorPool',
+            'vkDestroyCommandPool',
             'vkAllocateCommandBuffers',
             'vkAllocateDescriptorSets',
             'vkFreeDescriptorSets',
-            'vkCmdPushDescriptorSetKHR',
-            'vkDebugMarkerSetObjectNameEXT',
-            'vkGetPhysicalDeviceProcAddr',
-            'vkGetDeviceProcAddr',
-            'vkGetInstanceProcAddr',
-            'vkEnumerateInstanceExtensionProperties',
-            'vkEnumerateInstanceLayerProperties',
-            'vkEnumerateDeviceLayerProperties',
-            'vkGetDeviceProcAddr',
-            'vkGetInstanceProcAddr',
-            'vkEnumerateDeviceExtensionProperties',
-            'vk_layerGetPhysicalDeviceProcAddr',
-            'vkNegotiateLoaderLayerInterfaceVersion',
-            'vkCreateComputePipelines',
-            'vkGetDeviceQueue',
-            'vkGetDeviceQueue2',
-            'vkGetSwapchainImagesKHR',
-            'vkCreateDescriptorSetLayout',
+            'vkFreeCommandBuffers',
+            'vkUpdateDescriptorSets',
+            'vkBeginCommandBuffer',
             'vkGetDescriptorSetLayoutSupport',
             'vkGetDescriptorSetLayoutSupportKHR',
-            'vkCreateDebugUtilsMessengerEXT',
-            'vkDestroyDebugUtilsMessengerEXT',
-            'vkSubmitDebugUtilsMessageEXT',
-            'vkSetDebugUtilsObjectNameEXT',
-            'vkSetDebugUtilsObjectTagEXT',
-            'vkQueueBeginDebugUtilsLabelEXT',
-            'vkQueueEndDebugUtilsLabelEXT',
-            'vkQueueInsertDebugUtilsLabelEXT',
-            'vkCmdBeginDebugUtilsLabelEXT',
-            'vkCmdEndDebugUtilsLabelEXT',
-            'vkCmdInsertDebugUtilsLabelEXT',
-            'vkGetDisplayModePropertiesKHR',
+            'vkDestroySwapchainKHR',
+            'vkGetSwapchainImagesKHR',
+            'vkCmdPushDescriptorSetKHR',
+            'vkDestroyDevice',
+            'vkResetDescriptorPool',
             'vkGetPhysicalDeviceDisplayPropertiesKHR',
             'vkGetPhysicalDeviceDisplayProperties2KHR',
-            'vkGetDisplayPlaneSupportedDisplaysKHR',
+            'vkGetDisplayModePropertiesKHR',
             'vkGetDisplayModeProperties2KHR',
             ]
         # These VUIDS are not implicit, but are best handled in this layer. Codegen for vkDestroy calls will generate a key
@@ -326,7 +293,7 @@
     # Generate the object tracker undestroyed object validation function
     def GenReportFunc(self):
         output_func = ''
-        output_func += 'bool ReportUndestroyedObjects(VkDevice device, const std::string& error_code) {\n'
+        output_func += 'bool ObjectLifetimes::ReportUndestroyedObjects(VkDevice device, const std::string& error_code) {\n'
         output_func += '    bool skip = false;\n'
         output_func += '    skip |= DeviceReportUndestroyedObjects(device, kVulkanObjectTypeCommandBuffer, error_code);\n'
         for handle in self.object_types:
@@ -340,7 +307,7 @@
     # Generate the object tracker undestroyed object destruction function
     def GenDestroyFunc(self):
         output_func = ''
-        output_func += 'void DestroyUndestroyedObjects(VkDevice device) {\n'
+        output_func += 'void ObjectLifetimes::DestroyUndestroyedObjects(VkDevice device) {\n'
         output_func += '    DeviceDestroyUndestroyedObjects(device, kVulkanObjectTypeCommandBuffer);\n'
         for handle in self.object_types:
             if self.isHandleTypeNonDispatchable(handle):
@@ -363,11 +330,11 @@
                         for s in self.ExtractVUIDs(l):
                             yield s
     #
-    # Separate content for validation (utils) and core files
+    # Separate content for validation source and header files
     def otwrite(self, dest, formatstring):
-        if 'core' in self.genOpts.filename and (dest == 'core' or dest == 'both'):
+        if 'object_tracker.h' in self.genOpts.filename and (dest == 'hdr' or dest == 'both'):
             write(formatstring, file=self.outFile)
-        elif 'utils' in self.genOpts.filename and (dest == 'util' or dest == 'both'):
+        elif 'object_tracker.cpp' in self.genOpts.filename and (dest == 'cpp' or dest == 'both'):
             write(formatstring, file=self.outFile)
 
     #
@@ -375,10 +342,10 @@
     def beginFile(self, genOpts):
         OutputGenerator.beginFile(self, genOpts)
 
-        core_file = (genOpts.filename == 'object_tracker_utils_auto.cpp')
-        utils_file = (genOpts.filename == 'object_tracker_core_auto.cpp')
+        header_file = (genOpts.filename == 'object_tracker.h')
+        source_file = (genOpts.filename == 'object_tracker.cpp')
 
-        if not core_file and not utils_file:
+        if not header_file and not source_file:
             print("Error: Output Filenames have changed, update generator source.\n")
             sys.exit(1)
 
@@ -427,15 +394,10 @@
         copyright += ' *\n'
         copyright += ' ****************************************************************************/\n'
         self.otwrite('both', copyright)
-        # Namespace
         self.newline()
-        self.otwrite('both', '#include "object_tracker.h"')
-        self.otwrite('both', '#include "object_lifetime_validation.h"')
-        self.otwrite('both', '\n')
-        self.otwrite('both', 'namespace object_tracker {')
-        self.otwrite('core', '#include "precall.h"')
-        self.otwrite('core', '#include "postcall.h"')
-        self.otwrite('core', '\n')
+        self.otwrite('cpp', '#include "chassis.h"')
+        self.otwrite('cpp', '#include "object_lifetime_validation.h"')
+        self.otwrite('cpp', '\n')
 
     #
     # Now that the data is all collected and complete, generate and output the object validation routines
@@ -449,10 +411,10 @@
         self.newline()
         # Build undestroyed objects destruction function
         destroy_func = self.GenDestroyFunc()
-        self.otwrite('util', '\n')
-        self.otwrite('util', '// ObjectTracker undestroyed objects validation function')
-        self.otwrite('util', '%s' % report_func)
-        self.otwrite('util', '%s' % destroy_func)
+        self.otwrite('cpp', '\n')
+        self.otwrite('cpp', '// ObjectTracker undestroyed objects validation function')
+        self.otwrite('cpp', '%s' % report_func)
+        self.otwrite('cpp', '%s' % destroy_func)
         # Actually write the interface to the output file.
         if (self.emit):
             self.newline()
@@ -469,14 +431,18 @@
             else:
                 self.otwrite('both', '\n')
 
-        # Record intercepted procedures
-        self.otwrite('core', '// Map of all APIs to be intercepted by this layer')
-        self.otwrite('core', 'const std::unordered_map<std::string, void*> name_to_funcptr_map = {')
-        intercepts = '\n'.join(self.intercepts)
-        self.otwrite('core', '%s' % intercepts)
-        self.otwrite('core', '};\n\n')
-        self.otwrite('both', '} // namespace object_tracker')
-        # Finish processing in superclass
+
+        self.otwrite('hdr', 'void PostCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator);')
+        self.otwrite('hdr', 'void PreCallRecordResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags);')
+        self.otwrite('hdr', 'void PostCallRecordGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties *pQueueFamilyProperties);')
+        self.otwrite('hdr', 'void PreCallRecordFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);')
+        self.otwrite('hdr', 'void PreCallRecordFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets);')
+        self.otwrite('hdr', 'void PostCallRecordGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties);')
+        self.otwrite('hdr', 'void PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties);')
+        self.otwrite('hdr', 'void PostCallRecordGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPropertiesKHR *pProperties);')
+        self.otwrite('hdr', 'void PostCallRecordGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties);')
+        self.otwrite('hdr', 'void PostCallRecordGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayProperties2KHR *pProperties);')
+        self.otwrite('hdr', 'void PostCallRecordGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t *pPropertyCount, VkDisplayModeProperties2KHR *pProperties);')
         OutputGenerator.endFile(self)
     #
     # Processing point at beginning of each extension definition
@@ -713,6 +679,7 @@
     def generate_create_object_code(self, indent, proto, params, cmd_info, allocator):
         create_obj_code = ''
         handle_type = params[-1].find('type')
+
         if self.isHandleTypeObject(handle_type.text):
             # Check for special case where multiple handles are returned
             object_array = False
@@ -721,7 +688,10 @@
             handle_name = params[-1].find('name')
             object_dest = '*%s' % handle_name.text
             if object_array == True:
-                create_obj_code += '%sfor (uint32_t index = 0; index < %s; index++) {\n' % (indent, cmd_info[-1].len)
+                countispointer = ''
+                if 'uint32_t*' in cmd_info[-2].cdecl:
+                    countispointer = '*'
+                create_obj_code += '%sfor (uint32_t index = 0; index < %s%s; index++) {\n' % (indent, countispointer, cmd_info[-1].len)
                 indent = self.incIndent(indent)
                 object_dest = '%s[index]' % cmd_info[-1].name
 
@@ -942,29 +912,21 @@
             cmdinfo = cmddata.cmdinfo
             if cmdname in self.interface_functions:
                 continue
+            manual = False
             if cmdname in self.no_autogen_list:
-                if 'core' in self.genOpts.filename:
-                    decls = self.makeCDecls(cmdinfo.elem)
-                    self.appendSection('command', '')
-                    self.appendSection('command', '// Declare only')
-                    self.appendSection('command', decls[0])
-                    self.intercepts += [ '    {"%s", (void *)%s},' % (cmdname,cmdname[2:]) ]
-                continue
+                manual = True
+
             # Generate object handling code
             (pre_call_validate, pre_call_record, post_call_record) = self.generate_wrapping_code(cmdinfo.elem)
 
-            # If API doesn't contain any object handles, don't fool with it
-            if not pre_call_validate and not pre_call_record and not post_call_record:
-                continue
-
             feature_extra_protect = cmddata.extra_protect
             if (feature_extra_protect is not None):
                 self.appendSection('command', '')
                 self.appendSection('command', '#ifdef '+ feature_extra_protect)
-                self.intercepts += [ '#ifdef %s' % feature_extra_protect ]
+                self.prototypes += [ '#ifdef %s' % feature_extra_protect ]
 
             # Add intercept to procmap
-            self.intercepts += [ '    {"%s", (void*)%s},' % (cmdname,cmdname[2:]) ]
+            self.prototypes += [ '    {"%s", (void*)%s},' % (cmdname,cmdname[2:]) ]
 
             decls = self.makeCDecls(cmdinfo.elem)
 
@@ -976,12 +938,28 @@
             fcn_call = cmdinfo.elem.attrib.get('name').replace('vk', 'TOKEN', 1) + '(' + paramstext + ');'
 
             func_decl_template = decls[0][:-1].split('VKAPI_CALL ')
-            func_decl_template = func_decl_template[1] + ' {'
+            func_decl_template = func_decl_template[1]
 
-            if 'utils' in self.genOpts.filename:
-                # Output PreCallValidateAPI function if necessary
+            if 'object_tracker.h' in self.genOpts.filename:
+                # Output PreCallValidateAPI prototype if necessary
                 if pre_call_validate:
-                    pre_cv_func_decl = 'bool PreCallValidate' + func_decl_template
+                    pre_cv_func_decl = 'bool PreCallValidate' + func_decl_template + ';'
+                    self.appendSection('command', pre_cv_func_decl)
+
+                # Output PreCallRecordAPI prototype if necessary
+                if pre_call_record:
+                    pre_cr_func_decl = 'void PreCallRecord' + func_decl_template + ';'
+                    self.appendSection('command', pre_cr_func_decl)
+
+                # Output PosCallRecordAPI prototype if necessary
+                if post_call_record:
+                    post_cr_func_decl = 'void PostCallRecord' + func_decl_template + ';'
+                    self.appendSection('command', post_cr_func_decl)
+
+            if 'object_tracker.cpp' in self.genOpts.filename:
+                # Output PreCallValidateAPI function if necessary
+                if pre_call_validate and not manual:
+                    pre_cv_func_decl = 'bool ObjectLifetimes::PreCallValidate' + func_decl_template + ' {'
                     self.appendSection('command', '')
                     self.appendSection('command', pre_cv_func_decl)
                     self.appendSection('command', '    bool skip = false;')
@@ -990,93 +968,21 @@
                     self.appendSection('command', '}')
 
                 # Output PreCallRecordAPI function if necessary
-                if pre_call_record:
-                    pre_cr_func_decl = 'void PreCallRecord' + func_decl_template
+                if pre_call_record and not manual:
+                    pre_cr_func_decl = 'void ObjectLifetimes::PreCallRecord' + func_decl_template + ' {'
                     self.appendSection('command', '')
                     self.appendSection('command', pre_cr_func_decl)
                     self.appendSection('command', pre_call_record)
                     self.appendSection('command', '}')
 
                 # Output PosCallRecordAPI function if necessary
-                if post_call_record:
-                    post_cr_func_decl = 'void PostCallRecord' + func_decl_template
+                if post_call_record and not manual:
+                    post_cr_func_decl = 'void ObjectLifetimes::PostCallRecord' + func_decl_template + ' {'
                     self.appendSection('command', '')
                     self.appendSection('command', post_cr_func_decl)
                     self.appendSection('command', post_call_record)
                     self.appendSection('command', '}')
 
-            if 'core' in self.genOpts.filename:
-                # Output API function:
-                self.appendSection('command', '')
-                self.appendSection('command', decls[0][:-1])
-                self.appendSection('command', '{')
-
-                # Handle return values, if any
-                resulttype = cmdinfo.elem.find('proto/type')
-                if (resulttype is not None and resulttype.text == 'void'):
-                  resulttype = None
-                if (resulttype is not None):
-                    assignresult = resulttype.text + ' result = '
-                else:
-                    assignresult = ''
-
-                # Output all pre-API-call source
-                if pre_call_validate:
-                    self.appendSection('command', '    bool skip = false;')
-                if pre_call_validate or pre_call_record:
-                    self.appendSection('command', '    {')
-                    self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
-                # If necessary, add call to PreCallValidateApi(...);
-                if pre_call_validate:
-                    pcv_call = fcn_call.replace('TOKEN', '        skip |= PreCallValidate', 1)
-                    self.appendSection('command', pcv_call)
-                    if assignresult != '':
-                        if resulttype.text == 'VkResult':
-                            self.appendSection('command', '        if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;')
-                        elif resulttype.text == 'VkBool32':
-                            self.appendSection('command', '        if (skip) return VK_FALSE;')
-                        else:
-                            raise Exception('Unknown result type ' + resulttype.text)
-                    else:
-                        self.appendSection('command', '        if (skip) return;')
-                # If necessary, add call to PreCallRecordApi(...);
-                if pre_call_record:
-                    pre_cr_call = fcn_call.replace('TOKEN', '        PreCallRecord', 1)
-                    self.appendSection('command', pre_cr_call)
-
-                if pre_call_validate or pre_call_record:
-                    self.appendSection('command', '    }')
-
-                # Build down-chain call strings and output source
-                # Use correct dispatch table
-                disp_name = cmdinfo.elem.find('param/name').text
-                disp_type = cmdinfo.elem.find('param/type').text
-                map_type = ''
-                if disp_type in ["VkInstance", "VkPhysicalDevice"] or cmdname == 'vkCreateInstance':
-                    object_type = 'instance'
-                    map_type = 'instance_'
-                else:
-                    object_type = 'device'
-                dispatch_table = 'GetLayerDataPtr(get_dispatch_key(%s), %slayer_data_map)->%s_dispatch_table.' % (disp_name, map_type, object_type)
-                down_chain_call = fcn_call.replace('TOKEN', dispatch_table, 1)
-                self.appendSection('command', '    ' + assignresult + down_chain_call)
-
-                # If necessary, add call to PostCallRecordApi(...);
-                if post_call_record:
-                    if assignresult:
-                        if resulttype.text == 'VkResult':
-                            self.appendSection('command', '    if (VK_SUCCESS == result) {')
-                        elif resulttype.text == 'VkBool32':
-                            self.appendSection('command', '    if (VK_TRUE == result) {')
-                    self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
-                    post_cr_call = fcn_call.replace('TOKEN', '        PostCallRecord', 1)
-                    self.appendSection('command', post_cr_call)
-                    self.appendSection('command', '    }')
-
-                # Handle the return result variable, if any
-                if (resulttype is not None):
-                    self.appendSection('command', '    return result;')
-                self.appendSection('command', '}')
             if (feature_extra_protect is not None):
                 self.appendSection('command', '#endif // '+ feature_extra_protect)
-                self.intercepts += [ '#endif' ]
+                self.prototypes += [ '#endif' ]