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

#include <chrono>
#include <cstdlib>
#include <iostream>
#include <optional>
#include <tuple>
#include <vector>

// Use vulkan.hpp's convenient proc table and resolver.
#define VULKAN_HPP_NO_EXCEPTIONS 1
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include "vulkan/vulkan.hpp"
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE

// Convenient reference to vulkan.hpp's global proc table.
auto& d = vk::defaultDispatchLoaderDynamic;

// GLFW needs to be included after Vulkan.
#include "GLFW/glfw3.h"

#include "embedder.h"  // Flutter's Embedder ABI.

static const bool g_enable_validation_layers = true;
// This value is calculated after the window is created.
static double g_pixelRatio = 1.0;
static const size_t kInitialWindowWidth = 800;
static const size_t kInitialWindowHeight = 600;
// Use `VK_PRESENT_MODE_FIFO_KHR` for full vsync (one swap per screen refresh),
// `VK_PRESENT_MODE_MAILBOX_KHR` for continual swap without horizontal tearing,
// or `VK_PRESENT_MODE_IMMEDIATE_KHR` for no vsync.
static const VkPresentModeKHR kPreferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
static constexpr FlutterViewId kImplicitViewId = 0;

static_assert(FLUTTER_ENGINE_VERSION == 1,
              "This Flutter Embedder was authored against the stable Flutter "
              "API at version 1. There has been a serious breakage in the "
              "API. Please read the ChangeLog and take appropriate action "
              "before updating this assertion");

/// Global struct for holding the Window+Vulkan state.
struct {
  GLFWwindow* window;

  std::vector<const char*> enabled_instance_extensions;
  VkInstance instance;
  VkSurfaceKHR surface;

  VkPhysicalDevice physical_device;
  std::vector<const char*> enabled_device_extensions;
  VkDevice device;
  uint32_t queue_family_index;
  VkQueue queue;

  VkCommandPool swapchain_command_pool;
  std::vector<VkCommandBuffer> present_transition_buffers;

  VkFence image_ready_fence;
  VkSemaphore present_transition_semaphore;

  VkSurfaceFormatKHR surface_format;
  VkSwapchainKHR swapchain;
  std::vector<VkImage> swapchain_images;
  uint32_t last_image_index;

  FlutterEngine engine;

  bool resize_pending = false;
} g_state;

void GLFW_ErrorCallback(int error, const char* description) {
  std::cerr << "GLFW Error: (" << error << ") " << description << std::endl;
}

void GLFWcursorPositionCallbackAtPhase(GLFWwindow* window,
                                       FlutterPointerPhase phase,
                                       double x,
                                       double y) {
  FlutterPointerEvent event = {};
  event.struct_size = sizeof(event);
  event.phase = phase;
  event.x = x * g_pixelRatio;
  event.y = y * g_pixelRatio;
  event.timestamp =
      std::chrono::duration_cast<std::chrono::microseconds>(
          std::chrono::high_resolution_clock::now().time_since_epoch())
          .count();
  // This example only supports a single window, therefore we assume the event
  // occurred in the only view, the implicit view.
  event.view_id = kImplicitViewId;
  FlutterEngineSendPointerEvent(g_state.engine, &event, 1);
}

void GLFWcursorPositionCallback(GLFWwindow* window, double x, double y) {
  GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kMove, x, y);
}

void GLFWmouseButtonCallback(GLFWwindow* window,
                             int key,
                             int action,
                             int mods) {
  if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
    double x, y;
    glfwGetCursorPos(window, &x, &y);
    GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kDown, x, y);
    glfwSetCursorPosCallback(window, GLFWcursorPositionCallback);
  }

  if (key == GLFW_MOUSE_BUTTON_1 && action == GLFW_RELEASE) {
    double x, y;
    glfwGetCursorPos(window, &x, &y);
    GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kUp, x, y);
    glfwSetCursorPosCallback(window, nullptr);
  }
}

void GLFWKeyCallback(GLFWwindow* window,
                     int key,
                     int scancode,
                     int action,
                     int mods) {
  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
    glfwSetWindowShouldClose(window, GLFW_TRUE);
  }
}

void GLFWframebufferSizeCallback(GLFWwindow* window, int width, int height) {
  g_state.resize_pending = true;

  FlutterWindowMetricsEvent event = {};
  event.struct_size = sizeof(event);
  event.width = width;
  event.height = height;
  event.pixel_ratio = g_pixelRatio;
  // This example only supports a single window, therefore we assume the event
  // occurred in the only view, the implicit view.
  event.view_id = kImplicitViewId;
  FlutterEngineSendWindowMetricsEvent(g_state.engine, &event);
}

void PrintUsage() {
  std::cerr
      << "usage: embedder_example_vulkan <path to project> <path to icudtl.dat>"
      << std::endl;
}

bool InitializeSwapchain() {
  if (g_state.resize_pending) {
    g_state.resize_pending = false;
    d.vkDestroySwapchainKHR(g_state.device, g_state.swapchain, nullptr);

    d.vkQueueWaitIdle(g_state.queue);
    d.vkResetCommandPool(g_state.device, g_state.swapchain_command_pool,
                         VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
  }

  /// --------------------------------------------------------------------------
  /// Choose an image format that can be presented to the surface, preferring
  /// the common BGRA+sRGB if available.
  /// --------------------------------------------------------------------------

  uint32_t format_count;
  d.vkGetPhysicalDeviceSurfaceFormatsKHR(
      g_state.physical_device, g_state.surface, &format_count, nullptr);
  std::vector<VkSurfaceFormatKHR> formats(format_count);
  d.vkGetPhysicalDeviceSurfaceFormatsKHR(
      g_state.physical_device, g_state.surface, &format_count, formats.data());
  assert(!formats.empty());  // Shouldn't be possible.

  g_state.surface_format = formats[0];
  for (const auto& format : formats) {
    if (format.format == VK_FORMAT_B8G8R8A8_UNORM &&
        format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
      g_state.surface_format = format;
    }
  }

  /// --------------------------------------------------------------------------
  /// Choose the presentable image size that's as close as possible to the
  /// window size.
  /// --------------------------------------------------------------------------

  VkExtent2D extent;

  VkSurfaceCapabilitiesKHR surface_capabilities;
  d.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
      g_state.physical_device, g_state.surface, &surface_capabilities);

  if (surface_capabilities.currentExtent.width != UINT32_MAX) {
    // If the surface reports a specific extent, we must use it.
    extent = surface_capabilities.currentExtent;
  } else {
    // `glfwGetWindowSize` returns the window size in screen coordinates, so we
    // instead use `glfwGetFramebufferSize` to get the size in pixels in order
    // to properly support high DPI displays.
    int width, height;
    glfwGetFramebufferSize(g_state.window, &width, &height);

    VkExtent2D actual_extent = {
        .width = static_cast<uint32_t>(width),
        .height = static_cast<uint32_t>(height),
    };
    actual_extent.width =
        std::max(surface_capabilities.minImageExtent.width,
                 std::min(surface_capabilities.maxImageExtent.width,
                          actual_extent.width));
    actual_extent.height =
        std::max(surface_capabilities.minImageExtent.height,
                 std::min(surface_capabilities.maxImageExtent.height,
                          actual_extent.height));
  }

  /// --------------------------------------------------------------------------
  /// Choose the present mode.
  /// --------------------------------------------------------------------------

  uint32_t mode_count;
  d.vkGetPhysicalDeviceSurfacePresentModesKHR(
      g_state.physical_device, g_state.surface, &mode_count, nullptr);
  std::vector<VkPresentModeKHR> modes(mode_count);
  d.vkGetPhysicalDeviceSurfacePresentModesKHR(
      g_state.physical_device, g_state.surface, &mode_count, modes.data());
  assert(!formats.empty());  // Shouldn't be possible.

  // If the preferred mode isn't available, just choose the first one.
  VkPresentModeKHR present_mode = modes[0];
  for (const auto& mode : modes) {
    if (mode == kPreferredPresentMode) {
      present_mode = mode;
      break;
    }
  }

  /// --------------------------------------------------------------------------
  /// Create the swapchain.
  /// --------------------------------------------------------------------------

  VkSwapchainCreateInfoKHR info = {
      .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
      .surface = g_state.surface,
      .minImageCount = surface_capabilities.minImageCount + 1,
      .imageFormat = g_state.surface_format.format,
      .imageColorSpace = g_state.surface_format.colorSpace,
      .imageExtent = extent,
      .imageArrayLayers = 1,
      .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
      .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
      .queueFamilyIndexCount = 0,
      .pQueueFamilyIndices = nullptr,
      .preTransform = surface_capabilities.currentTransform,
      .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
      .presentMode = present_mode,
      .clipped = true,
  };
  if (d.vkCreateSwapchainKHR(g_state.device, &info, nullptr,
                             &g_state.swapchain) != VK_SUCCESS) {
    return false;
  }

  /// --------------------------------------------------------------------------
  /// Fetch swapchain images.
  /// --------------------------------------------------------------------------

  uint32_t image_count;
  d.vkGetSwapchainImagesKHR(g_state.device, g_state.swapchain, &image_count,
                            nullptr);
  g_state.swapchain_images.resize(image_count);
  d.vkGetSwapchainImagesKHR(g_state.device, g_state.swapchain, &image_count,
                            g_state.swapchain_images.data());

  /// --------------------------------------------------------------------------
  /// Record a command buffer for each of the images to be executed prior to
  /// presenting.
  /// --------------------------------------------------------------------------

  g_state.present_transition_buffers.resize(g_state.swapchain_images.size());

  VkCommandBufferAllocateInfo buffers_info = {
      .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
      .commandPool = g_state.swapchain_command_pool,
      .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
      .commandBufferCount =
          static_cast<uint32_t>(g_state.present_transition_buffers.size()),
  };
  d.vkAllocateCommandBuffers(g_state.device, &buffers_info,
                             g_state.present_transition_buffers.data());

  for (size_t i = 0; i < g_state.swapchain_images.size(); i++) {
    auto image = g_state.swapchain_images[i];
    auto buffer = g_state.present_transition_buffers[i];

    VkCommandBufferBeginInfo begin_info = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
    d.vkBeginCommandBuffer(buffer, &begin_info);

    // Flutter Engine hands back the image after writing to it
    VkImageMemoryBarrier barrier = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
        .srcAccessMask = 0,
        .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
        .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
        .image = image,
        .subresourceRange = {
            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
            .baseMipLevel = 0,
            .levelCount = 1,
            .baseArrayLayer = 0,
            .layerCount = 1,
        }};
    d.vkCmdPipelineBarrier(
        buffer,                                         // commandBuffer
        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // srcStageMask
        VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,           // dstStageMask
        0,                                              // dependencyFlags
        0,                                              // memoryBarrierCount
        nullptr,                                        // pMemoryBarriers
        0,        // bufferMemoryBarrierCount
        nullptr,  // pBufferMemoryBarriers
        1,        // imageMemoryBarrierCount
        &barrier  // pImageMemoryBarriers
    );

    d.vkEndCommandBuffer(buffer);
  }

  return true;  // \o/
}

