• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/vulkan/vulkan_backbuffer.h"
6 
7 #include <limits>
8 
9 #include "flutter/vulkan/vulkan_proc_table.h"
10 #include "third_party/skia/include/gpu/vk/GrVkTypes.h"
11 #include "vulkan/vulkan.h"
12 
13 namespace vulkan {
14 
VulkanBackbuffer(const VulkanProcTable & p_vk,const VulkanHandle<VkDevice> & device,const VulkanHandle<VkCommandPool> & pool)15 VulkanBackbuffer::VulkanBackbuffer(const VulkanProcTable& p_vk,
16                                    const VulkanHandle<VkDevice>& device,
17                                    const VulkanHandle<VkCommandPool>& pool)
18     : vk(p_vk),
19       device_(device),
20       usage_command_buffer_(p_vk, device, pool),
21       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     return;
26   }
27 
28   if (!CreateSemaphores()) {
29     FML_DLOG(INFO) << "Could not create semaphores.";
30     return;
31   }
32 
33   if (!CreateFences()) {
34     FML_DLOG(INFO) << "Could not create fences.";
35     return;
36   }
37 
38   valid_ = true;
39 }
40 
~VulkanBackbuffer()41 VulkanBackbuffer::~VulkanBackbuffer() {
42   FML_ALLOW_UNUSED_LOCAL(WaitFences());
43 }
44 
IsValid() const45 bool VulkanBackbuffer::IsValid() const {
46   return valid_;
47 }
48 
CreateSemaphores()49 bool VulkanBackbuffer::CreateSemaphores() {
50   const VkSemaphoreCreateInfo create_info = {
51       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
52       .pNext = nullptr,
53       .flags = 0,
54   };
55 
56   auto semaphore_collect = [this](VkSemaphore semaphore) {
57     vk.DestroySemaphore(device_, semaphore, nullptr);
58   };
59 
60   for (size_t i = 0; i < semaphores_.size(); i++) {
61     VkSemaphore semaphore = VK_NULL_HANDLE;
62 
63     if (VK_CALL_LOG_ERROR(vk.CreateSemaphore(device_, &create_info, nullptr,
64                                              &semaphore)) != VK_SUCCESS) {
65       return false;
66     }
67 
68     semaphores_[i] = {semaphore, semaphore_collect};
69   }
70 
71   return true;
72 }
73 
CreateFences()74 bool VulkanBackbuffer::CreateFences() {
75   const VkFenceCreateInfo create_info = {
76       .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
77       .pNext = nullptr,
78       .flags = VK_FENCE_CREATE_SIGNALED_BIT,
79   };
80 
81   auto fence_collect = [this](VkFence fence) {
82     vk.DestroyFence(device_, fence, nullptr);
83   };
84 
85   for (size_t i = 0; i < use_fences_.size(); i++) {
86     VkFence fence = VK_NULL_HANDLE;
87 
88     if (VK_CALL_LOG_ERROR(vk.CreateFence(device_, &create_info, nullptr,
89                                          &fence)) != VK_SUCCESS) {
90       return false;
91     }
92 
93     use_fences_[i] = {fence, fence_collect};
94   }
95 
96   return true;
97 }
98 
WaitFences()99 bool VulkanBackbuffer::WaitFences() {
100   VkFence fences[use_fences_.size()];
101 
102   for (size_t i = 0; i < use_fences_.size(); i++) {
103     fences[i] = use_fences_[i];
104   }
105 
106   return VK_CALL_LOG_ERROR(vk.WaitForFences(
107              device_, static_cast<uint32_t>(use_fences_.size()), fences, true,
108              std::numeric_limits<uint64_t>::max())) == VK_SUCCESS;
109 }
110 
ResetFences()111 bool VulkanBackbuffer::ResetFences() {
112   VkFence fences[use_fences_.size()];
113 
114   for (size_t i = 0; i < use_fences_.size(); i++) {
115     fences[i] = use_fences_[i];
116   }
117 
118   return VK_CALL_LOG_ERROR(vk.ResetFences(
119              device_, static_cast<uint32_t>(use_fences_.size()), fences)) ==
120          VK_SUCCESS;
121 }
122 
GetUsageFence() const123 const VulkanHandle<VkFence>& VulkanBackbuffer::GetUsageFence() const {
124   return use_fences_[0];
125 }
126 
GetRenderFence() const127 const VulkanHandle<VkFence>& VulkanBackbuffer::GetRenderFence() const {
128   return use_fences_[1];
129 }
130 
GetUsageSemaphore() const131 const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetUsageSemaphore() const {
132   return semaphores_[0];
133 }
134 
GetRenderSemaphore() const135 const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetRenderSemaphore() const {
136   return semaphores_[1];
137 }
138 
GetUsageCommandBuffer()139 VulkanCommandBuffer& VulkanBackbuffer::GetUsageCommandBuffer() {
140   return usage_command_buffer_;
141 }
142 
GetRenderCommandBuffer()143 VulkanCommandBuffer& VulkanBackbuffer::GetRenderCommandBuffer() {
144   return render_command_buffer_;
145 }
146 
147 }  // namespace vulkan
148