/*
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// The API layer of the loader defines Vulkan API and manages layers.  The
// entrypoints are generated and defined in api_dispatch.cpp.  Most of them
// simply find the dispatch table and jump.
//
// There are a few of them requiring manual code for things such as layer
// discovery or chaining.  They call into functions defined in this file.

#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <mutex>
#include <new>
#include <utility>
#include <cutils/properties.h>
#include <log/log.h>

#include <vulkan/vk_layer_interface.h>
#include "api.h"
#include "driver.h"
#include "loader.h"

namespace vulkan {
namespace api {

namespace {

// Provide overridden layer names when there are implicit layers.  No effect
// otherwise.
class OverrideLayerNames {
   public:
    OverrideLayerNames(bool is_instance, const VkAllocationCallbacks& allocator)
        : is_instance_(is_instance),
          allocator_(allocator),
          scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
          names_(nullptr),
          name_count_(0),
          implicit_layers_() {
        implicit_layers_.result = VK_SUCCESS;
    }

    ~OverrideLayerNames() {
        allocator_.pfnFree(allocator_.pUserData, names_);
        allocator_.pfnFree(allocator_.pUserData, implicit_layers_.elements);
        allocator_.pfnFree(allocator_.pUserData, implicit_layers_.name_pool);
    }

    VkResult parse(const char* const* names, uint32_t count) {
        add_implicit_layers();

        const auto& arr = implicit_layers_;
        if (arr.result != VK_SUCCESS)
            return arr.result;

        // no need to override when there is no implicit layer
        if (!arr.count)
            return VK_SUCCESS;

        names_ = allocate_name_array(arr.count + count);
        if (!names_)
            return VK_ERROR_OUT_OF_HOST_MEMORY;

        // add implicit layer names
        for (uint32_t i = 0; i < arr.count; i++)
            names_[i] = get_implicit_layer_name(i);

        name_count_ = arr.count;

        // add explicit layer names
        for (uint32_t i = 0; i < count; i++) {
            // ignore explicit layers that are also implicit
            if (is_implicit_layer(names[i]))
                continue;

            names_[name_count_++] = names[i];
        }

        return VK_SUCCESS;
    }

    const char* const* names() const { return names_; }

    uint32_t count() const { return name_count_; }

   private:
    struct ImplicitLayer {
        int priority;
        size_t name_offset;
    };

    struct ImplicitLayerArray {
        ImplicitLayer* elements;
        uint32_t max_count;
        uint32_t count;

        char* name_pool;
        size_t max_pool_size;
        size_t pool_size;

        VkResult result;
    };

    void add_implicit_layers() {
        if (!driver::Debuggable())
            return;

        parse_debug_vulkan_layers();
        property_list(parse_debug_vulkan_layer, this);

        // sort by priorities
        auto& arr = implicit_layers_;
        std::sort(arr.elements, arr.elements + arr.count,
                  [](const ImplicitLayer& a, const ImplicitLayer& b) {
                      return (a.priority < b.priority);
                  });
    }

    void parse_debug_vulkan_layers() {
        // debug.vulkan.layers specifies colon-separated layer names
        char prop[PROPERTY_VALUE_MAX];
        if (!property_get("debug.vulkan.layers", prop, ""))
            return;

        // assign negative/high priorities to them
        int prio = -PROPERTY_VALUE_MAX;

        const char* p = prop;
        const char* delim;
        while ((delim = strchr(p, ':'))) {
            if (delim > p)
                add_implicit_layer(prio, p, static_cast<size_t>(delim - p));

            prio++;
            p = delim + 1;
        }

        if (p[0] != '\0')
            add_implicit_layer(prio, p, strlen(p));
    }

    static void parse_debug_vulkan_layer(const char* key,
                                         const char* val,
                                         void* user_data) {
        static const char prefix[] = "debug.vulkan.layer.";
        const size_t prefix_len = sizeof(prefix) - 1;

        if (strncmp(key, prefix, prefix_len) || val[0] == '\0')
            return;
        key += prefix_len;

        // debug.vulkan.layer.<priority>
        int priority = -1;
        if (key[0] >= '0' && key[0] <= '9')
            priority = atoi(key);

        if (priority < 0) {
            ALOGW("Ignored implicit layer %s with invalid priority %s", val,
                  key);
            return;
        }

        OverrideLayerNames& override_layers =
            *reinterpret_cast<OverrideLayerNames*>(user_data);
        override_layers.add_implicit_layer(priority, val, strlen(val));
    }

    void add_implicit_layer(int priority, const char* name, size_t len) {
        if (!grow_implicit_layer_array(1, 0))
            return;

        auto& arr = implicit_layers_;
        auto& layer = arr.elements[arr.count++];

        layer.priority = priority;
        layer.name_offset = add_implicit_layer_name(name, len);

        ALOGV("Added implicit layer %s",
              get_implicit_layer_name(arr.count - 1));
    }

    size_t add_implicit_layer_name(const char* name, size_t len) {
        if (!grow_implicit_layer_array(0, len + 1))
            return 0;

        // add the name to the pool
        auto& arr = implicit_layers_;
        size_t offset = arr.pool_size;
        char* dst = arr.name_pool + offset;

        std::copy(name, name + len, dst);
        dst[len] = '\0';

        arr.pool_size += len + 1;

        return offset;
    }

    bool grow_implicit_layer_array(uint32_t layer_count, size_t name_size) {
        const uint32_t initial_max_count = 16;
        const size_t initial_max_pool_size = 512;

        auto& arr = implicit_layers_;

        // grow the element array if needed
        while (arr.count + layer_count > arr.max_count) {
            uint32_t new_max_count =
                (arr.max_count) ? (arr.max_count << 1) : initial_max_count;
            void* new_mem = nullptr;

            if (new_max_count > arr.max_count) {
                new_mem = allocator_.pfnReallocation(
                    allocator_.pUserData, arr.elements,
                    sizeof(ImplicitLayer) * new_max_count,
                    alignof(ImplicitLayer), scope_);
            }

            if (!new_mem) {
                arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
                arr.count = 0;
                return false;
            }

            arr.elements = reinterpret_cast<ImplicitLayer*>(new_mem);
            arr.max_count = new_max_count;
        }

        // grow the name pool if needed
        while (arr.pool_size + name_size > arr.max_pool_size) {
            size_t new_max_pool_size = (arr.max_pool_size)
                                           ? (arr.max_pool_size << 1)
                                           : initial_max_pool_size;
            void* new_mem = nullptr;

            if (new_max_pool_size > arr.max_pool_size) {
                new_mem = allocator_.pfnReallocation(
                    allocator_.pUserData, arr.name_pool, new_max_pool_size,
                    alignof(char), scope_);
            }

            if (!new_mem) {
                arr.result = VK_ERROR_OUT_OF_HOST_MEMORY;
                arr.pool_size = 0;
                return false;
            }

            arr.name_pool = reinterpret_cast<char*>(new_mem);
            arr.max_pool_size = new_max_pool_size;
        }

        return true;
    }

    const char* get_implicit_layer_name(uint32_t index) const {
        const auto& arr = implicit_layers_;

        // this may return nullptr when arr.result is not VK_SUCCESS
        return implicit_layers_.name_pool + arr.elements[index].name_offset;
    }

    bool is_implicit_layer(const char* name) const {
        const auto& arr = implicit_layers_;

        for (uint32_t i = 0; i < arr.count; i++) {
            if (strcmp(name, get_implicit_layer_name(i)) == 0)
                return true;
        }

        return false;
    }

    const char** allocate_name_array(uint32_t count) const {
        return reinterpret_cast<const char**>(allocator_.pfnAllocation(
            allocator_.pUserData, sizeof(const char*) * count,
            alignof(const char*), scope_));
    }

    const bool is_instance_;
    const VkAllocationCallbacks& allocator_;
    const VkSystemAllocationScope scope_;

    const char** names_;
    uint32_t name_count_;

    ImplicitLayerArray implicit_layers_;
};

// Provide overridden extension names when there are implicit extensions.
// No effect otherwise.
//
// This is used only to enable VK_EXT_debug_report.
class OverrideExtensionNames {
   public:
    OverrideExtensionNames(bool is_instance,
                           const VkAllocationCallbacks& allocator)
        : is_instance_(is_instance),
          allocator_(allocator),
          scope_(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
          names_(nullptr),
          name_count_(0),
          install_debug_callback_(false) {}

    ~OverrideExtensionNames() {
        allocator_.pfnFree(allocator_.pUserData, names_);
    }

    VkResult parse(const char* const* names, uint32_t count) {
        // this is only for debug.vulkan.enable_callback
        if (!enable_debug_callback())
            return VK_SUCCESS;

        names_ = allocate_name_array(count + 1);
        if (!names_)
            return VK_ERROR_OUT_OF_HOST_MEMORY;

        std::copy(names, names + count, names_);

        name_count_ = count;
        names_[name_count_++] = "VK_EXT_debug_report";

        install_debug_callback_ = true;

        return VK_SUCCESS;
    }

    const char* const* names() const { return names_; }

    uint32_t count() const { return name_count_; }

    bool install_debug_callback() const { return install_debug_callback_; }

   private:
    bool enable_debug_callback() const {
        return (is_instance_ && driver::Debuggable() &&
                property_get_bool("debug.vulkan.enable_callback", false));
    }

    const char** allocate_name_array(uint32_t count) const {
        return reinterpret_cast<const char**>(allocator_.pfnAllocation(
            allocator_.pUserData, sizeof(const char*) * count,
            alignof(const char*), scope_));
    }

    const bool is_instance_;
    const VkAllocationCallbacks& allocator_;
    const VkSystemAllocationScope scope_;

    const char** names_;
    uint32_t name_count_;
    bool install_debug_callback_;
};

// vkCreateInstance and vkCreateDevice helpers with support for layer
// chaining.
class LayerChain {
   public:
    static VkResult create_instance(const VkInstanceCreateInfo* create_info,
                                    const VkAllocationCallbacks* allocator,
                                    VkInstance* instance_out);

    static VkResult create_device(VkPhysicalDevice physical_dev,
                                  const VkDeviceCreateInfo* create_info,
                                  const VkAllocationCallbacks* allocator,
                                  VkDevice* dev_out);

    static void destroy_instance(VkInstance instance,
                                 const VkAllocationCallbacks* allocator);

    static void destroy_device(VkDevice dev,
                               const VkAllocationCallbacks* allocator);

   private:
    struct ActiveLayer {
        LayerRef ref;
        union {
            VkLayerInstanceLink instance_link;
            VkLayerDeviceLink device_link;
        };
    };

    LayerChain(bool is_instance, const VkAllocationCallbacks& allocator);
    ~LayerChain();

    VkResult activate_layers(const char* const* layer_names,
                             uint32_t layer_count,
                             const char* const* extension_names,
                             uint32_t extension_count);
    ActiveLayer* allocate_layer_array(uint32_t count) const;
    VkResult load_layer(ActiveLayer& layer, const char* name);
    void setup_layer_links();

    bool empty() const;
    void modify_create_info(VkInstanceCreateInfo& info);
    void modify_create_info(VkDeviceCreateInfo& info);

    VkResult create(const VkInstanceCreateInfo* create_info,
                    const VkAllocationCallbacks* allocator,
                    VkInstance* instance_out);

    VkResult create(VkPhysicalDevice physical_dev,
                    const VkDeviceCreateInfo* create_info,
                    const VkAllocationCallbacks* allocator,
                    VkDevice* dev_out);

    template <typename DataType>
    void steal_layers(DataType& data);

    static void destroy_layers(ActiveLayer* layers,
                               uint32_t count,
                               const VkAllocationCallbacks& allocator);

    static VKAPI_ATTR VkBool32
    debug_report_callback(VkDebugReportFlagsEXT flags,
                          VkDebugReportObjectTypeEXT obj_type,
                          uint64_t obj,
                          size_t location,
                          int32_t msg_code,
                          const char* layer_prefix,
                          const char* msg,
                          void* user_data);

    const bool is_instance_;
    const VkAllocationCallbacks& allocator_;

    OverrideLayerNames override_layers_;
    OverrideExtensionNames override_extensions_;

    ActiveLayer* layers_;
    uint32_t layer_count_;

    PFN_vkGetInstanceProcAddr get_instance_proc_addr_;
    PFN_vkGetDeviceProcAddr get_device_proc_addr_;

    union {
        VkLayerInstanceCreateInfo instance_chain_info_;
        VkLayerDeviceCreateInfo device_chain_info_;
    };
};

LayerChain::LayerChain(bool is_instance, const VkAllocationCallbacks& allocator)
    : is_instance_(is_instance),
      allocator_(allocator),
      override_layers_(is_instance, allocator),
      override_extensions_(is_instance, allocator),
      layers_(nullptr),
      layer_count_(0),
      get_instance_proc_addr_(nullptr),
      get_device_proc_addr_(nullptr) {}

LayerChain::~LayerChain() {
    destroy_layers(layers_, layer_count_, allocator_);
}

VkResult LayerChain::activate_layers(const char* const* layer_names,
                                     uint32_t layer_count,
                                     const char* const* extension_names,
                                     uint32_t extension_count) {
    VkResult result = override_layers_.parse(layer_names, layer_count);
    if (result != VK_SUCCESS)
        return result;

    result = override_extensions_.parse(extension_names, extension_count);
    if (result != VK_SUCCESS)
        return result;

    if (override_layers_.count()) {
        layer_names = override_layers_.names();
        layer_count = override_layers_.count();
    }

    if (!layer_count) {
        // point head of chain to the driver
        get_instance_proc_addr_ = driver::GetInstanceProcAddr;
        if (!is_instance_)
            get_device_proc_addr_ = driver::GetDeviceProcAddr;

        return VK_SUCCESS;
    }

    layers_ = allocate_layer_array(layer_count);
    if (!layers_)
        return VK_ERROR_OUT_OF_HOST_MEMORY;

    // load layers
    for (uint32_t i = 0; i < layer_count; i++) {
        result = load_layer(layers_[i], layer_names[i]);
        if (result != VK_SUCCESS)
            return result;

        // count loaded layers for proper destructions on errors
        layer_count_++;
    }

    setup_layer_links();

    return VK_SUCCESS;
}

LayerChain::ActiveLayer* LayerChain::allocate_layer_array(
    uint32_t count) const {
    VkSystemAllocationScope scope = (is_instance_)
                                        ? VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
                                        : VK_SYSTEM_ALLOCATION_SCOPE_DEVICE;

    return reinterpret_cast<ActiveLayer*>(allocator_.pfnAllocation(
        allocator_.pUserData, sizeof(ActiveLayer) * count, alignof(ActiveLayer),
        scope));
}

VkResult LayerChain::load_layer(ActiveLayer& layer, const char* name) {
    if (is_instance_)
        new (&layer) ActiveLayer{GetInstanceLayerRef(name), {}};
    else
        new (&layer) ActiveLayer{GetDeviceLayerRef(name), {}};

    if (!layer.ref) {
        ALOGE("Failed to load layer %s", name);
        layer.ref.~LayerRef();
        return VK_ERROR_LAYER_NOT_PRESENT;
    }

    ALOGI("Loaded %s layer %s", (is_instance_) ? "instance" : "device", name);

    return VK_SUCCESS;
}

void LayerChain::setup_layer_links() {
    if (is_instance_) {
        for (uint32_t i = 0; i < layer_count_; i++) {
            ActiveLayer& layer = layers_[i];

            // point head of chain to the first layer
            if (i == 0)
                get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();

            // point tail of chain to the driver
            if (i == layer_count_ - 1) {
                layer.instance_link.pNext = nullptr;
                layer.instance_link.pfnNextGetInstanceProcAddr =
                    driver::GetInstanceProcAddr;
                break;
            }

            const ActiveLayer& next = layers_[i + 1];

            // const_cast as some naughty layers want to modify our links!
            layer.instance_link.pNext =
                const_cast<VkLayerInstanceLink*>(&next.instance_link);
            layer.instance_link.pfnNextGetInstanceProcAddr =
                next.ref.GetGetInstanceProcAddr();
        }
    } else {
        for (uint32_t i = 0; i < layer_count_; i++) {
            ActiveLayer& layer = layers_[i];

            // point head of chain to the first layer
            if (i == 0) {
                get_instance_proc_addr_ = layer.ref.GetGetInstanceProcAddr();
                get_device_proc_addr_ = layer.ref.GetGetDeviceProcAddr();
            }

            // point tail of chain to the driver
            if (i == layer_count_ - 1) {
                layer.device_link.pNext = nullptr;
                layer.device_link.pfnNextGetInstanceProcAddr =
                    driver::GetInstanceProcAddr;
                layer.device_link.pfnNextGetDeviceProcAddr =
                    driver::GetDeviceProcAddr;
                break;
            }

            const ActiveLayer& next = layers_[i + 1];

            // const_cast as some naughty layers want to modify our links!
            layer.device_link.pNext =
                const_cast<VkLayerDeviceLink*>(&next.device_link);
            layer.device_link.pfnNextGetInstanceProcAddr =
                next.ref.GetGetInstanceProcAddr();
            layer.device_link.pfnNextGetDeviceProcAddr =
                next.ref.GetGetDeviceProcAddr();
        }
    }
}

bool LayerChain::empty() const {
    return (!layer_count_ && !override_layers_.count() &&
            !override_extensions_.count());
}

void LayerChain::modify_create_info(VkInstanceCreateInfo& info) {
    if (layer_count_) {
        const ActiveLayer& layer = layers_[0];

        instance_chain_info_.sType =
            VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
        instance_chain_info_.function = VK_LAYER_FUNCTION_LINK;
        // TODO fix vk_layer_interface.h and get rid of const_cast?
        instance_chain_info_.u.pLayerInfo =
            const_cast<VkLayerInstanceLink*>(&layer.instance_link);

        // insert layer info
        instance_chain_info_.pNext = info.pNext;
        info.pNext = &instance_chain_info_;
    }

    if (override_layers_.count()) {
        info.enabledLayerCount = override_layers_.count();
        info.ppEnabledLayerNames = override_layers_.names();
    }

    if (override_extensions_.count()) {
        info.enabledExtensionCount = override_extensions_.count();
        info.ppEnabledExtensionNames = override_extensions_.names();
    }
}

void LayerChain::modify_create_info(VkDeviceCreateInfo& info) {
    if (layer_count_) {
        const ActiveLayer& layer = layers_[0];

        device_chain_info_.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
        device_chain_info_.function = VK_LAYER_FUNCTION_LINK;
        // TODO fix vk_layer_interface.h and get rid of const_cast?
        device_chain_info_.u.pLayerInfo =
            const_cast<VkLayerDeviceLink*>(&layer.device_link);

        // insert layer info
        device_chain_info_.pNext = info.pNext;
        info.pNext = &device_chain_info_;
    }

    if (override_layers_.count()) {
        info.enabledLayerCount = override_layers_.count();
        info.ppEnabledLayerNames = override_layers_.names();
    }

    if (override_extensions_.count()) {
        info.enabledExtensionCount = override_extensions_.count();
        info.ppEnabledExtensionNames = override_extensions_.names();
    }
}

VkResult LayerChain::create(const VkInstanceCreateInfo* create_info,
                            const VkAllocationCallbacks* allocator,
                            VkInstance* instance_out) {
    // call down the chain
    PFN_vkCreateInstance create_instance =
        reinterpret_cast<PFN_vkCreateInstance>(
            get_instance_proc_addr_(VK_NULL_HANDLE, "vkCreateInstance"));
    VkInstance instance;
    VkResult result = create_instance(create_info, allocator, &instance);
    if (result != VK_SUCCESS)
        return result;

    // initialize InstanceData
    InstanceData& data = GetData(instance);
    memset(&data, 0, sizeof(data));

    data.instance = instance;

    if (!InitDispatchTable(instance, get_instance_proc_addr_)) {
        if (data.dispatch.DestroyInstance)
            data.dispatch.DestroyInstance(instance, allocator);

        return VK_ERROR_INITIALIZATION_FAILED;
    }

    // install debug report callback
    if (override_extensions_.install_debug_callback()) {
        PFN_vkCreateDebugReportCallbackEXT create_debug_report_callback =
            reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(
                get_instance_proc_addr_(instance,
                                        "vkCreateDebugReportCallbackEXT"));
        data.destroy_debug_callback =
            reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
                get_instance_proc_addr_(instance,
                                        "vkDestroyDebugReportCallbackEXT"));
        if (!create_debug_report_callback || !data.destroy_debug_callback) {
            ALOGE("Broken VK_EXT_debug_report support");
            data.dispatch.DestroyInstance(instance, allocator);
            return VK_ERROR_INITIALIZATION_FAILED;
        }

        VkDebugReportCallbackCreateInfoEXT debug_callback_info = {};
        debug_callback_info.sType =
            VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
        debug_callback_info.flags =
            VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
        debug_callback_info.pfnCallback = debug_report_callback;

        VkDebugReportCallbackEXT debug_callback;
        result = create_debug_report_callback(instance, &debug_callback_info,
                                              nullptr, &debug_callback);
        if (result != VK_SUCCESS) {
            ALOGE("Failed to install debug report callback");
            data.dispatch.DestroyInstance(instance, allocator);
            return VK_ERROR_INITIALIZATION_FAILED;
        }

        data.debug_callback = debug_callback;

        ALOGI("Installed debug report callback");
    }

    steal_layers(data);

    *instance_out = instance;

    return VK_SUCCESS;
}

VkResult LayerChain::create(VkPhysicalDevice physical_dev,
                            const VkDeviceCreateInfo* create_info,
                            const VkAllocationCallbacks* allocator,
                            VkDevice* dev_out) {
    // call down the chain
    //
    // TODO Instance call chain available at
    // GetData(physical_dev).dispatch.CreateDevice is ignored.  Is that
    // right?
    VkInstance instance = GetData(physical_dev).instance;
    PFN_vkCreateDevice create_device = reinterpret_cast<PFN_vkCreateDevice>(
        get_instance_proc_addr_(instance, "vkCreateDevice"));
    VkDevice dev;
    VkResult result = create_device(physical_dev, create_info, allocator, &dev);
    if (result != VK_SUCCESS)
        return result;

    // initialize DeviceData
    DeviceData& data = GetData(dev);
    memset(&data, 0, sizeof(data));

    if (!InitDispatchTable(dev, get_device_proc_addr_)) {
        if (data.dispatch.DestroyDevice)
            data.dispatch.DestroyDevice(dev, allocator);

        return VK_ERROR_INITIALIZATION_FAILED;
    }

    steal_layers(data);

    *dev_out = dev;

    return VK_SUCCESS;
}

template <typename DataType>
void LayerChain::steal_layers(DataType& data) {
    data.layers = layers_;
    data.layer_count = layer_count_;

    layers_ = nullptr;
    layer_count_ = 0;
}

void LayerChain::destroy_layers(ActiveLayer* layers,
                                uint32_t count,
                                const VkAllocationCallbacks& allocator) {
    for (uint32_t i = 0; i < count; i++)
        layers[i].ref.~LayerRef();

    allocator.pfnFree(allocator.pUserData, layers);
}

VkBool32 LayerChain::debug_report_callback(VkDebugReportFlagsEXT flags,
                                           VkDebugReportObjectTypeEXT obj_type,
                                           uint64_t obj,
                                           size_t location,
                                           int32_t msg_code,
                                           const char* layer_prefix,
                                           const char* msg,
                                           void* user_data) {
    int prio;

    if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
        prio = ANDROID_LOG_ERROR;
    else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT |
                      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT))
        prio = ANDROID_LOG_WARN;
    else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
        prio = ANDROID_LOG_INFO;
    else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
        prio = ANDROID_LOG_DEBUG;
    else
        prio = ANDROID_LOG_UNKNOWN;

    LOG_PRI(prio, LOG_TAG, "[%s] Code %d : %s", layer_prefix, msg_code, msg);

    (void)obj_type;
    (void)obj;
    (void)location;
    (void)user_data;

    return false;
}

VkResult LayerChain::create_instance(const VkInstanceCreateInfo* create_info,
                                     const VkAllocationCallbacks* allocator,
                                     VkInstance* instance_out) {
    LayerChain chain(true,
                     (allocator) ? *allocator : driver::GetDefaultAllocator());

    VkResult result = chain.activate_layers(
        create_info->ppEnabledLayerNames, create_info->enabledLayerCount,
        create_info->ppEnabledExtensionNames,
        create_info->enabledExtensionCount);
    if (result != VK_SUCCESS)
        return result;

    // use a local create info when the chain is not empty
    VkInstanceCreateInfo local_create_info;
    if (!chain.empty()) {
        local_create_info = *create_info;
        chain.modify_create_info(local_create_info);
        create_info = &local_create_info;
    }

    return chain.create(create_info, allocator, instance_out);
}

VkResult LayerChain::create_device(VkPhysicalDevice physical_dev,
                                   const VkDeviceCreateInfo* create_info,
                                   const VkAllocationCallbacks* allocator,
                                   VkDevice* dev_out) {
    LayerChain chain(false, (allocator)
                                ? *allocator
                                : driver::GetData(physical_dev).allocator);

    VkResult result = chain.activate_layers(
        create_info->ppEnabledLayerNames, create_info->enabledLayerCount,
        create_info->ppEnabledExtensionNames,
        create_info->enabledExtensionCount);
    if (result != VK_SUCCESS)
        return result;

    // use a local create info when the chain is not empty
    VkDeviceCreateInfo local_create_info;
    if (!chain.empty()) {
        local_create_info = *create_info;
        chain.modify_create_info(local_create_info);
        create_info = &local_create_info;
    }

    return chain.create(physical_dev, create_info, allocator, dev_out);
}

void LayerChain::destroy_instance(VkInstance instance,
                                  const VkAllocationCallbacks* allocator) {
    InstanceData& data = GetData(instance);

    if (data.debug_callback != VK_NULL_HANDLE)
        data.destroy_debug_callback(instance, data.debug_callback, allocator);

    ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
    uint32_t layer_count = data.layer_count;

    VkAllocationCallbacks local_allocator;
    if (!allocator)
        local_allocator = driver::GetData(instance).allocator;

    // this also destroys InstanceData
    data.dispatch.DestroyInstance(instance, allocator);

    destroy_layers(layers, layer_count,
                   (allocator) ? *allocator : local_allocator);
}

void LayerChain::destroy_device(VkDevice device,
                                const VkAllocationCallbacks* allocator) {
    DeviceData& data = GetData(device);

    ActiveLayer* layers = reinterpret_cast<ActiveLayer*>(data.layers);
    uint32_t layer_count = data.layer_count;

    VkAllocationCallbacks local_allocator;
    if (!allocator)
        local_allocator = driver::GetData(device).allocator;

    // this also destroys DeviceData
    data.dispatch.DestroyDevice(device, allocator);

    destroy_layers(layers, layer_count,
                   (allocator) ? *allocator : local_allocator);
}

// ----------------------------------------------------------------------------

bool EnsureInitialized() {
    static std::once_flag once_flag;
    static bool initialized;

    std::call_once(once_flag, []() {
        if (driver::OpenHAL()) {
            DiscoverLayers();
            initialized = true;
        }
    });

    return initialized;
}

}  // anonymous namespace

VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
                        const VkAllocationCallbacks* pAllocator,
                        VkInstance* pInstance) {
    if (!EnsureInitialized())
        return VK_ERROR_INITIALIZATION_FAILED;

    return LayerChain::create_instance(pCreateInfo, pAllocator, pInstance);
}

void DestroyInstance(VkInstance instance,
                     const VkAllocationCallbacks* pAllocator) {
    if (instance != VK_NULL_HANDLE)
        LayerChain::destroy_instance(instance, pAllocator);
}

VkResult CreateDevice(VkPhysicalDevice physicalDevice,
                      const VkDeviceCreateInfo* pCreateInfo,
                      const VkAllocationCallbacks* pAllocator,
                      VkDevice* pDevice) {
    return LayerChain::create_device(physicalDevice, pCreateInfo, pAllocator,
                                     pDevice);
}

void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
    if (device != VK_NULL_HANDLE)
        LayerChain::destroy_device(device, pAllocator);
}

VkResult EnumerateInstanceLayerProperties(uint32_t* pPropertyCount,
                                          VkLayerProperties* pProperties) {
    if (!EnsureInitialized())
        return VK_ERROR_INITIALIZATION_FAILED;

    uint32_t count =
        EnumerateInstanceLayers(pProperties ? *pPropertyCount : 0, pProperties);

    if (!pProperties || *pPropertyCount > count)
        *pPropertyCount = count;

    return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
}

VkResult EnumerateInstanceExtensionProperties(
    const char* pLayerName,
    uint32_t* pPropertyCount,
    VkExtensionProperties* pProperties) {
    if (!EnsureInitialized())
        return VK_ERROR_INITIALIZATION_FAILED;

    if (pLayerName) {
        const VkExtensionProperties* props;
        uint32_t count;
        GetInstanceLayerExtensions(pLayerName, &props, &count);

        if (!pProperties || *pPropertyCount > count)
            *pPropertyCount = count;
        if (pProperties)
            std::copy(props, props + *pPropertyCount, pProperties);

        return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
    }

    // TODO how about extensions from implicitly enabled layers?
    return vulkan::driver::EnumerateInstanceExtensionProperties(
        nullptr, pPropertyCount, pProperties);
}

VkResult EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
                                        uint32_t* pPropertyCount,
                                        VkLayerProperties* pProperties) {
    (void)physicalDevice;

    uint32_t count =
        EnumerateDeviceLayers(pProperties ? *pPropertyCount : 0, pProperties);

    if (!pProperties || *pPropertyCount > count)
        *pPropertyCount = count;

    return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
}

VkResult EnumerateDeviceExtensionProperties(
    VkPhysicalDevice physicalDevice,
    const char* pLayerName,
    uint32_t* pPropertyCount,
    VkExtensionProperties* pProperties) {
    if (pLayerName) {
        const VkExtensionProperties* props;
        uint32_t count;
        GetDeviceLayerExtensions(pLayerName, &props, &count);

        if (!pProperties || *pPropertyCount > count)
            *pPropertyCount = count;
        if (pProperties)
            std::copy(props, props + *pPropertyCount, pProperties);

        return *pPropertyCount < count ? VK_INCOMPLETE : VK_SUCCESS;
    }

    // TODO how about extensions from implicitly enabled layers?
    const InstanceData& data = GetData(physicalDevice);
    return data.dispatch.EnumerateDeviceExtensionProperties(
        physicalDevice, nullptr, pPropertyCount, pProperties);
}

}  // namespace api
}  // namespace vulkan
