// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/vulkan/vulkan_device_queue.h"

#include <algorithm>
#include <array>
#include <bit>
#include <cstring>
#include <unordered_set>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "gpu/config/gpu_info.h"  // nogncheck
#include "gpu/vulkan/vulkan_command_pool.h"
#include "gpu/vulkan/vulkan_crash_keys.h"
#include "gpu/vulkan/vulkan_fence_helper.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_info.h"
#include "gpu/vulkan/vulkan_util.h"
#include "ui/gl/gl_angle_util_vulkan.h"

namespace gpu {
namespace {
VkDeviceSize GetPreferredVMALargeHeapBlockSize() {
  // Based on Finch experiment results, the VMA block size does not
  // significantly affect performance.  Too small sizes (such as 4KB) result in
  // instability, likely due to running out of allowed allocations (the
  // |maxMemoryAllocationCount| Vulkan limit).  Too large sizes (such as 4MB)
  // result in significant memory waste due to fragmentation.  Finch results
  // have shown that with a block size of 64KB and below, the amount of
  // fragmentation is ~1MB in the 99th percentile.  For 128KB and higher block
  // sizes, the amount of fragmentation exponentially increases (with 2MB for
  // 128KB block size, 4MB for 256KB, etc).
  constexpr VkDeviceSize kVulkanVMALargeHeapBlockSize = 64 * 1024;
  return kVulkanVMALargeHeapBlockSize;
}

#if BUILDFLAG(IS_ANDROID)
class VulkanMetric final
    : public base::android::PreFreezeBackgroundMemoryTrimmer::PreFreezeMetric {
 public:
  explicit VulkanMetric(VmaAllocator vma_allocator)
      : PreFreezeMetric("Vulkan"), vma_allocator_(vma_allocator) {
    base::android::PreFreezeBackgroundMemoryTrimmer::RegisterMemoryMetric(this);
  }

  ~VulkanMetric() override {
    base::android::PreFreezeBackgroundMemoryTrimmer::UnregisterMemoryMetric(
        this);
  }

 private:
  std::optional<base::ByteCount> Measure() const override {
    auto allocated_used = vma::GetTotalAllocatedAndUsedMemory(vma_allocator_);
    return base::ByteCount::FromUnsigned(allocated_used.first);
  }
  VmaAllocator vma_allocator_;
};
#endif  // BUILDFLAG(IS_ANDROID)

}  // anonymous namespace

VulkanDeviceQueue::VulkanDeviceQueue(VkInstance vk_instance)
    : vk_instance_(vk_instance) {}

VulkanDeviceQueue::VulkanDeviceQueue(VulkanInstance* instance)
    : vk_instance_(instance->vk_instance()), instance_(instance) {}

VulkanDeviceQueue::~VulkanDeviceQueue() {
  // Destroy() should have been called.
  DCHECK_EQ(static_cast<VkPhysicalDevice>(VK_NULL_HANDLE), vk_physical_device_);
  DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
  DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
}

bool VulkanDeviceQueue::Initialize(
    uint32_t options,
    const GPUInfo* gpu_info,
    const std::vector<const char*>& required_extensions,
    const std::vector<const char*>& optional_extensions,
    bool allow_protected_memory,
    const GetPresentationSupportCallback& get_presentation_support,
    uint32_t heap_memory_limit,
    const bool is_thread_safe) {
  DCHECK_EQ(static_cast<VkPhysicalDevice>(VK_NULL_HANDLE), vk_physical_device_);
  DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), owned_vk_device_);
  DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
  DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), owned_vma_allocator_);
  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), vma_allocator_);
  DCHECK_EQ(nullptr, angle_display_);

  if (VK_NULL_HANDLE == vk_instance_)
    return false;

  const VulkanInfo& info = instance_->vulkan_info();

  VkResult result = VK_SUCCESS;

  VkQueueFlags queue_flags = 0;
  if (options & DeviceQueueOption::GRAPHICS_QUEUE_FLAG) {
    queue_flags |= VK_QUEUE_GRAPHICS_BIT;
  }
  if (allow_protected_memory) {
    queue_flags |= VK_QUEUE_PROTECTED_BIT;
  }

  // We prefer to use discrete GPU, integrated GPU is the second, and then
  // others.
  static constexpr auto kDeviceTypeScores = std::to_array<int>({
      0,  // VK_PHYSICAL_DEVICE_TYPE_OTHER
      3,  // VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
      4,  // VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
      2,  // VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU
      1,  // VK_PHYSICAL_DEVICE_TYPE_CPU
  });
  static_assert(VK_PHYSICAL_DEVICE_TYPE_OTHER == 0, "");
  static_assert(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU == 1, "");
  static_assert(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU == 2, "");
  static_assert(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU == 3, "");
  static_assert(VK_PHYSICAL_DEVICE_TYPE_CPU == 4, "");

  int device_index = -1;
  int queue_index = -1;
  int device_score = -1;
  for (size_t i = 0; i < info.physical_devices.size(); ++i) {
    const auto& device_info = info.physical_devices[i];
    const auto& device_properties = device_info.properties;
    if (device_properties.apiVersion < info.used_api_version)
      continue;

      // In dual-CPU cases, we cannot detect the active GPU correctly on Linux,
      // so don't select GPU device based on the |gpu_info|.
#if !BUILDFLAG(IS_LINUX)
    // If gpu_info is provided, the device should match it.
    if (gpu_info && (device_properties.vendorID != gpu_info->gpu.vendor_id ||
                     device_properties.deviceID != gpu_info->gpu.device_id)) {
      continue;
    }
#endif

    if (device_properties.deviceType < 0 ||
        device_properties.deviceType > VK_PHYSICAL_DEVICE_TYPE_CPU) {
      DLOG(ERROR) << "Unsupported device type: "
                  << device_properties.deviceType;
      continue;
    }

    const VkPhysicalDevice& device = device_info.device;
    bool found = false;
    for (size_t n = 0; n < device_info.queue_families.size(); ++n) {
      if ((device_info.queue_families[n].queueFlags & queue_flags) !=
          queue_flags) {
        continue;
      }

      if (options & DeviceQueueOption::PRESENTATION_SUPPORT_QUEUE_FLAG &&
          !get_presentation_support.Run(device, device_info.queue_families,
                                        n)) {
        continue;
      }

      if (kDeviceTypeScores[device_properties.deviceType] > device_score) {
        device_index = i;
        queue_index = static_cast<int>(n);
        device_score = kDeviceTypeScores[device_properties.deviceType];
        found = true;
        break;
      }
    }

    if (!found)
      continue;

    // Use the device, if it matches gpu_info.
    if (gpu_info)
      break;

    // If the device is a discrete GPU, we will use it. Otherwise go through
    // all the devices and find the device with the highest score.
    if (device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
      break;
  }

  if (device_index == -1) {
    DLOG(ERROR) << "Cannot find capable device.";
    return false;
  }

  const auto& physical_device_info = info.physical_devices[device_index];
  vk_physical_device_ = physical_device_info.device;
  vk_physical_device_properties_ = physical_device_info.properties;
  vk_physical_device_driver_properties_ =
      physical_device_info.driver_properties;
  drm_device_id_ = physical_device_info.drm_device_id;
  vk_queue_index_ = queue_index;

  float queue_priority = 0.0f;
  VkDeviceQueueCreateInfo queue_create_info = {};
  queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  queue_create_info.queueFamilyIndex = queue_index;
  queue_create_info.queueCount = 1;
  queue_create_info.pQueuePriorities = &queue_priority;
  queue_create_info.flags =
      allow_protected_memory ? VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT : 0;

  std::vector<const char*> enabled_extensions;
  for (const char* extension : required_extensions) {
    if (std::ranges::none_of(physical_device_info.extensions,
                             [extension](const VkExtensionProperties& p) {
                               return UNSAFE_TODO(std::strcmp(
                                          extension, p.extensionName)) == 0;
                             })) {
      // On Fuchsia, some device extensions are provided by layers.
      // TODO(penghuang): checking extensions against layer device extensions
      // too.
#if !BUILDFLAG(IS_FUCHSIA)
      DLOG(ERROR) << "Required Vulkan extension " << extension
                  << " is not supported.";
      return false;
#endif
    }
    enabled_extensions.push_back(extension);
  }

  for (const char* extension : optional_extensions) {
    if (std::ranges::none_of(physical_device_info.extensions,
                             [extension](const VkExtensionProperties& p) {
                               return UNSAFE_TODO(std::strcmp(
                                          extension, p.extensionName)) == 0;
                             })) {
      DLOG(ERROR) << "Optional Vulkan extension " << extension
                  << " is not supported.";
    } else {
      enabled_extensions.push_back(extension);
    }
  }

  crash_keys::vulkan_device_api_version.Set(
      VkVersionToString(vk_physical_device_properties_.apiVersion));
  if (vk_physical_device_properties_.vendorID == 0x10DE) {
    // NVIDIA
    // 10 bits = major version (up to r1023)
    // 8 bits = minor version (up to 255)
    // 8 bits = secondary branch version/build version (up to 255)
    // 6 bits = tertiary branch/build version (up to 63)
    auto version = vk_physical_device_properties_.driverVersion;
    uint32_t major = (version >> 22) & 0x3ff;
    uint32_t minor = (version >> 14) & 0x0ff;
    uint32_t secondary_branch = (version >> 6) & 0x0ff;
    uint32_t tertiary_branch = version & 0x003f;
    crash_keys::vulkan_device_driver_version.Set(base::StringPrintf(
        "%d.%d.%d.%d", major, minor, secondary_branch, tertiary_branch));
  } else {
    crash_keys::vulkan_device_driver_version.Set(
        VkVersionToString(vk_physical_device_properties_.driverVersion));
  }
  crash_keys::vulkan_device_vendor_id.Set(
      base::StringPrintf("0x%04x", vk_physical_device_properties_.vendorID));
  crash_keys::vulkan_device_id.Set(
      base::StringPrintf("0x%04x", vk_physical_device_properties_.deviceID));
  static auto kDeviceTypeNames = std::to_array<const char*>({
      "other",
      "integrated",
      "discrete",
      "virtual",
      "cpu",
  });
  uint32_t gpu_type = vk_physical_device_properties_.deviceType;
  if (gpu_type >= std::size(kDeviceTypeNames))
    gpu_type = 0;
  crash_keys::vulkan_device_type.Set(kDeviceTypeNames[gpu_type]);
  crash_keys::vulkan_device_name.Set(vk_physical_device_properties_.deviceName);

  // Disable all physical device features by default.
  enabled_device_features_2_ = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};

  // Android, Fuchsia, Linux, and CrOS (VaapiVideoDecoder) need YCbCr sampler
  // support.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX) || \
    BUILDFLAG(IS_CHROMEOS)
  if (!physical_device_info.feature_sampler_ycbcr_conversion) {
    LOG(ERROR) << "samplerYcbcrConversion is not supported.";
    return false;
  }
  sampler_ycbcr_conversion_features_ = {
      VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES};
  sampler_ycbcr_conversion_features_.samplerYcbcrConversion = VK_TRUE;

  // Add VkPhysicalDeviceSamplerYcbcrConversionFeatures struct to pNext chain
  // of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support.
  sampler_ycbcr_conversion_features_.pNext = enabled_device_features_2_.pNext;
  enabled_device_features_2_.pNext = &sampler_ycbcr_conversion_features_;