FlutterVulkanImage FlutterGetNextImageCallback(
    void* user_data,
    const FlutterFrameInfo* frame_info) {
  // If the GLFW framebuffer has been resized, discard the swapchain and create
  // a new one.
  if (g_state.resize_pending) {
    InitializeSwapchain();
  }

  d.vkAcquireNextImageKHR(g_state.device, g_state.swapchain, UINT64_MAX,
                          nullptr, g_state.image_ready_fence,
                          &g_state.last_image_index);

  // Flutter Engine expects the image to be available for transitioning and
  // attaching immediately, and so we need to force a host sync here before
  // returning.
  d.vkWaitForFences(g_state.device, 1, &g_state.image_ready_fence, true,
                    UINT64_MAX);
  d.vkResetFences(g_state.device, 1, &g_state.image_ready_fence);

  return {
      .struct_size = sizeof(FlutterVulkanImage),
      .image = reinterpret_cast<uint64_t>(
          g_state.swapchain_images[g_state.last_image_index]),
      .format = g_state.surface_format.format,
  };
}

bool FlutterPresentCallback(void* user_data, const FlutterVulkanImage* image) {
  VkPipelineStageFlags stage_flags =
      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  VkSubmitInfo submit_info = {
      .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
      .waitSemaphoreCount = 0,
      .pWaitSemaphores = nullptr,
      .pWaitDstStageMask = &stage_flags,
      .commandBufferCount = 1,
      .pCommandBuffers =
          &g_state.present_transition_buffers[g_state.last_image_index],
      .signalSemaphoreCount = 1,
      .pSignalSemaphores = &g_state.present_transition_semaphore,
  };
  d.vkQueueSubmit(g_state.queue, 1, &submit_info, nullptr);

  VkPresentInfoKHR present_info = {
      .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
      .waitSemaphoreCount = 1,
      .pWaitSemaphores = &g_state.present_transition_semaphore,
      .swapchainCount = 1,
      .pSwapchains = &g_state.swapchain,
      .pImageIndices = &g_state.last_image_index,
  };
  VkResult result = d.vkQueuePresentKHR(g_state.queue, &present_info);

  // If the swapchain is no longer compatible with the surface, discard the
  // swapchain and create a new one.
  if (result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_OUT_OF_DATE_KHR) {
    InitializeSwapchain();
  }
  d.vkQueueWaitIdle(g_state.queue);

  return result == VK_SUCCESS;
}

