loader: ghlvl 361, Simplify library resource handling

Layer and ICD libraries are opened and closed as needed. No ref counting,
no knowledge of if a library contains multiple layers or ICDs.

Change-Id: Ie88b671cd1671187a42d3d838d20e3af1afc67cc
diff --git a/loader/loader.c b/loader/loader.c
index 6f82723..b852f9e 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -52,13 +52,6 @@
 #endif
 #endif
 
-static loader_platform_dl_handle
-loader_add_layer_lib(const struct loader_instance *inst, const char *chain_type,
-                     struct loader_layer_properties *layer_prop);
-
-static void loader_remove_layer_lib(struct loader_instance *inst,
-                                    struct loader_layer_properties *layer_prop);
-
 struct loader_struct loader = {0};
 // TLS for instance for alloc/free callbacks
 THREAD_LOCAL_DECL struct loader_instance *tls_instance;
@@ -900,73 +893,6 @@
 }
 
 /*
- * Manage list of layer libraries (loader_lib_info)
- */
-static bool
-loader_init_layer_library_list(const struct loader_instance *inst,
-                               struct loader_layer_library_list *list) {
-    list->capacity = 32 * sizeof(struct loader_lib_info);
-    list->list = loader_heap_alloc(inst, list->capacity,
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (list->list == NULL) {
-        return false;
-    }
-    memset(list->list, 0, list->capacity);
-    list->count = 0;
-    return true;
-}
-
-void loader_destroy_layer_library_list(const struct loader_instance *inst,
-                                       struct loader_layer_library_list *list) {
-    for (uint32_t i = 0; i < list->count; i++) {
-        loader_heap_free(inst, list->list[i].lib_name);
-    }
-    loader_heap_free(inst, list->list);
-    list->count = 0;
-    list->capacity = 0;
-}
-
-void loader_add_to_layer_library_list(const struct loader_instance *inst,
-                                      struct loader_layer_library_list *list,
-                                      uint32_t item_count,
-                                      const struct loader_lib_info *new_items) {
-    uint32_t i;
-    struct loader_lib_info *item;
-
-    if (list->list == NULL || list->capacity == 0) {
-        loader_init_layer_library_list(inst, list);
-    }
-
-    if (list->list == NULL)
-        return;
-
-    for (i = 0; i < item_count; i++) {
-        item = (struct loader_lib_info *)&new_items[i];
-
-        // look for duplicates
-        for (uint32_t j = 0; j < list->count; j++) {
-            if (strcmp(list->list[i].lib_name, new_items->lib_name) == 0) {
-                continue;
-            }
-        }
-
-        // add to list at end
-        // check for enough capacity
-        if (list->count * sizeof(struct loader_lib_info) >= list->capacity) {
-
-            list->list = loader_heap_realloc(
-                inst, list->list, list->capacity, list->capacity * 2,
-                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-            // double capacity
-            list->capacity *= 2;
-        }
-
-        memcpy(&list->list[list->count], item, sizeof(struct loader_lib_info));
-        list->count++;
-    }
-}
-
-/*
  * Search the given layer list for a list
  * matching the given VkLayerProperties
  */
@@ -1166,7 +1092,7 @@
 static void loader_destroy_logical_device(const struct loader_instance *inst,
                                           struct loader_device *dev) {
     loader_heap_free(inst, dev->app_extension_props);
-    loader_destroy_layer_list(inst, &dev->activated_layer_list);
+    loader_deactivate_layers(inst, &dev->activated_layer_list);
     loader_heap_free(inst, dev);
 }
 
@@ -1293,9 +1219,8 @@
     PFN_vkGetInstanceProcAddr fp_get_proc_addr;
     struct loader_scanned_icds *new_node;
 
-    /* TODO implement ref counting of libraries, for now this function leaves
-       libraries open and the scanned_icd_clear closes them */
-    // Used to call: dlopen(filename, RTLD_LAZY);
+    /* TODO implement smarter opening/closing of libraries. For now this
+     * function leaves libraries open and the scanned_icd_clear closes them */
     handle = loader_platform_open_library(filename);
     if (!handle) {
         loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
@@ -2565,20 +2490,6 @@
     if (manifest_files[0].count == 0 && manifest_files[1].count == 0)
         return;
 
-#if 0 // TODO
-    /**
-     * We need a list of the layer libraries, not just a list of
-     * the layer properties (a layer library could expose more than
-     * one layer property). This list of scanned layers would be
-     * used to check for global and physicaldevice layer properties.
-     */
-    if (!loader_init_layer_library_list(&loader.scanned_layer_libraries)) {
-        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                   "Alloc for layer list failed: %s line: %d", __FILE__, __LINE__);
-        return;
-    }
-#endif
-
     /* cleanup any previously scanned libraries */
     loader_delete_layer_properties(inst, instance_layers);
     loader_delete_layer_properties(inst, device_layers);
@@ -2985,132 +2896,43 @@
 }
 
 static loader_platform_dl_handle
-loader_add_layer_lib(const struct loader_instance *inst, const char *chain_type,
-                     struct loader_layer_properties *layer_prop) {
-    struct loader_lib_info *new_layer_lib_list, *my_lib;
-    size_t new_alloc_size;
-    /*
-     * TODO: We can now track this information in the
-     * scanned_layer_libraries list.
-     */
-    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
-        if (strcmp(loader.loaded_layer_lib_list[i].lib_name,
-                   layer_prop->lib_name) == 0) {
-            /* Have already loaded this library, just increment ref count */
-            loader.loaded_layer_lib_list[i].ref_count++;
-            loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-                       "%s Chain: Increment layer reference count for layer "
-                       "library %s",
-                       chain_type, layer_prop->lib_name);
-            return loader.loaded_layer_lib_list[i].lib_handle;
-        }
-    }
+loader_open_layer_lib(const struct loader_instance *inst, const char *chain_type,
+                     struct loader_layer_properties *prop) {
 
-    /* Haven't seen this library so load it */
-    new_alloc_size = 0;
-    if (loader.loaded_layer_lib_capacity == 0)
-        new_alloc_size = 8 * sizeof(struct loader_lib_info);
-    else if (loader.loaded_layer_lib_capacity <=
-             loader.loaded_layer_lib_count * sizeof(struct loader_lib_info))
-        new_alloc_size = loader.loaded_layer_lib_capacity * 2;
-
-    if (new_alloc_size) {
-        new_layer_lib_list = loader_heap_realloc(
-            inst, loader.loaded_layer_lib_list,
-            loader.loaded_layer_lib_capacity, new_alloc_size,
-            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-        if (!new_layer_lib_list) {
-            loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                       "loader: realloc failed in loader_add_layer_lib");
-            return NULL;
-        }
-        loader.loaded_layer_lib_capacity = new_alloc_size;
-        loader.loaded_layer_lib_list = new_layer_lib_list;
-    } else
-        new_layer_lib_list = loader.loaded_layer_lib_list;
-    my_lib = &new_layer_lib_list[loader.loaded_layer_lib_count];
-
-    strncpy(my_lib->lib_name, layer_prop->lib_name, sizeof(my_lib->lib_name));
-    my_lib->lib_name[sizeof(my_lib->lib_name) - 1] = '\0';
-    my_lib->ref_count = 0;
-    my_lib->lib_handle = NULL;
-
-    if ((my_lib->lib_handle = loader_platform_open_library(my_lib->lib_name)) ==
+    if ((prop->lib_handle = loader_platform_open_library(prop->lib_name)) ==
         NULL) {
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                   loader_platform_open_library_error(my_lib->lib_name));
-        return NULL;
+                   loader_platform_open_library_error(prop->lib_name));
     } else {
         loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
                    "Chain: %s: Loading layer library %s", chain_type,
-                   layer_prop->lib_name);
+                   prop->lib_name);
     }