#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX)
        // || BUILDFLAG(IS_CHROMEOS)

  if (allow_protected_memory) {
    if (!physical_device_info.feature_protected_memory) {
      LOG(DFATAL)
          << "Protected memory is not supported. Vulkan is unavailable.";
      return false;
    }
    protected_memory_features_ = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES};
    protected_memory_features_.protectedMemory = VK_TRUE;

    // Add VkPhysicalDeviceProtectedMemoryFeatures struct to pNext chain
    // of VkPhysicalDeviceFeatures2 to enable YCbCr sampler support.
    protected_memory_features_.pNext = enabled_device_features_2_.pNext;
    enabled_device_features_2_.pNext = &protected_memory_features_;
  }

  // Add Skia features to query
  instance_->skia_features().addFeaturesToQuery(
      physical_device_info.extensions.data(),
      physical_device_info.extensions.size(), enabled_device_features_2_);

  // Query the physical device features.
  vkGetPhysicalDeviceFeatures2(vk_physical_device_,
                               &enabled_device_features_2_);

  // TODO(syoussefi): feature_sampler_ycbcr_conversion and
  // feature_protected_memory can be removed from physical_device_info and
  // checked after the vkGetPhysicalDeviceFeatures2 query here.

  // Enable Skia extensions and features
  instance_->skia_features().addFeaturesToEnable(enabled_extensions,
                                                 enabled_device_features_2_);

  VkDeviceCreateInfo device_create_info = {
      VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO};
  device_create_info.pNext = enabled_device_features_2_.pNext;
  device_create_info.queueCreateInfoCount = 1;
  device_create_info.pQueueCreateInfos = &queue_create_info;
  device_create_info.enabledExtensionCount = enabled_extensions.size();
  device_create_info.ppEnabledExtensionNames = enabled_extensions.data();
  device_create_info.pEnabledFeatures = &enabled_device_features_2_.features;

  result = vkCreateDevice(vk_physical_device_, &device_create_info, nullptr,
                          &owned_vk_device_);
  if (VK_SUCCESS != result) {
    DLOG(ERROR) << "vkCreateDevice failed. result:" << result;
    return false;
  }

  enabled_extensions_ = gfx::ExtensionSet(std::begin(enabled_extensions),
                                          std::end(enabled_extensions));

  if (!gpu::GetVulkanFunctionPointers()->BindDeviceFunctionPointers(
          owned_vk_device_, info.used_api_version, enabled_extensions_)) {
    vkDestroyDevice(owned_vk_device_, nullptr);
    owned_vk_device_ = VK_NULL_HANDLE;
    return false;
  }

  vk_device_ = owned_vk_device_;

  if (allow_protected_memory) {
    VkDeviceQueueInfo2 queue_info2 = {};
    queue_info2.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
    queue_info2.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
    queue_info2.queueFamilyIndex = queue_index;
    queue_info2.queueIndex = 0;
    vkGetDeviceQueue2(vk_device_, &queue_info2, &vk_queue_);
  } else {
    vkGetDeviceQueue(vk_device_, queue_index, 0, &vk_queue_);
  }

  std::vector<VkDeviceSize> heap_size_limit(
      VK_MAX_MEMORY_HEAPS,
      heap_memory_limit ? heap_memory_limit : VK_WHOLE_SIZE);
  vma::CreateAllocator(vk_physical_device_, vk_device_, vk_instance_,
                       enabled_extensions_, GetPreferredVMALargeHeapBlockSize(),
                       heap_size_limit.data(), is_thread_safe,
                       &owned_vma_allocator_);
  vma_allocator_ = owned_vma_allocator_;

  skia_vk_memory_allocator_ =
      sk_make_sp<gpu::SkiaVulkanMemoryAllocator>(vma_allocator_);

  cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);

  allow_protected_memory_ = allow_protected_memory;

