Flutter Engine
vulkan::VulkanWindow Class Reference

#include <vulkan_window.h>

Public Member Functions

 VulkanWindow (fml::RefPtr< VulkanProcTable > proc_table, std::unique_ptr< VulkanNativeSurface > native_surface, bool render_to_surface)
 
 ~VulkanWindow ()
 
bool IsValid () const
 
GrDirectContext * GetSkiaGrContext ()
 
sk_sp< SkSurface > AcquireSurface ()
 
bool SwapBuffers ()
 

Detailed Description

Definition at line 32 of file vulkan_window.h.

Constructor & Destructor Documentation

◆ VulkanWindow()

vulkan::VulkanWindow::VulkanWindow ( fml::RefPtr< VulkanProcTable proc_table,
std::unique_ptr< VulkanNativeSurface native_surface,
bool  render_to_surface 
)

Definition at line 21 of file vulkan_window.cc.

References FML_DLOG, and ~VulkanWindow().

24  : valid_(false), vk(std::move(proc_table)) {
25  if (!vk || !vk->HasAcquiredMandatoryProcAddresses()) {
26  FML_DLOG(INFO) << "Proc table has not acquired mandatory proc addresses.";
27  return;
28  }
29 
30  if (native_surface == nullptr || !native_surface->IsValid()) {
31  FML_DLOG(INFO) << "Native surface is invalid.";
32  return;
33  }
34 
35  // Create the application instance.
36 
37  std::vector<std::string> extensions = {
38  VK_KHR_SURFACE_EXTENSION_NAME, // parent extension
39  native_surface->GetExtensionName() // child extension
40  };
41 
42  application_ = std::make_unique<VulkanApplication>(*vk, "Flutter",
43  std::move(extensions));
44 
45  if (!application_->IsValid() || !vk->AreInstanceProcsSetup()) {
46  // Make certain the application instance was created and it setup the
47  // instance proc table entries.
48  FML_DLOG(INFO) << "Instance proc addresses have not been setup.";
49  return;
50  }
51 
52  // Create the device.
53 
54  logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();
55 
56  if (logical_device_ == nullptr || !logical_device_->IsValid() ||
57  !vk->AreDeviceProcsSetup()) {
58  // Make certain the device was created and it setup the device proc table
59  // entries.
60  FML_DLOG(INFO) << "Device proc addresses have not been setup.";
61  return;
62  }
63 
64  // TODO(38466): Refactor GPU surface APIs take into account the fact that an
65  // external view embedder may want to render to the root surface.
66  if (!render_to_surface) {
67  return;
68  }
69 
70  // Create the logical surface from the native platform surface.
71  surface_ = std::make_unique<VulkanSurface>(*vk, *application_,
72  std::move(native_surface));
73 
74  if (!surface_->IsValid()) {
75  FML_DLOG(INFO) << "Vulkan surface is invalid.";
76  return;
77  }
78 
79  // Create the Skia GrDirectContext.
80 
81  if (!CreateSkiaGrContext()) {
82  FML_DLOG(INFO) << "Could not create Skia context.";
83  return;
84  }
85 
86  // Create the swapchain.
87 
88  if (!RecreateSwapchain()) {
89  FML_DLOG(INFO) << "Could not setup the swapchain initially.";
90  return;
91  }
92 
93  valid_ = true;
94 }
#define FML_DLOG(severity)
Definition: logging.h:85

◆ ~VulkanWindow()

vulkan::VulkanWindow::~VulkanWindow ( )
default

Referenced by VulkanWindow().

Member Function Documentation

◆ AcquireSurface()

sk_sp< SkSurface > vulkan::VulkanWindow::AcquireSurface ( )

Definition at line 153 of file vulkan_window.cc.

References vulkan::VulkanSwapchain::ErrorSurfaceLost, vulkan::VulkanSwapchain::ErrorSurfaceOutOfDate, FML_DCHECK, FML_DLOG, IsValid(), and vulkan::VulkanSwapchain::Success.

Referenced by flutter::GPUSurfaceVulkan::AcquireFrame().

153  {
154  if (!IsValid()) {
155  FML_DLOG(INFO) << "Surface is invalid.";
156  return nullptr;
157  }
158 
159  auto surface_size = surface_->GetSize();
160 
161  // This check is theoretically unnecessary as the swapchain should report that
162  // the surface is out-of-date and perform swapchain recreation at the new
163  // configuration. However, on Android, the swapchain never reports that it is
164  // of date. Hence this extra check. Platforms that don't have this issue, or,
165  // cant report this information (which is optional anyway), report a zero
166  // size.
167  if (surface_size != SkISize::Make(0, 0) &&
168  surface_size != swapchain_->GetSize()) {
169  FML_DLOG(INFO) << "Swapchain and surface sizes are out of sync. Recreating "
170  "swapchain.";
171  if (!RecreateSwapchain()) {
172  FML_DLOG(INFO) << "Could not recreate swapchain.";
173  valid_ = false;
174  return nullptr;
175  }
176  }
177 
178  while (true) {
179  sk_sp<SkSurface> surface;
181 
182  std::tie(acquire_result, surface) = swapchain_->AcquireSurface();
183 
184  if (acquire_result == VulkanSwapchain::AcquireStatus::Success) {
185  // Successfully acquired a surface from the swapchain. Nothing more to do.
186  return surface;
187  }
188 
189  if (acquire_result == VulkanSwapchain::AcquireStatus::ErrorSurfaceLost) {
190  // Surface is lost. This is an unrecoverable error.
191  FML_DLOG(INFO) << "Swapchain reported surface was lost.";
192  return nullptr;
193  }
194 
195  if (acquire_result ==
197  // Surface out of date. Recreate the swapchain at the new configuration.
198  if (RecreateSwapchain()) {
199  // Swapchain was recreated, try surface acquisition again.
200  continue;
201  } else {
202  // Could not recreate the swapchain at the new configuration.
203  FML_DLOG(INFO) << "Swapchain reported surface was out of date but "
204  "could not recreate the swapchain at the new "
205  "configuration.";
206  valid_ = false;
207  return nullptr;
208  }
209  }
210 
211  break;
212  }
213 
214  FML_DCHECK(false) << "Unhandled VulkanSwapchain::AcquireResult";
215  return nullptr;
216 }
#define FML_DCHECK(condition)
Definition: logging.h:86
bool IsValid() const
#define FML_DLOG(severity)
Definition: logging.h:85
A valid SkSurface was acquired successfully from the swapchain.

◆ GetSkiaGrContext()

GrDirectContext * vulkan::VulkanWindow::GetSkiaGrContext ( )

Definition at line 102 of file vulkan_window.cc.

References vulkan::kGrCacheMaxByteSize, and vulkan::kGrCacheMaxCount.

Referenced by flutter::GPUSurfaceVulkan::GetContext().

102  {
103  return skia_gr_context_.get();
104 }

◆ IsValid()

bool vulkan::VulkanWindow::IsValid ( ) const

Definition at line 98 of file vulkan_window.cc.

Referenced by AcquireSurface(), flutter::GPUSurfaceVulkan::IsValid(), and SwapBuffers().

98  {
99  return valid_;
100 }

◆ SwapBuffers()

bool vulkan::VulkanWindow::SwapBuffers ( )

Definition at line 218 of file vulkan_window.cc.

References FML_DLOG, and IsValid().

218  {
219  if (!IsValid()) {
220  FML_DLOG(INFO) << "Window was invalid.";
221  return false;
222  }
223 
224  return swapchain_->Submit();
225 }
bool IsValid() const
#define FML_DLOG(severity)
Definition: logging.h:85

The documentation for this class was generated from the following files: