// Copyright (c) 2018 The Chromium 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 "gpu/vulkan/android/vulkan_implementation_android.h"

#include "base/android/android_hardware_buffer_compat.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "ui/gfx/gpu_fence.h"

namespace gpu {

VulkanImplementationAndroid::VulkanImplementationAndroid() = default;

VulkanImplementationAndroid::~VulkanImplementationAndroid() = default;

bool VulkanImplementationAndroid::InitializeVulkanInstance() {
  std::vector<const char*> required_extensions = {
      VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
      VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
      VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME};

  VulkanFunctionPointers* vulkan_function_pointers =
      gpu::GetVulkanFunctionPointers();

  base::NativeLibraryLoadError native_library_load_error;
  vulkan_function_pointers->vulkan_loader_library_ = base::LoadNativeLibrary(
      base::FilePath("libvulkan.so"), &native_library_load_error);
  if (!vulkan_function_pointers->vulkan_loader_library_)
    return false;

  if (!vulkan_instance_.Initialize(required_extensions, {}))
    return false;

  // Initialize platform function pointers
  vkCreateAndroidSurfaceKHR_ =
      reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(vkGetInstanceProcAddr(
          vulkan_instance_.vk_instance(), "vkCreateAndroidSurfaceKHR"));
  if (!vkCreateAndroidSurfaceKHR_)
    return false;

  return true;
}

VulkanInstance* VulkanImplementationAndroid::GetVulkanInstance() {
  return &vulkan_instance_;
}

std::unique_ptr<VulkanSurface> VulkanImplementationAndroid::CreateViewSurface(
    gfx::AcceleratedWidget window) {
  VkSurfaceKHR surface;
  VkAndroidSurfaceCreateInfoKHR surface_create_info = {};
  surface_create_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
  surface_create_info.window = window;
  VkResult result = vkCreateAndroidSurfaceKHR_(
      vulkan_instance_.vk_instance(), &surface_create_info, nullptr, &surface);
  if (VK_SUCCESS != result) {
    DLOG(ERROR) << "vkCreateAndroidSurfaceKHR() failed: " << result;
    return nullptr;
  }

  return std::make_unique<VulkanSurface>(vulkan_instance_.vk_instance(),
                                         surface);
}

bool VulkanImplementationAndroid::GetPhysicalDevicePresentationSupport(
    VkPhysicalDevice device,
    const std::vector<VkQueueFamilyProperties>& queue_family_properties,
    uint32_t queue_family_index) {
  // On Android, all physical devices and queue families must be capable of
  // presentation with any native window.
  // As a result there is no Android-specific query for these capabilities.
  return true;
}

std::vector<const char*>
VulkanImplementationAndroid::GetRequiredDeviceExtensions() {
  // VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME also requires
  // VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME as per spec.
  return {VK_KHR_SWAPCHAIN_EXTENSION_NAME,
          VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
          VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
          VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
          VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
          VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
          VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME};
}

VkFence VulkanImplementationAndroid::CreateVkFenceForGpuFence(
    VkDevice vk_device) {
  NOTREACHED();
  return VK_NULL_HANDLE;
}

std::unique_ptr<gfx::GpuFence>
VulkanImplementationAndroid::ExportVkFenceToGpuFence(VkDevice vk_device,
                                                     VkFence vk_fence) {
  NOTREACHED();
  return nullptr;
}

bool VulkanImplementationAndroid::ImportSemaphoreFdKHR(
    VkDevice vk_device,
    base::ScopedFD sync_fd,
    VkSemaphore* vk_semaphore) {
  // Create a VkSemaphore.
  VkSemaphoreCreateInfo info = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
  bool result = vkCreateSemaphore(vk_device, &info, nullptr, vk_semaphore);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkCreateSemaphore failed : " << result;
    return false;
  }

  // Create VkImportSemaphoreFdInfoKHR structure.
  VkImportSemaphoreFdInfoKHR import;
  import.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
  import.pNext = nullptr;
  import.semaphore = *vk_semaphore;
  import.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR;

  // VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX file
  // descriptor handle to a Linux Sync File or Android Fence object.
  import.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
  import.fd = sync_fd.get();