#if BUILDFLAG(IS_ANDROID)
  if (!metric_) {
    metric_ = std::make_unique<VulkanMetric>(vma_allocator());
  }
#endif  // BUILDFLAG(IS_ANDROID)

  if (base::SingleThreadTaskRunner::HasCurrentDefault()) {
    base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
        this, "vulkan", base::SingleThreadTaskRunner::GetCurrentDefault());
  }

  return true;
}

bool VulkanDeviceQueue::InitCommon(VkPhysicalDevice vk_physical_device,
                                   VkDevice vk_device,
                                   VkQueue vk_queue,
                                   uint32_t vk_queue_index,
                                   gfx::ExtensionSet enabled_extensions) {
  DCHECK_EQ(static_cast<VkPhysicalDevice>(VK_NULL_HANDLE), vk_physical_device_);
  DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), owned_vk_device_);
  DCHECK_EQ(static_cast<VkDevice>(VK_NULL_HANDLE), vk_device_);
  DCHECK_EQ(static_cast<VkQueue>(VK_NULL_HANDLE), vk_queue_);
  DCHECK_EQ(static_cast<VmaAllocator>(VK_NULL_HANDLE), owned_vma_allocator_);

  vk_physical_device_ = vk_physical_device;
  vk_device_ = vk_device;
  vk_queue_ = vk_queue;
  vk_queue_index_ = vk_queue_index;
  enabled_extensions_ = std::move(enabled_extensions);

  if (vma_allocator_ == VK_NULL_HANDLE) {
    vma::CreateAllocator(vk_physical_device_, vk_device_, vk_instance_,
                         enabled_extensions_,
                         GetPreferredVMALargeHeapBlockSize(),
                         /*heap_size_limit=*/nullptr,
                         /*is_thread_safe =*/false, &owned_vma_allocator_);
    vma_allocator_ = owned_vma_allocator_;
#if BUILDFLAG(IS_ANDROID)
    if (!metric_) {
      metric_ = std::make_unique<VulkanMetric>(vma_allocator());
    }
#endif  // BUILDFLAG(IS_ANDROID)
  }

  skia_vk_memory_allocator_ =
      sk_make_sp<gpu::SkiaVulkanMemoryAllocator>(vma_allocator_);

  cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);

  if (base::SingleThreadTaskRunner::HasCurrentDefault()) {
    base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
        this, "vulkan", base::SingleThreadTaskRunner::GetCurrentDefault());
  }
  return true;
}