-    loader.loaded_layer_lib_count++;
-    my_lib->ref_count++;
 
-    return my_lib->lib_handle;
+    return prop->lib_handle;
 }
 
 static void
-loader_remove_layer_lib(struct loader_instance *inst,
-                        struct loader_layer_properties *layer_prop) {
-    uint32_t idx = loader.loaded_layer_lib_count;
-    struct loader_lib_info *new_layer_lib_list, *my_lib = NULL;
+loader_close_layer_lib(const struct loader_instance *inst,
+                        struct loader_layer_properties *prop) {
 
-    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
-        if (strcmp(loader.loaded_layer_lib_list[i].lib_name,
-                   layer_prop->lib_name) == 0) {
-            /* found matching library */
-            idx = i;
-            my_lib = &loader.loaded_layer_lib_list[i];
-            break;
-        }
+    if (prop->lib_handle) {
+        loader_platform_close_library(prop->lib_handle);
+        loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+                   "Unloading layer library %s", prop->lib_name);
+        prop->lib_handle = NULL;
     }
+}
 
-    if (idx == loader.loaded_layer_lib_count) {
-        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                   "Unable to unref library %s", layer_prop->lib_name);
-        return;
-    }
+void loader_deactivate_layers(const struct loader_instance *instance,
+                              struct loader_layer_list *list) {
+    /* delete instance list of enabled layers and close any layer libraries */
+    for (uint32_t i = 0; i < list->count; i++) {
+        struct loader_layer_properties *layer_prop = &list->list[i];
 
-    if (my_lib) {
-        my_lib->ref_count--;
-        if (my_lib->ref_count > 0) {
-            loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-                       "Decrement reference count for layer library %s",
-                       layer_prop->lib_name);
-            return;
-        }
+        loader_close_layer_lib(instance, layer_prop);
     }
-    loader_platform_close_library(my_lib->lib_handle);
-    loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
-               "Unloading layer library %s", layer_prop->lib_name);
-
-    /* Need to remove unused library from list */
-    new_layer_lib_list =
-        loader_heap_alloc(inst, loader.loaded_layer_lib_capacity,
-                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (!new_layer_lib_list) {
-        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
-                   "loader: heap alloc failed loader_remove_layer_library");
-        return;
-    }
-
-    if (idx > 0) {
-        /* Copy records before idx */
-        memcpy(new_layer_lib_list, &loader.loaded_layer_lib_list[0],
-               sizeof(struct loader_lib_info) * idx);
-    }
-    if (idx < (loader.loaded_layer_lib_count - 1)) {
-        /* Copy records after idx */
-        memcpy(&new_layer_lib_list[idx], &loader.loaded_layer_lib_list[idx + 1],
-               sizeof(struct loader_lib_info) *
-                   (loader.loaded_layer_lib_count - idx - 1));
-    }
-
-    loader_heap_free(inst, loader.loaded_layer_lib_list);
-    loader.loaded_layer_lib_count--;
-    loader.loaded_layer_lib_list = new_layer_lib_list;
+    loader_destroy_layer_list(instance, list);
 }
 
 /**
@@ -3209,17 +3031,6 @@
     return;
 }
 
-void loader_deactivate_instance_layers(struct loader_instance *instance) {
-    /* Create instance chain of enabled layers */
-    for (uint32_t i = 0; i < instance->activated_layer_list.count; i++) {
-        struct loader_layer_properties *layer_prop =
-            &instance->activated_layer_list.list[i];
-
-        loader_remove_layer_lib(instance, layer_prop);
-    }
-    loader_destroy_layer_list(instance, &instance->activated_layer_list);
-}
-
 VkResult
 loader_enable_instance_layers(struct loader_instance *inst,
                               const VkInstanceCreateInfo *pCreateInfo,
@@ -3306,7 +3117,7 @@
                 &inst->activated_layer_list.list[i];
             loader_platform_dl_handle lib_handle;
 
-            lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
+            lib_handle = loader_open_layer_lib(inst, "instance", layer_prop);
             if (!lib_handle)
                 continue;
             if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) ==
