// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_
#define SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_

#include <list>
#include <set>
#include <string>

#include "src/lib/fxl/memory/ref_counted.h"

#include <vulkan/vulkan.hpp>

namespace escher {

class VulkanInstance;
using VulkanInstancePtr = fxl::RefPtr<VulkanInstance>;

using VkDebugReportCallbackFn =
    std::function<VkBool32(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType,
                           uint64_t object, size_t location, int32_t messageCode,
                           const char* pLayerPrefix, const char* pMessage, void* pUserData)>;

// Convenient wrapper for creating and managing the lifecycle of a VkInstance
// that is suitable for use by Escher.
class VulkanInstance : public fxl::RefCountedThreadSafe<VulkanInstance> {
 public:
  // Parameters used to construct a new Vulkan Instance.
  struct Params {
    std::set<std::string> layer_names;
    std::set<std::string> extension_names;
    bool requires_surface = true;
  };

  // Contains dynamically-obtained addresses of instance-specific functions.
  struct ProcAddrs {
    ProcAddrs(vk::Instance instance, bool requires_surface);

    PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = nullptr;
    PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = nullptr;
    PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
  };

  // Contains debug report callback function and the user data pointer the
  // callback function binds to.
  struct DebugReportCallback {
    VkDebugReportCallbackFn function = nullptr;
    void* user_data = nullptr;

    DebugReportCallback(VkDebugReportCallbackFn function_, void* user_data_)
        : function(std::move(function_)), user_data(user_data_) {}
  };
  using DebugReportCallbackList = std::list<DebugReportCallback>;
  using DebugReportCallbackHandle = DebugReportCallbackList::iterator;

  // Constructor.
  static fxl::RefPtr<VulkanInstance> New(Params params);

  ~VulkanInstance();

  // Get the name of Vulkan validation layer. On platforms with Vulkan API
  // < 1.1.106 only VK_LAYER_LUNARG_standard_validation is supported, while it
  // is deprecated and we need to use VK_LAYER_KHRONOS_validation instead if
  // possible.
  static std::optional<std::string> GetValidationLayerName();

  // Enumerate the available instance layers.  Return true if all required
  // layers are present, and false otherwise.
  static bool ValidateLayers(const std::set<std::string>& required_layer_names);

  // Enumerate the available instance extensions.  Return true if all required
  // extensions are present, and false otherwise.  NOTE: if an extension isn't
  // found at first, we look in all required layers to see if it is implemented
  // there.
  static bool ValidateExtensions(const std::set<std::string>& required_extension_names,
                                 const std::set<std::string>& required_layer_names);

  // Register debug report callback |function| to list of callbacks, which will
  // be invoked by |DebugReportCallbackEntrance| when validation error occurs.
  // The returned handle will be required when deregistering the callback.
  DebugReportCallbackHandle RegisterDebugReportCallback(VkDebugReportCallbackFn function,
                                                        void* user_data = nullptr);

  // Remove debug report callback pointed by |handle| from |callbacks_|, the list
  // of callback functions.
  void DeregisterDebugReportCallback(const DebugReportCallbackHandle& handle);

  vk::Instance vk_instance() const { return instance_; }

  // Return the parameterss that were used to create this instance.
  const Params& params() const { return params_; }

  // Return per-instance functions that were dynamically looked up.
  const ProcAddrs& proc_addrs() const { return proc_addrs_; }

  // Return Vulkan API Version of the instance.
  uint32_t api_version() const { return api_version_; }

 private:
  VulkanInstance(vk::Instance instance, Params params, uint32_t api_version);

  // The "entrance" handler for all Vulkan instances. When validation error
  // occurs, this function will invoke all debug report callback functions
  // stored in vector |callbacks_|. This function always return VK_FALSE.
  static VkBool32 DebugReportCallbackEntrance(VkDebugReportFlagsEXT flags,
                                              VkDebugReportObjectTypeEXT objectType,
                                              uint64_t object, size_t location, int32_t messageCode,
                                              const char* pLayerPrefix, const char* pMessage,
                                              void* pUserData);

  bool HasDebugReportExt() const {
    return std::find(params_.extension_names.begin(), params_.extension_names.end(),
                     VK_EXT_DEBUG_REPORT_EXTENSION_NAME) != params_.extension_names.end();
  }

  vk::Instance instance_;
  Params params_;
  ProcAddrs proc_addrs_;
  std::list<DebugReportCallback> callbacks_;
  vk::DebugReportCallbackEXT vk_callback_entrance_handle_;
  uint32_t api_version_;
};

};  // namespace escher

#endif  // SRC_UI_LIB_ESCHER_VK_VULKAN_INSTANCE_H_