bool VulkanDeviceQueue::InitializeFromANGLE() {
  const VulkanInfo& info = instance_->vulkan_info();
  VkPhysicalDevice vk_physical_device = gl::QueryVkPhysicalDeviceFromANGLE();
  if (vk_physical_device == VK_NULL_HANDLE)
    return false;

  int device_index = -1;
  for (size_t i = 0; i < info.physical_devices.size(); ++i) {
    if (info.physical_devices[i].device == vk_physical_device) {
      device_index = i;
      break;
    }
  }

  if (device_index == -1) {
    DLOG(ERROR) << "Cannot find physical device match ANGLE.";
    return false;
  }

  const auto& physical_device_info = info.physical_devices[device_index];
  vk_physical_device_properties_ = physical_device_info.properties;
  vk_physical_device_driver_properties_ =
      physical_device_info.driver_properties;

  VkDevice vk_device = gl::QueryVkDeviceFromANGLE();
  VkQueue vk_queue = gl::QueryVkQueueFromANGLE();
  uint32_t vk_queue_index = gl::QueryVkQueueFramiliyIndexFromANGLE();
  auto enabled_extensions = gl::QueryVkDeviceExtensionsFromANGLE();

  if (!gpu::GetVulkanFunctionPointers()->BindDeviceFunctionPointers(
          vk_device, info.used_api_version, enabled_extensions)) {
    return false;
  }

  enabled_device_features_2_from_angle_ =
      gl::QueryVkEnabledDeviceFeaturesFromANGLE();
  if (!enabled_device_features_2_from_angle_)
    return false;

  angle_display_ = gl::QueryDisplayFromANGLE();
  return InitCommon(vk_physical_device, vk_device, vk_queue, vk_queue_index,
                    enabled_extensions);
}

