13#include "flutter/flutter_vma/flutter_skia_vma.h"
14#include "flutter/vulkan/vulkan_skia_proc_table.h"
29 std::unique_ptr<VulkanNativeSurface> native_surface)
30 : VulkanWindow( nullptr,
31 std::move(proc_table),
32 std::move(native_surface)) {}
36 std::unique_ptr<VulkanNativeSurface> native_surface)
37 : valid_(
false), vk_(
std::move(proc_table)), skia_gr_context_(context) {
38 if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) {
39 FML_DLOG(INFO) <<
"Proc table has not acquired mandatory proc addresses.";
43 if (native_surface && !native_surface->IsValid()) {
44 FML_DLOG(INFO) <<
"Native surface is invalid.";
52 native_surface->GetExtensionName()
55 application_ = std::make_unique<VulkanApplication>(*vk_,
"Flutter",
58 if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) {
61 FML_DLOG(INFO) <<
"Instance proc addresses have not been set up.";
67 logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();
69 if (logical_device_ ==
nullptr || !logical_device_->IsValid() ||
70 !vk_->AreDeviceProcsSetup()) {
73 FML_DLOG(INFO) <<
"Device proc addresses have not been set up.";
77 if (!native_surface) {
82 surface_ = std::make_unique<VulkanSurface>(*vk_, *application_,
83 std::move(native_surface));
86 FML_DLOG(INFO) <<
"Vulkan surface is invalid.";
92 application_->GetAPIVersion(), application_->GetInstance(),
93 logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(),
98 if (!skia_gr_context_ && !CreateSkiaGrContext()) {
99 FML_DLOG(INFO) <<
"Could not create Skia context.";
105 if (!RecreateSwapchain()) {
106 FML_DLOG(INFO) <<
"Could not set up the swapchain initially.";
113VulkanWindow::~VulkanWindow() =
default;
115bool VulkanWindow::IsValid()
const {
120 return skia_gr_context_.get();
123bool VulkanWindow::CreateSkiaGrContext() {
129 if (!this->CreateSkiaBackendContext(&backend_context, &features,
139 if (context ==
nullptr) {
145 skia_gr_context_ = context;
153bool VulkanWindow::CreateSkiaBackendContext(
163 if (getProc ==
nullptr) {
167 if (!logical_device_->GetPhysicalDeviceFeatures(features)) {
171 context->
fInstance = application_->GetInstance();
173 context->
fDevice = logical_device_->GetHandle();
174 context->
fQueue = logical_device_->GetQueueHandle();
178 context->
fGetProc = std::move(getProc);
181 constexpr uint32_t instance_extension_count = 2;
182 const char* instance_extensions[instance_extension_count] = {
185 surface_->GetNativeSurface().GetExtensionName(),
187 constexpr uint32_t device_extension_count = 1;
188 const char* device_extensions[device_extension_count] = {
194 instance_extensions, device_extension_count,
205 FML_DLOG(INFO) <<
"Surface is invalid.";
209 auto surface_size =
surface_->GetSize();
218 surface_size != swapchain_->GetSize()) {
219 FML_DLOG(INFO) <<
"Swapchain and surface sizes are out of sync. Recreating "
221 if (!RecreateSwapchain()) {
222 FML_DLOG(INFO) <<
"Could not recreate swapchain.";
230 auto acquire_result = VulkanSwapchain::AcquireStatus::ErrorSurfaceLost;
232 std::tie(acquire_result,
surface) = swapchain_->AcquireSurface();
234 if (acquire_result == VulkanSwapchain::AcquireStatus::Success) {
239 if (acquire_result == VulkanSwapchain::AcquireStatus::ErrorSurfaceLost) {
241 FML_DLOG(INFO) <<
"Swapchain reported surface was lost.";
245 if (acquire_result ==
246 VulkanSwapchain::AcquireStatus::ErrorSurfaceOutOfDate) {
248 if (RecreateSwapchain()) {
253 FML_DLOG(INFO) <<
"Swapchain reported surface was out of date but "
254 "could not recreate the swapchain at the new "
264 FML_DCHECK(
false) <<
"Unhandled VulkanSwapchain::AcquireResult";
268bool VulkanWindow::SwapBuffers() {
270 FML_DLOG(INFO) <<
"Window was invalid.";
274 return swapchain_->Submit();
277bool VulkanWindow::RecreateSwapchain() {
280 auto old_swapchain = std::move(swapchain_);
282 if (!vk_->IsValid()) {
286 if (logical_device_ ==
nullptr || !logical_device_->IsValid()) {
294 if (skia_gr_context_ ==
nullptr) {
298 auto swapchain = std::make_unique<VulkanSwapchain>(
299 *vk_, *logical_device_, *
surface_, skia_gr_context_.get(),
300 std::move(old_swapchain), logical_device_->GetGraphicsQueueIndex());
void setResourceCacheLimit(size_t maxResourceBytes)
static sk_sp< VulkanMemoryAllocator > Make(uint32_t vulkan_api_version, VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, const fml::RefPtr< vulkan::VulkanProcTable > &vk, bool mustUseCoherentHostVisibleMemory)
VulkanWindow(fml::RefPtr< VulkanProcTable > proc_table, std::unique_ptr< VulkanNativeSurface > native_surface)
Construct a VulkanWindow. Let it implicitly create a GrDirectContext.
#define FML_DLOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
SK_API sk_sp< GrDirectContext > MakeVulkan(const skgpu::VulkanBackendContext &, const GrContextOptions &)
static const size_t kGrCacheMaxByteSize
GrVkGetProc CreateSkiaGetProc(const fml::RefPtr< vulkan::VulkanProcTable > &vk)
static constexpr SkISize Make(int32_t w, int32_t h)
sk_sp< VulkanMemoryAllocator > fMemoryAllocator
const VkPhysicalDeviceFeatures * fDeviceFeatures
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
VkPhysicalDevice fPhysicalDevice
const skgpu::VulkanExtensions * fVkExtensions
#define VK_KHR_SURFACE_EXTENSION_NAME
#define VK_KHR_SWAPCHAIN_EXTENSION_NAME