// 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/ipc/common/vulkan_ycbcr_info.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_posix_util.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "gpu/vulkan/vulkan_util.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace gpu {

namespace {
bool GetAhbProps(
    const VkDevice& vk_device,
    AHardwareBuffer* hardware_buffer,
    VkAndroidHardwareBufferFormatPropertiesANDROID* ahb_format_props,
    VkAndroidHardwareBufferPropertiesANDROID* ahb_props) {
  DCHECK(ahb_format_props);
  DCHECK(ahb_props);

  // 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.
  ahb_format_props->sType =
      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
  ahb_format_props->pNext = nullptr;

  ahb_props->sType =
      VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
  ahb_props->pNext = ahb_format_props;

  bool result = vkGetAndroidHardwareBufferPropertiesANDROID(
      vk_device, hardware_buffer, ahb_props);
  if (result != VK_SUCCESS) {
    LOG(ERROR)
        << "GetAhbProps: vkGetAndroidHardwareBufferPropertiesANDROID failed : "
        << result;
    return false;
  }
  return true;
}

void PopulateYcbcrInfo(
    const VkAndroidHardwareBufferFormatPropertiesANDROID& ahb_format_props,
    VulkanYCbCrInfo* ycbcr_info) {
  DCHECK(ycbcr_info);

  ycbcr_info->suggested_ycbcr_model = ahb_format_props.suggestedYcbcrModel;
  ycbcr_info->suggested_ycbcr_range = ahb_format_props.suggestedYcbcrRange;
  ycbcr_info->suggested_xchroma_offset =
      ahb_format_props.suggestedXChromaOffset;
  ycbcr_info->suggested_ychroma_offset =
      ahb_format_props.suggestedYChromaOffset;
  ycbcr_info->external_format = ahb_format_props.externalFormat;
  ycbcr_info->format_features = ahb_format_props.formatFeatures;
}

}  // namespace

VulkanImplementationAndroid::VulkanImplementationAndroid() = default;

VulkanImplementationAndroid::~VulkanImplementationAndroid() = default;

bool VulkanImplementationAndroid::InitializeVulkanInstance(bool using_surface) {
  DCHECK(using_surface);
  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,
          VK_KHR_SAMPLER_YCBCR_CONVERSION_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;
}

VkSemaphore VulkanImplementationAndroid::CreateExternalSemaphore(
    VkDevice vk_device) {
  return CreateExternalVkSemaphore(
      vk_device, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
}

VkSemaphore VulkanImplementationAndroid::ImportSemaphoreHandle(
    VkDevice vk_device,
    SemaphoreHandle sync_handle) {
  return ImportVkSemaphoreHandlePosix(vk_device, std::move(sync_handle));
}

SemaphoreHandle VulkanImplementationAndroid::GetSemaphoreHandle(
    VkDevice vk_device,
    VkSemaphore vk_semaphore) {
  // VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX file
  // descriptor handle to a Linux Sync File or Android Fence object.
  return GetVkSemaphoreHandlePosix(
      vk_device, vk_semaphore, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
}

VkExternalMemoryHandleTypeFlagBits
VulkanImplementationAndroid::GetExternalImageHandleType() {
  return VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
}

bool VulkanImplementationAndroid::CanImportGpuMemoryBuffer(
    gfx::GpuMemoryBufferType memory_buffer_type) {
  return false;
}

bool VulkanImplementationAndroid::CreateImageFromGpuMemoryHandle(
    VkDevice vk_device,
    gfx::GpuMemoryBufferHandle gmb_handle,
    gfx::Size size,
    VkImage* vk_image,
    VkImageCreateInfo* vk_image_info,
    VkDeviceMemory* vk_device_memory,
    VkDeviceSize* mem_allocation_size) {
  // TODO(sergeyu): Move code from CreateVkImageAndImportAHB() here and remove
  // CreateVkImageAndImportAHB().
  NOTIMPLEMENTED();
  return false;
}

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,
    VulkanYCbCrInfo* ycbcr_info) {
  DCHECK(ahb_handle.is_valid());
  DCHECK(vk_image);
  DCHECK(vk_image_info);
  DCHECK(vk_device_memory);
  DCHECK(mem_allocation_size);

  // Get the image format properties of an Android hardware buffer.
  VkAndroidHardwareBufferFormatPropertiesANDROID ahb_format_props = {};
  VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
  if (!GetAhbProps(vk_device, ahb_handle.get(), &ahb_format_props, &ahb_props))
    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.
  bool 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;
  if (ycbcr_info)
    PopulateYcbcrInfo(ahb_format_props, ycbcr_info);
  return true;
}

bool VulkanImplementationAndroid::GetSamplerYcbcrConversionInfo(
    const VkDevice& vk_device,
    base::android::ScopedHardwareBufferHandle ahb_handle,
    VulkanYCbCrInfo* ycbcr_info) {
  DCHECK(ycbcr_info);

  // Get the image format properties of an Android hardware buffer.
  VkAndroidHardwareBufferFormatPropertiesANDROID ahb_format_props = {};
  VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
  if (!GetAhbProps(vk_device, ahb_handle.get(), &ahb_format_props, &ahb_props))
    return false;

  PopulateYcbcrInfo(ahb_format_props, ycbcr_info);
  return true;
}

}  // namespace gpu