bool VulkanDeviceQueue::InitializeForWebView(
    VkPhysicalDevice vk_physical_device,
    VkDevice vk_device,
    VkQueue vk_queue,
    uint32_t vk_queue_index,
    gfx::ExtensionSet enabled_extensions) {
  return InitCommon(vk_physical_device, vk_device, vk_queue, vk_queue_index,
                    enabled_extensions);
}

bool VulkanDeviceQueue::InitializeForCompositorGpuThread(
    VkPhysicalDevice vk_physical_device,
    VkDevice vk_device,
    VkQueue vk_queue,
    void* vk_queue_lock_context,
    uint32_t vk_queue_index,
    gfx::ExtensionSet enabled_extensions,
    const VkPhysicalDeviceFeatures2& vk_physical_device_features2,
    VmaAllocator vma_allocator) {
  // Currently VulkanDeviceQueue for drdc thread(aka CompositorGpuThread) uses
  // the same vulkan queue as the gpu main thread. Now since both gpu main and
  // drdc threads would be accessing/submitting work to the same queue, all the
  // queue access should be made thread safe. This is done by using locks. This
  // lock is per |vk_queue|. Note that we are intentionally overwriting a
  // previous lock if any.
  // Since the map itself would be accessed by multiple gpu threads, we need to
  // ensure that the access are thread safe. Here the locks are created and
  // written into the map only when drdc thread is initialized which happens
  // during GpuServiceImpl init. At this point none of the gpu threads would be
  // doing read access until GpuServiceImpl init completed. Hence its safe to
  // access map here.
  // If the Vulkan queue is queried from ANGLE, ANGLE's internal locking needs
  // to be used.
  GetVulkanFunctionPointers()->per_queue_lock_map[vk_queue] =
      std::make_unique<gpu::VulkanQueueLock>(vk_queue_lock_context);
  enabled_device_features_2_ = vk_physical_device_features2;

  // Note that CompositorGpuThread uses same vma allocator as gpu main thread.
  vma_allocator_ = vma_allocator;
  return InitCommon(vk_physical_device, vk_device, vk_queue, vk_queue_index,
                    enabled_extensions);
}