  // Import the fd into the semaphore.
  result = vkImportSemaphoreFdKHR(vk_device, &import);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkImportSemaphoreFdKHR failed : " << result;
    vkDestroySemaphore(vk_device, *vk_semaphore, nullptr);
    return false;
  }

  // If import is successful, the VkSemaphore object takes the ownership of fd.
  ignore_result(sync_fd.release());
  return true;
}

bool VulkanImplementationAndroid::GetSemaphoreFdKHR(VkDevice vk_device,
                                                    VkSemaphore vk_semaphore,
                                                    base::ScopedFD* sync_fd) {
  // Create VkSemaphoreGetFdInfoKHR structure.
  VkSemaphoreGetFdInfoKHR info;
  info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
  info.pNext = nullptr;
  info.semaphore = vk_semaphore;
  info.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;

  // Create a new sync fd from the semaphore.
  int fd = -1;
  bool result = vkGetSemaphoreFdKHR(vk_device, &info, &fd);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkGetSemaphoreFdKHR failed : " << result;
    sync_fd->reset(-1);
    return false;
  }

  // Transfer the ownership of the fd to the caller.
  sync_fd->reset(fd);
  return true;
}

bool VulkanImplementationAndroid::CreateVkImageAndImportAHB(
    const VkDevice& vk_device,
    const VkPhysicalDevice& vk_physical_device,
    const gfx::Size& size,
    base::android::ScopedHardwareBufferHandle ahb_handle,
    VkImage* vk_image,
    VkImageCreateInfo* vk_image_info,
    VkDeviceMemory* vk_device_memory,
    VkDeviceSize* mem_allocation_size) {
  DCHECK(ahb_handle.is_valid());
  DCHECK(vk_image);
  DCHECK(vk_image_info);
  DCHECK(vk_device_memory);
  DCHECK(mem_allocation_size);

  // To obtain format properties of an Android hardware buffer, include an
  // instance of VkAndroidHardwareBufferFormatPropertiesANDROID in the pNext
  // chain of the VkAndroidHardwareBufferPropertiesANDROID instance passed to
  // vkGetAndroidHardwareBufferPropertiesANDROID.
  VkAndroidHardwareBufferFormatPropertiesANDROID ahb_format_props;
  ahb_format_props.sType =
      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
  ahb_format_props.pNext = nullptr;

  VkAndroidHardwareBufferPropertiesANDROID ahb_props;
  ahb_props.sType =
      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
  ahb_props.pNext = &ahb_format_props;

  bool result = vkGetAndroidHardwareBufferPropertiesANDROID(
      vk_device, ahb_handle.get(), &ahb_props);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "GetAndroidHardwareBufferProperties failed : " << result;
    return false;
  }

  // To create an image with an external format, include an instance of
  // VkExternalFormatANDROID in the pNext chain of VkImageCreateInfo.
  VkExternalFormatANDROID external_format;
  external_format.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
  external_format.pNext = nullptr;

  // If externalFormat is zero, the effect is as if the VkExternalFormatANDROID
  // structure was not present. Otherwise, the image will have the specified
  // external format.
  external_format.externalFormat = 0;

  // If image has an external format, format must be VK_FORMAT_UNDEFINED.
  if (ahb_format_props.format == VK_FORMAT_UNDEFINED) {
    // externalFormat must be 0 or a value returned in the externalFormat member
    // of VkAndroidHardwareBufferFormatPropertiesANDROID by an earlier call to
    // vkGetAndroidHardwareBufferPropertiesANDROID.
    external_format.externalFormat = ahb_format_props.externalFormat;
  }

  // To define a set of external memory handle types that may be used as backing
  // store for an image, add a VkExternalMemoryImageCreateInfo structure to the
  // pNext chain of the VkImageCreateInfo structure.
  VkExternalMemoryImageCreateInfo external_memory_image_info;
  external_memory_image_info.sType =
      VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
  external_memory_image_info.pNext = &external_format;
  external_memory_image_info.handleTypes =
      VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;

  // Intended usage of the image.
  VkImageUsageFlags usage_flags = 0;

  // Get the AHB description.
  AHardwareBuffer_Desc ahb_desc = {};
  base::AndroidHardwareBufferCompat::GetInstance().Describe(ahb_handle.get(),
                                                            &ahb_desc);

  // Get Vulkan Image usage flag equivalence of AHB usage.
  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
    usage_flags = usage_flags | VK_IMAGE_USAGE_SAMPLED_BIT |
                  VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
  }
  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT) {
    usage_flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
  }
  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
    usage_flags |= VK_IMAGE_CREATE_PROTECTED_BIT;
  }

  // TODO(vikassoni) : AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP is supported from API
  // level 28 which is not part of current android_ndk version in chromium. Add
  // equvalent VK usage later.

  if (!usage_flags) {
    LOG(ERROR) << "No valid usage flags found";
    return false;
  }

  // Find the first set bit to use as memoryTypeIndex.
  uint32_t memory_type_bits = ahb_props.memoryTypeBits;
  int32_t type_index = -1;
  for (uint32_t i = 0; memory_type_bits;
       memory_type_bits = memory_type_bits >> 0x1, ++i) {
    if (memory_type_bits & 0x1) {
      type_index = i;
      break;
    }
  }
  if (type_index == -1) {
    LOG(ERROR) << "No valid memoryTypeIndex found";
    return false;
  }

  // Populate VkImageCreateInfo.
  vk_image_info->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  vk_image_info->pNext = &external_memory_image_info;
  vk_image_info->flags = 0;
  vk_image_info->imageType = VK_IMAGE_TYPE_2D;
  vk_image_info->format = ahb_format_props.format;
  vk_image_info->extent = {static_cast<uint32_t>(size.width()),
                           static_cast<uint32_t>(size.height()), 1};
  vk_image_info->mipLevels = 1;
  vk_image_info->arrayLayers = 1;
  vk_image_info->samples = VK_SAMPLE_COUNT_1_BIT;
  vk_image_info->tiling = VK_IMAGE_TILING_OPTIMAL;
  vk_image_info->usage = usage_flags;
  vk_image_info->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  vk_image_info->queueFamilyIndexCount = 0;
  vk_image_info->pQueueFamilyIndices = 0;
  vk_image_info->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

  // Create Vk Image.
  result = vkCreateImage(vk_device, vk_image_info, nullptr, vk_image);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkCreateImage failed : " << result;
    return false;
  }

  // To import memory created outside of the current Vulkan instance from an
  // Android hardware buffer, add a VkImportAndroidHardwareBufferInfoANDROID
  // structure to the pNext chain of the VkMemoryAllocateInfo structure.
  VkImportAndroidHardwareBufferInfoANDROID ahb_import_info;
  ahb_import_info.sType =
      VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
  ahb_import_info.pNext = nullptr;
  ahb_import_info.buffer = ahb_handle.get();

  // If the VkMemoryAllocateInfo pNext chain includes a
  // VkMemoryDedicatedAllocateInfo structure, then that structure includes a
  // handle of the sole buffer or image resource that the memory can be bound
  // to.
  VkMemoryDedicatedAllocateInfo dedicated_alloc_info;
  dedicated_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
  dedicated_alloc_info.pNext = &ahb_import_info;
  dedicated_alloc_info.image = *vk_image;
  dedicated_alloc_info.buffer = VK_NULL_HANDLE;

  // An instance of the VkMemoryAllocateInfo structure defines a memory import
  // operation.
  VkMemoryAllocateInfo mem_alloc_info;
  mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  mem_alloc_info.pNext = &dedicated_alloc_info;

  // If the parameters define an import operation and the external handle type
  // is VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
  // allocationSize must be the size returned by
  // vkGetAndroidHardwareBufferPropertiesANDROID for the Android hardware
  // buffer.
  mem_alloc_info.allocationSize = ahb_props.allocationSize;
  mem_alloc_info.memoryTypeIndex = type_index;

  // A Vulkan device operates on data in device memory via memory objects that
  // are represented in the API by a VkDeviceMemory handle.
  // Allocate memory.
  result =
      vkAllocateMemory(vk_device, &mem_alloc_info, nullptr, vk_device_memory);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkAllocateMemory failed : " << result;
    vkDestroyImage(vk_device, *vk_image, nullptr);
    return false;
  }

  // Attach memory to the image object.
  result = vkBindImageMemory(vk_device, *vk_image, *vk_device_memory, 0);
  if (result != VK_SUCCESS) {
    LOG(ERROR) << "vkBindImageMemory failed : " << result;
    vkDestroyImage(vk_device, *vk_image, nullptr);
    vkFreeMemory(vk_device, *vk_device_memory, nullptr);
    return false;
  }

  *mem_allocation_size = mem_alloc_info.allocationSize;
  return true;
}

}  // namespace gpu