@@ -3460,7 +3271,7 @@
                 &dev->activated_layer_list.list[i];
             loader_platform_dl_handle lib_handle;
 
-            lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
+            lib_handle = loader_open_layer_lib(inst, "device", layer_prop);
             if (!lib_handle)
                 continue;
             if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) ==
diff --git a/loader/loader.h b/loader/loader.h
index 84659bb..9411c20 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -112,12 +112,6 @@
     char value[MAX_STRING_SIZE];
 };
 
-struct loader_lib_info {
-    char lib_name[MAX_STRING_SIZE];
-    uint32_t ref_count;
-    loader_platform_dl_handle lib_handle;
-};
-
 struct loader_layer_functions {
     char str_gipa[MAX_STRING_SIZE];
     char str_gdpa[MAX_STRING_SIZE];
@@ -129,6 +123,7 @@
     VkLayerProperties info;
     enum layer_type type;
     char lib_name[MAX_STRING_SIZE];
+    loader_platform_dl_handle lib_handle;
     struct loader_layer_functions functions;
     struct loader_extension_list instance_extension_list;
     struct loader_device_extension_list device_extension_list;
@@ -142,12 +137,6 @@
     struct loader_layer_properties *list;
 };
 
-struct loader_layer_library_list {
-    size_t capacity;
-    uint32_t count;
-    struct loader_lib_info *list;
-};
-
 struct loader_dispatch_hash_list {
     size_t capacity;
     uint32_t count;
@@ -341,13 +330,6 @@
 
 struct loader_struct {
     struct loader_instance *instances;
-
-    unsigned int loaded_layer_lib_count;
-    size_t loaded_layer_lib_capacity;
-    struct loader_lib_info *loaded_layer_lib_list;
-    // TODO add ref counting of ICD libraries
-    // TODO use this struct loader_layer_library_list scanned_layer_libraries;
-    // TODO add list of icd libraries for ref counting them for closure
 };
 
 struct loader_scanned_icds {
@@ -510,6 +492,8 @@
 void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
 void *loader_get_dev_ext_trampoline(uint32_t index);
 struct loader_instance *loader_get_instance(const VkInstance instance);
+void loader_deactivate_layers(const struct loader_instance *instance,
+                              struct loader_layer_list *list);
 struct loader_device *
 loader_create_logical_device(const struct loader_instance *inst);
 void loader_add_logical_device(const struct loader_instance *inst,
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 53ad1cd..b481578 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -503,7 +503,7 @@
 
     disp->DestroyInstance(instance, pAllocator);
 
-    loader_deactivate_instance_layers(ptr_instance);
+    loader_deactivate_layers(ptr_instance, &ptr_instance->activated_layer_list);
     if (ptr_instance->phys_devs)
         loader_heap_free(ptr_instance, ptr_instance->phys_devs);
     if (callback_setup) {