void VulkanDeviceQueue::Destroy() {
  base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
      this);
#if BUILDFLAG(IS_ANDROID)
  metric_ = nullptr;
#endif

  if (cleanup_helper_) {
    cleanup_helper_->Destroy();
    cleanup_helper_.reset();
  }

  if (owned_vma_allocator_ != VK_NULL_HANDLE) {
    vma::DestroyAllocator(owned_vma_allocator_);
    owned_vma_allocator_ = VK_NULL_HANDLE;
  }

  if (owned_vk_device_ != VK_NULL_HANDLE) {
    vkDestroyDevice(owned_vk_device_, nullptr);
    owned_vk_device_ = VK_NULL_HANDLE;

    // Clear all the entries from this map since the device and hence all the
    // generated queue(and their corresponding lock) from this device is
    // destroyed.
    // This happens when VulkanDeviceQueue is destroyed on gpu main thread
    // during GpuServiceImpl destruction which happens after CompositorGpuThread
    // is destroyed. Hence CompositorGpuThread would not be accessing the map at
    // this point and its thread safe to delete map entries here.
    GetVulkanFunctionPointers()->per_queue_lock_map.clear();
  }
  vk_device_ = VK_NULL_HANDLE;
  vk_queue_ = VK_NULL_HANDLE;
  vk_queue_index_ = 0;
  vk_physical_device_ = VK_NULL_HANDLE;
  vma_allocator_ = VK_NULL_HANDLE;
}

std::unique_ptr<VulkanCommandPool> VulkanDeviceQueue::CreateCommandPool() {
  std::unique_ptr<VulkanCommandPool> command_pool(new VulkanCommandPool(this));
  if (!command_pool->Initialize())
    return nullptr;

  return command_pool;
}

bool VulkanDeviceQueue::OnMemoryDump(
    const base::trace_event::MemoryDumpArgs& args,
    base::trace_event::ProcessMemoryDump* pmd) {
  std::string path =
      base::StringPrintf("gpu/vulkan/vma_allocator_%p", vma_allocator());
  // There are cases where the same VMA is used by several device queues. Make
  // sure to not double count by using the VMA address in the path.
  //
  // This is still a success case, as the other device queue may disappear, so
  // return true.
  if (pmd->GetAllocatorDump(path)) {
    return true;
  }

  auto* dump = pmd->CreateAllocatorDump(path);
  auto allocated_used = vma::GetTotalAllocatedAndUsedMemory(vma_allocator());
  uint32_t lazy_allocated_size =
      skia_vk_memory_allocator_->totalLazyAllocatedMemory();
  // `allocated_size` is memory allocated from the device, used is what is
  // actually used. `lazy_allocated_size` is transient memory that is lazily
  // allocated by the driver.
  dump->AddScalar("allocated_size", "bytes",
                  allocated_used.first - lazy_allocated_size);
  dump->AddScalar("used_size", "bytes",
                  allocated_used.second - lazy_allocated_size);
  dump->AddScalar("fragmentation_size", "bytes",
                  allocated_used.first - allocated_used.second);
  dump->AddScalar("lazy_allocated_size", "bytes", lazy_allocated_size);
  dump->AddScalar("lazy_used_size", "bytes", lazy_allocated_size);
  return true;
}

}  // namespace gpu
