Flutter Impeller
playground_impl_vk.cc
Go to the documentation of this file.
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 
6 
7 #include "flutter/fml/paths.h"
9 
10 #define GLFW_INCLUDE_VULKAN
11 #include <GLFW/glfw3.h>
12 
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/mapping.h"
15 #include "impeller/entity/vk/entity_shaders_vk.h"
16 #include "impeller/entity/vk/modern_shaders_vk.h"
17 #include "impeller/fixtures/vk/fixtures_shaders_vk.h"
18 #include "impeller/playground/imgui/vk/imgui_shaders_vk.h"
24 #include "impeller/renderer/vk/compute_shaders_vk.h"
25 #include "impeller/scene/shaders/vk/scene_shaders_vk.h"
26 
27 namespace impeller {
28 
29 static std::vector<std::shared_ptr<fml::Mapping>>
31  return {
32  std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
33  impeller_entity_shaders_vk_length),
34  std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
35  impeller_modern_shaders_vk_length),
36  std::make_shared<fml::NonOwnedMapping>(
37  impeller_fixtures_shaders_vk_data,
38  impeller_fixtures_shaders_vk_length),
39  std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_vk_data,
40  impeller_imgui_shaders_vk_length),
41  std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
42  impeller_scene_shaders_vk_length),
43  std::make_shared<fml::NonOwnedMapping>(
44  impeller_compute_shaders_vk_data, impeller_compute_shaders_vk_length),
45  };
46 }
47 
48 void PlaygroundImplVK::DestroyWindowHandle(WindowHandle handle) {
49  if (!handle) {
50  return;
51  }
52  ::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle));
53 }
54 
56  : PlaygroundImpl(switches), handle_(nullptr, &DestroyWindowHandle) {
57  if (!::glfwVulkanSupported()) {
58 #ifdef TARGET_OS_MAC
59  VALIDATION_LOG << "Attempted to initialize a Vulkan playground on macOS "
60  "where Vulkan cannot be found. It can be installed via "
61  "MoltenVK and make sure to install it globally so "
62  "dlopen can find it.";
63 #else
64  VALIDATION_LOG << "Attempted to initialize a Vulkan playground on a system "
65  "that does not support Vulkan.";
66 #endif
67  return;
68  }
69 
70  ::glfwDefaultWindowHints();
71  ::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
72  ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
73 
74  auto window = ::glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
75  if (!window) {
76  VALIDATION_LOG << "Unable to create glfw window";
77  return;
78  }
79 
80  handle_.reset(window);
81 
82  ContextVK::Settings context_settings;
83  context_settings.proc_address_callback =
84  reinterpret_cast<PFN_vkGetInstanceProcAddr>(
85  &::glfwGetInstanceProcAddress);
87  context_settings.cache_directory = fml::paths::GetCachesDirectory();
89 
90  auto context_vk = ContextVK::Create(std::move(context_settings));
91  if (!context_vk || !context_vk->IsValid()) {
92  VALIDATION_LOG << "Could not create Vulkan context in the playground.";
93  return;
94  }
95 
96  // Without this, the playground will timeout waiting for the presentation.
97  // It's better to have some Vulkan validation tests running on CI to catch
98  // regressions, but for now this is a workaround.
99  //
100  // TODO(matanlurey): https://github.com/flutter/flutter/issues/134852.
101  //
102  // (Note, if you're using MoltenVK, or Linux, you can comment out this line).
103  context_vk->SetSyncPresentation(true);
104 
105  VkSurfaceKHR vk_surface;
106  auto res = vk::Result{::glfwCreateWindowSurface(
107  context_vk->GetInstance(), // instance
108  window, // window
109  nullptr, // allocator
110  &vk_surface // surface
111  )};
112  if (res != vk::Result::eSuccess) {
113  VALIDATION_LOG << "Could not create surface for GLFW window: "
114  << vk::to_string(res);
115  return;
116  }
117 
118  vk::UniqueSurfaceKHR surface{vk_surface, context_vk->GetInstance()};
119  auto context = context_vk->CreateSurfaceContext();
120  if (!context->SetWindowSurface(std::move(surface))) {
121  VALIDATION_LOG << "Could not set up surface for context.";
122  return;
123  }
124 
125  context_ = std::move(context);
126 }
127 
129 
130 // |PlaygroundImpl|
131 std::shared_ptr<Context> PlaygroundImplVK::GetContext() const {
132  return context_;
133 }
134 
135 // |PlaygroundImpl|
136 PlaygroundImpl::WindowHandle PlaygroundImplVK::GetWindowHandle() const {
137  return handle_.get();
138 }
139 
140 // |PlaygroundImpl|
141 std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
142  std::shared_ptr<Context> context) {
143  SurfaceContextVK* surface_context_vk =
144  reinterpret_cast<SurfaceContextVK*>(context_.get());
145  return surface_context_vk->AcquireNextSurface();
146 }
147 
148 } // namespace impeller
impeller::ContextVK::Settings::enable_validation
bool enable_validation
Definition: context_vk.h:44
surface_vk.h
surface_context_vk.h
formats_vk.h
impeller::PlaygroundImpl
Definition: playground_impl.h:17
vk.h
impeller::ContextVK::Settings
Definition: context_vk.h:40
impeller::ContextVK::Settings::proc_address_callback
PFN_vkGetInstanceProcAddr proc_address_callback
Definition: context_vk.h:41
impeller::ContextVK::Settings::shader_libraries_data
std::vector< std::shared_ptr< fml::Mapping > > shader_libraries_data
Definition: context_vk.h:42
impeller::ShaderLibraryMappingsForPlayground
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
Definition: playground_impl_gles.cc:89
impeller::PlaygroundImplVK::PlaygroundImplVK
PlaygroundImplVK(PlaygroundSwitches switches)
Definition: playground_impl_vk.cc:55
impeller::ContextVK::Create
static std::shared_ptr< ContextVK > Create(Settings settings)
Definition: context_vk.cc:92
texture_vk.h
impeller::PlaygroundImpl::switches_
const PlaygroundSwitches switches_
Definition: playground_impl.h:36
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
playground_impl_vk.h
impeller::ContextVK::Settings::cache_directory
fml::UniqueFD cache_directory
Definition: context_vk.h:43
impeller::PlaygroundSwitches
Definition: switches.h:15
impeller::PlaygroundSwitches::enable_vulkan_validation
bool enable_vulkan_validation
Definition: switches.h:21
impeller::PlaygroundImplVK::~PlaygroundImplVK
~PlaygroundImplVK()
context_vk.h
impeller
Definition: aiks_context.cc:10
impeller::PlaygroundImpl::WindowHandle
void * WindowHandle
Definition: playground_impl.h:24