vulkan_backbuffer.cc 3.8 KB
Newer Older
1 2 3 4
// Copyright 2016 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.

5
#include "flutter/vulkan/vulkan_backbuffer.h"
6 7 8

#include <limits>

9 10
#include "flutter/vulkan/vulkan_proc_table.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h"
11
#include "vulkan/vulkan.h"
12

13 14
namespace vulkan {

15 16 17
VulkanBackbuffer::VulkanBackbuffer(const VulkanProcTable& p_vk,
                                   const VulkanHandle<VkDevice>& device,
                                   const VulkanHandle<VkCommandPool>& pool)
18 19
    : vk(p_vk),
      device_(device),
20 21
      usage_command_buffer_(p_vk, device, pool),
      render_command_buffer_(p_vk, device, pool),
22
      valid_(false) {
23
  if (!usage_command_buffer_.IsValid() || !render_command_buffer_.IsValid()) {
24
    FML_DLOG(INFO) << "Command buffers were not valid.";
25 26 27 28
    return;
  }

  if (!CreateSemaphores()) {
29
    FML_DLOG(INFO) << "Could not create semaphores.";
30 31 32 33
    return;
  }

  if (!CreateFences()) {
34
    FML_DLOG(INFO) << "Could not create fences.";
35 36 37 38 39 40 41
    return;
  }

  valid_ = true;
}

VulkanBackbuffer::~VulkanBackbuffer() {
42
  FML_ALLOW_UNUSED_LOCAL(WaitFences());
43 44 45 46 47 48 49 50 51 52 53 54 55 56
}

bool VulkanBackbuffer::IsValid() const {
  return valid_;
}

bool VulkanBackbuffer::CreateSemaphores() {
  const VkSemaphoreCreateInfo create_info = {
      .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
      .pNext = nullptr,
      .flags = 0,
  };

  auto semaphore_collect = [this](VkSemaphore semaphore) {
57
    vk.DestroySemaphore(device_, semaphore, nullptr);
58 59 60 61 62
  };

  for (size_t i = 0; i < semaphores_.size(); i++) {
    VkSemaphore semaphore = VK_NULL_HANDLE;

63 64
    if (VK_CALL_LOG_ERROR(vk.CreateSemaphore(device_, &create_info, nullptr,
                                             &semaphore)) != VK_SUCCESS) {
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
      return false;
    }

    semaphores_[i] = {semaphore, semaphore_collect};
  }

  return true;
}

bool VulkanBackbuffer::CreateFences() {
  const VkFenceCreateInfo create_info = {
      .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
      .pNext = nullptr,
      .flags = VK_FENCE_CREATE_SIGNALED_BIT,
  };

  auto fence_collect = [this](VkFence fence) {
82
    vk.DestroyFence(device_, fence, nullptr);
83 84 85 86 87
  };

  for (size_t i = 0; i < use_fences_.size(); i++) {
    VkFence fence = VK_NULL_HANDLE;

88 89
    if (VK_CALL_LOG_ERROR(vk.CreateFence(device_, &create_info, nullptr,
                                         &fence)) != VK_SUCCESS) {
90 91 92 93 94 95 96 97 98
      return false;
    }

    use_fences_[i] = {fence, fence_collect};
  }

  return true;
}

99 100 101 102 103 104 105 106 107 108 109 110 111
bool VulkanBackbuffer::WaitFences() {
  VkFence fences[use_fences_.size()];

  for (size_t i = 0; i < use_fences_.size(); i++) {
    fences[i] = use_fences_[i];
  }

  return VK_CALL_LOG_ERROR(vk.WaitForFences(
             device_, static_cast<uint32_t>(use_fences_.size()), fences, true,
             std::numeric_limits<uint64_t>::max())) == VK_SUCCESS;
}

bool VulkanBackbuffer::ResetFences() {
112 113 114 115 116 117
  VkFence fences[use_fences_.size()];

  for (size_t i = 0; i < use_fences_.size(); i++) {
    fences[i] = use_fences_[i];
  }

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
  return VK_CALL_LOG_ERROR(vk.ResetFences(
             device_, static_cast<uint32_t>(use_fences_.size()), fences)) ==
         VK_SUCCESS;
}

const VulkanHandle<VkFence>& VulkanBackbuffer::GetUsageFence() const {
  return use_fences_[0];
}

const VulkanHandle<VkFence>& VulkanBackbuffer::GetRenderFence() const {
  return use_fences_[1];
}

const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetUsageSemaphore() const {
  return semaphores_[0];
}

const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetRenderSemaphore() const {
  return semaphores_[1];
}

VulkanCommandBuffer& VulkanBackbuffer::GetUsageCommandBuffer() {
  return usage_command_buffer_;
}

VulkanCommandBuffer& VulkanBackbuffer::GetRenderCommandBuffer() {
  return render_command_buffer_;
145 146 147
}

}  // namespace vulkan