• 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 #ifdef RS_ENABLE_VK
10 #include "flutter/vulkan/vulkan_hilog.h"
11 #endif
12 #include "flutter/vulkan/vulkan_proc_table.h"
13 #include "third_party/skia/include/gpu/vk/GrVkTypes.h"
14 #include "vulkan/vulkan.h"
15 
16 namespace vulkan {
17 
VulkanBackbuffer(const VulkanProcTable & p_vk,const VulkanHandle<VkDevice> & device,const VulkanHandle<VkCommandPool> & pool)18 VulkanBackbuffer::VulkanBackbuffer(const VulkanProcTable& p_vk,
19                                    const VulkanHandle<VkDevice>& device,
20                                    const VulkanHandle<VkCommandPool>& pool)
21     : vk(p_vk),
22       device_(device),
23       usage_command_buffer_(p_vk, device, pool),
24       render_command_buffer_(p_vk, device, pool),
25       valid_(false) {
26   if (!usage_command_buffer_.IsValid() || !render_command_buffer_.IsValid()) {
27 #ifdef RS_ENABLE_VK
28     LOGE("Command buffers were not valid.");
29 #else
30     FML_DLOG(INFO) << "Command buffers were not valid.";
31 #endif
32     return;
33   }
34 
35   if (!CreateSemaphores()) {
36 #ifdef RS_ENABLE_VK
37     LOGE("Could not create semaphores.");
38 #else
39     FML_DLOG(INFO) << "Could not create semaphores.";
40 #endif
41     return;
42   }
43 
44   if (!CreateFences()) {
45 #ifdef RS_ENABLE_VK
46     LOGE("Could not create fences.");
47 #else
48     FML_DLOG(INFO) << "Could not create fences.";
49 #endif
50     return;
51   }
52 
53   valid_ = true;
54 }
55 
~VulkanBackbuffer()56 VulkanBackbuffer::~VulkanBackbuffer() {
57 #ifdef RS_ENABLE_VK
58   WaitFences();
59 #else
60   FML_ALLOW_UNUSED_LOCAL(WaitFences());
61 #endif
62 }
63 
IsValid() const64 bool VulkanBackbuffer::IsValid() const {
65   return valid_;
66 }
67 
CreateSemaphores()68 bool VulkanBackbuffer::CreateSemaphores() {
69   const VkSemaphoreCreateInfo create_info = {
70       .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
71       .pNext = nullptr,
72       .flags = 0,
73   };
74 
75   auto semaphore_collect = [this](VkSemaphore semaphore) {
76     vk.DestroySemaphore(device_, semaphore, nullptr);
77   };
78 
79   for (size_t i = 0; i < semaphores_.size(); i++) {
80     VkSemaphore semaphore = VK_NULL_HANDLE;
81 
82     if (VK_CALL_LOG_ERROR(vk.CreateSemaphore(device_, &create_info, nullptr,
83                                              &semaphore)) != VK_SUCCESS) {
84       return false;
85     }
86 
87     semaphores_[i] = {semaphore, semaphore_collect};
88   }
89 
90   return true;
91 }
92 
CreateFences()93 bool VulkanBackbuffer::CreateFences() {
94   const VkFenceCreateInfo create_info = {
95       .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
96       .pNext = nullptr,
97       .flags = VK_FENCE_CREATE_SIGNALED_BIT,
98   };
99 
100   auto fence_collect = [this](VkFence fence) {
101     vk.DestroyFence(device_, fence, nullptr);
102   };
103 
104   for (size_t i = 0; i < use_fences_.size(); i++) {
105     VkFence fence = VK_NULL_HANDLE;
106 
107     if (VK_CALL_LOG_ERROR(vk.CreateFence(device_, &create_info, nullptr,
108                                          &fence)) != VK_SUCCESS) {
109       return false;
110     }
111 
112     use_fences_[i] = {fence, fence_collect};
113   }
114 
115   return true;
116 }
117 
WaitFences()118 bool VulkanBackbuffer::WaitFences() {
119   VkFence fences[use_fences_.size()];
120 
121   for (size_t i = 0; i < use_fences_.size(); i++) {
122     fences[i] = use_fences_[i];
123   }
124 
125   return VK_CALL_LOG_ERROR(vk.WaitForFences(
126              device_, static_cast<uint32_t>(use_fences_.size()), fences, true,
127              std::numeric_limits<uint64_t>::max())) == VK_SUCCESS;
128 }
129 
ResetFences()130 bool VulkanBackbuffer::ResetFences() {
131   VkFence fences[use_fences_.size()];
132 
133   for (size_t i = 0; i < use_fences_.size(); i++) {
134     fences[i] = use_fences_[i];
135   }
136 
137   return VK_CALL_LOG_ERROR(vk.ResetFences(
138              device_, static_cast<uint32_t>(use_fences_.size()), fences)) ==
139          VK_SUCCESS;
140 }
141 
GetUsageFence() const142 const VulkanHandle<VkFence>& VulkanBackbuffer::GetUsageFence() const {
143   return use_fences_[0];
144 }
145 
GetRenderFence() const146 const VulkanHandle<VkFence>& VulkanBackbuffer::GetRenderFence() const {
147   return use_fences_[1];
148 }
149 
GetUsageSemaphore() const150 const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetUsageSemaphore() const {
151   return semaphores_[0];
152 }
153 
GetRenderSemaphore() const154 const VulkanHandle<VkSemaphore>& VulkanBackbuffer::GetRenderSemaphore() const {
155   return semaphores_[1];
156 }
157 
GetUsageCommandBuffer()158 VulkanCommandBuffer& VulkanBackbuffer::GetUsageCommandBuffer() {
159   return usage_command_buffer_;
160 }
161 
GetRenderCommandBuffer()162 VulkanCommandBuffer& VulkanBackbuffer::GetRenderCommandBuffer() {
163   return render_command_buffer_;
164 }
165 
166 }  // namespace vulkan
167