void* FlutterGetInstanceProcAddressCallback(
    void* user_data,
    FlutterVulkanInstanceHandle instance,
    const char* procname) {
  auto* proc = glfwGetInstanceProcAddress(
      reinterpret_cast<VkInstance>(instance), procname);
  return reinterpret_cast<void*>(proc);
}

int main(int argc, char** argv) {
  if (argc != 3) {
    PrintUsage();
    return 1;
  }

  std::string project_path = argv[1];
  std::string icudtl_path = argv[2];

  /// --------------------------------------------------------------------------
  /// Create a GLFW window.
  /// --------------------------------------------------------------------------

  {
    if (!glfwInit()) {
      std::cerr << "Failed to initialize GLFW." << std::endl;
      return EXIT_FAILURE;
    }

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    g_state.window = glfwCreateWindow(kInitialWindowWidth, kInitialWindowHeight,
                                      "Flutter", nullptr, nullptr);
    if (!g_state.window) {
      std::cerr << "Failed to create GLFW window." << std::endl;
      return EXIT_FAILURE;
    }

    int framebuffer_width, framebuffer_height;
    glfwGetFramebufferSize(g_state.window, &framebuffer_width,
                           &framebuffer_height);
    g_pixelRatio = framebuffer_width / kInitialWindowWidth;

    glfwSetErrorCallback(GLFW_ErrorCallback);
  }

  /// --------------------------------------------------------------------------
  /// Dynamically load the Vulkan loader with GLFW and use it to populate GLAD's
  /// proc table.
  /// --------------------------------------------------------------------------

  if (!glfwVulkanSupported()) {
    std::cerr << "GLFW was unable to resolve either a Vulkan loader or a "
                 "compatible physical device!"
              << std::endl;
#if defined(__APPLE__)
    std::cerr
        << "NOTE: Apple platforms don't ship with a Vulkan loader or any "
           "Vulkan drivers. Follow this guide to set up a Vulkan loader on "
           "macOS and use the MoltenVK ICD: "
           "https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html"
        << std::endl;
#endif
    return EXIT_FAILURE;
  }

  VULKAN_HPP_DEFAULT_DISPATCHER.init(glfwGetInstanceProcAddress);

  /// --------------------------------------------------------------------------
  /// Create a Vulkan instance.
  /// --------------------------------------------------------------------------

  {
    uint32_t extension_count;
    const char** glfw_extensions =
        glfwGetRequiredInstanceExtensions(&extension_count);
    g_state.enabled_instance_extensions.resize(extension_count);
    memcpy(g_state.enabled_instance_extensions.data(), glfw_extensions,
           extension_count * sizeof(char*));

    if (g_enable_validation_layers) {
      g_state.enabled_instance_extensions.push_back(
          VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
    }

    std::cout << "Enabling " << g_state.enabled_instance_extensions.size()
              << " instance extensions:" << std::endl;
    for (const auto& extension : g_state.enabled_instance_extensions) {
      std::cout << "  - " << extension << std::endl;
    }

    VkApplicationInfo app_info = {
        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
        .pNext = nullptr,
        .pApplicationName = "Flutter",
        .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
        .pEngineName = "No Engine",
        .engineVersion = VK_MAKE_VERSION(1, 0, 0),
        .apiVersion = VK_MAKE_VERSION(1, 1, 0),
    };
    VkInstanceCreateInfo info = {};
    info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    info.flags = 0;
    info.pApplicationInfo = &app_info;
    info.enabledExtensionCount = g_state.enabled_instance_extensions.size();
    info.ppEnabledExtensionNames = g_state.enabled_instance_extensions.data();
    if (g_enable_validation_layers) {
      auto available_layers = vk::enumerateInstanceLayerProperties();

      const char* layer = "VK_LAYER_KHRONOS_validation";
      for (const auto& l : available_layers.value) {
        if (strcmp(l.layerName, layer) == 0) {
          info.enabledLayerCount = 1;
          info.ppEnabledLayerNames = &layer;
          break;
        }
      }
    }

    if (d.vkCreateInstance(&info, nullptr, &g_state.instance) != VK_SUCCESS) {
      std::cerr << "Failed to create Vulkan instance." << std::endl;
      return EXIT_FAILURE;
    }
  }

  // Load instance procs.
  VULKAN_HPP_DEFAULT_DISPATCHER.init(vk::Instance(g_state.instance));

  /// --------------------------------------------------------------------------
  /// Create the window surface.
  /// --------------------------------------------------------------------------

  if (glfwCreateWindowSurface(g_state.instance, g_state.window, NULL,
                              &g_state.surface) != VK_SUCCESS) {
    std::cerr << "Failed to create window surface." << std::endl;
    return EXIT_FAILURE;
  }

  /// --------------------------------------------------------------------------
  /// Select a compatible physical device.
  /// --------------------------------------------------------------------------

  {
    uint32_t count;
    d.vkEnumeratePhysicalDevices(g_state.instance, &count, nullptr);
    std::vector<VkPhysicalDevice> physical_devices(count);
    d.vkEnumeratePhysicalDevices(g_state.instance, &count,
                                 physical_devices.data());

    std::cout << "Enumerating " << count << " physical device(s)." << std::endl;

    uint32_t selected_score = 0;
    for (const auto& pdevice : physical_devices) {
      VkPhysicalDeviceProperties properties;
      VkPhysicalDeviceFeatures features;
      d.vkGetPhysicalDeviceProperties(pdevice, &properties);
      d.vkGetPhysicalDeviceFeatures(pdevice, &features);

      std::cout << "Checking device: " << properties.deviceName << std::endl;

      uint32_t score = 0;
      std::vector<const char*> supported_extensions;

      uint32_t qfp_count;
      d.vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &qfp_count, nullptr);
      std::vector<VkQueueFamilyProperties> qfp(qfp_count);
      d.vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &qfp_count,
                                                 qfp.data());
      std::optional<uint32_t> graphics_queue_family;
      for (uint32_t i = 0; i < qfp.size(); i++) {
        // Only pick graphics queues that can also present to the surface.
        // Graphics queues that can't present are rare if not nonexistent, but
        // the spec allows for this, so check it anyways.
        VkBool32 surface_present_supported;
        d.vkGetPhysicalDeviceSurfaceSupportKHR(pdevice, i, g_state.surface,
                                               &surface_present_supported);

        if (!graphics_queue_family.has_value() &&
            qfp[i].queueFlags & VK_QUEUE_GRAPHICS_BIT &&
            surface_present_supported) {
          graphics_queue_family = i;
        }
      }

      // Skip physical devices that don't have a graphics queue.
      if (!graphics_queue_family.has_value()) {
        std::cout << "  - Skipping due to no suitable graphics queues."
                  << std::endl;
        continue;
      }

      // Prefer discrete GPUs.
      if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
        score += 1 << 30;
      }

      uint32_t extension_count;
      d.vkEnumerateDeviceExtensionProperties(pdevice, nullptr, &extension_count,
                                             nullptr);
      std::vector<VkExtensionProperties> available_extensions(extension_count);
      d.vkEnumerateDeviceExtensionProperties(pdevice, nullptr, &extension_count,
                                             available_extensions.data());

      bool supports_swapchain = false;
      for (const auto& available_extension : available_extensions) {
        if (strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME,
                   available_extension.extensionName) == 0) {
          supports_swapchain = true;
          supported_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
        }
        // The spec requires VK_KHR_portability_subset be enabled whenever it's
        // available on a device. It's present on compatibility ICDs like
        // MoltenVK.
        else if (strcmp("VK_KHR_portability_subset",
                        available_extension.extensionName) == 0) {
          supported_extensions.push_back("VK_KHR_portability_subset");
        }

        // Prefer GPUs that support VK_KHR_get_memory_requirements2.
        else if (strcmp(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
                        available_extension.extensionName) == 0) {
          score += 1 << 29;
          supported_extensions.push_back(
              VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
        }
      }

      // Skip physical devices that don't have swapchain support.
      if (!supports_swapchain) {
        std::cout << "  - Skipping due to lack of swapchain support."
                  << std::endl;
        continue;
      }

      // Prefer GPUs with larger max texture sizes.
      score += properties.limits.maxImageDimension2D;

      if (selected_score < score) {
        std::cout << "  - This is the best device so far. Score: 0x" << std::hex
                  << score << std::dec << std::endl;

        selected_score = score;
        g_state.physical_device = pdevice;
        g_state.enabled_device_extensions = supported_extensions;
        g_state.queue_family_index = graphics_queue_family.value_or(
            std::numeric_limits<uint32_t>::max());
      }
    }

    if (g_state.physical_device == nullptr) {
      std::cerr << "Failed to find a compatible Vulkan physical device."
                << std::endl;
      return EXIT_FAILURE;
    }
  }

  /// --------------------------------------------------------------------------
  /// Create a logical device and a graphics queue handle.
  /// --------------------------------------------------------------------------

  std::cout << "Enabling " << g_state.enabled_device_extensions.size()
            << " device extensions:" << std::endl;
  for (const char* extension : g_state.enabled_device_extensions) {
    std::cout << "  - " << extension << std::endl;
  }

  {
    VkPhysicalDeviceFeatures device_features = {};

    VkDeviceQueueCreateInfo graphics_queue = {};
    graphics_queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    graphics_queue.queueFamilyIndex = g_state.queue_family_index;
    graphics_queue.queueCount = 1;
    float priority = 1.0f;
    graphics_queue.pQueuePriorities = &priority;

    VkDeviceCreateInfo device_info = {};
    device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    device_info.enabledExtensionCount =
        g_state.enabled_device_extensions.size();
    device_info.ppEnabledExtensionNames =
        g_state.enabled_device_extensions.data();
    device_info.pEnabledFeatures = &device_features;
    device_info.queueCreateInfoCount = 1;
    device_info.pQueueCreateInfos = &graphics_queue;

    if (d.vkCreateDevice(g_state.physical_device, &device_info, nullptr,
                         &g_state.device) != VK_SUCCESS) {
      std::cerr << "Failed to create Vulkan logical device." << std::endl;
      return EXIT_FAILURE;
    }
  }

  d.vkGetDeviceQueue(g_state.device, g_state.queue_family_index, 0,
                     &g_state.queue);

  /// --------------------------------------------------------------------------
  /// Create sync primitives and command pool to use in the render loop
  /// callbacks.
  /// --------------------------------------------------------------------------

  {
    VkFenceCreateInfo f_info = {.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
    d.vkCreateFence(g_state.device, &f_info, nullptr,
                    &g_state.image_ready_fence);

    VkSemaphoreCreateInfo s_info = {
        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
    d.vkCreateSemaphore(g_state.device, &s_info, nullptr,
                        &g_state.present_transition_semaphore);

    VkCommandPoolCreateInfo pool_info = {
        .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
        .queueFamilyIndex = g_state.queue_family_index,
    };
    d.vkCreateCommandPool(g_state.device, &pool_info, nullptr,
                          &g_state.swapchain_command_pool);
  }

  /// --------------------------------------------------------------------------
  /// Create swapchain.
  /// --------------------------------------------------------------------------

  if (!InitializeSwapchain()) {
    std::cerr << "Failed to create swapchain." << std::endl;
    return EXIT_FAILURE;
  }

  /// --------------------------------------------------------------------------
  /// Start Flutter Engine.
  /// --------------------------------------------------------------------------

  {
    FlutterRendererConfig config = {};
    config.type = kVulkan;
    config.vulkan.struct_size = sizeof(config.vulkan);
    config.vulkan.version = VK_MAKE_VERSION(1, 1, 0);
    config.vulkan.instance = g_state.instance;
    config.vulkan.physical_device = g_state.physical_device;
    config.vulkan.device = g_state.device;
    config.vulkan.queue_family_index = g_state.queue_family_index;
    config.vulkan.queue = g_state.queue;
    config.vulkan.enabled_instance_extension_count =
        g_state.enabled_instance_extensions.size();
    config.vulkan.enabled_instance_extensions =
        g_state.enabled_instance_extensions.data();
    config.vulkan.enabled_device_extension_count =
        g_state.enabled_device_extensions.size();
    config.vulkan.enabled_device_extensions =
        g_state.enabled_device_extensions.data();
    config.vulkan.get_instance_proc_address_callback =
        FlutterGetInstanceProcAddressCallback;
    config.vulkan.get_next_image_callback = FlutterGetNextImageCallback;
    config.vulkan.present_image_callback = FlutterPresentCallback;

    // This directory is generated by `flutter build bundle`.
    std::string assets_path = project_path + "/build/flutter_assets";
    FlutterProjectArgs args = {
        .struct_size = sizeof(FlutterProjectArgs),
        .assets_path = assets_path.c_str(),
        .icu_data_path =
            icudtl_path.c_str(),  // Find this in your bin/cache directory.
    };
    FlutterEngineResult result =
        FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, g_state.window,
                         &g_state.engine);
    if (result != kSuccess || g_state.engine == nullptr) {
      std::cerr << "Failed to start Flutter Engine." << std::endl;
      return EXIT_FAILURE;
    }

    // Trigger a FlutterEngineSendWindowMetricsEvent to communicate the initial
    // size of the window.
    int width, height;
    glfwGetFramebufferSize(g_state.window, &width, &height);
    GLFWframebufferSizeCallback(g_state.window, width, height);
    g_state.resize_pending = false;
  }

  /// --------------------------------------------------------------------------
  /// GLFW render loop.
  /// --------------------------------------------------------------------------

  glfwSetKeyCallback(g_state.window, GLFWKeyCallback);
  glfwSetFramebufferSizeCallback(g_state.window, GLFWframebufferSizeCallback);
  glfwSetMouseButtonCallback(g_state.window, GLFWmouseButtonCallback);

  while (!glfwWindowShouldClose(g_state.window)) {
    glfwWaitEvents();
  }

  /// --------------------------------------------------------------------------
  /// Cleanup.
  /// --------------------------------------------------------------------------

  if (FlutterEngineShutdown(g_state.engine) != kSuccess) {
    std::cerr << "Flutter Engine shutdown failed." << std::endl;
  }

  d.vkDestroyCommandPool(g_state.device, g_state.swapchain_command_pool,
                         nullptr);
  d.vkDestroySemaphore(g_state.device, g_state.present_transition_semaphore,
                       nullptr);
  d.vkDestroyFence(g_state.device, g_state.image_ready_fence, nullptr);

  d.vkDestroyDevice(g_state.device, nullptr);
  d.vkDestroySurfaceKHR(g_state.instance, g_state.surface, nullptr);
  d.vkDestroyInstance(g_state.instance, nullptr);

  glfwDestroyWindow(g_state.window);
  glfwTerminate();

  return 0;
}
