Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit adac01d

Browse files
committed
[Impeller] Create a global Vulkan instance in PlaygroundImplVK to prevent SwiftShader from being unloaded after a test completes
Libcxx is leaking a thread-local storage key each time SwiftShader is loaded and unloaded. If a test's Vulkan instance is the only one in the process, then SwiftShader will be unloaded after the test ends. If many Vulkan playground tests run in a suite, then eventually the leak will cause the process to exceed its limit of TLS keys and the suite will fail. The process can ensure that SwiftShader remains loaded by holding another Vulkan instance that persists across all tests in the suite. Fixes flutter/flutter#138028
1 parent be43db3 commit adac01d

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

impeller/playground/backend/vulkan/playground_impl_vk.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ ShaderLibraryMappingsForPlayground() {
4545
};
4646
}
4747

48+
vk::UniqueInstance PlaygroundImplVK::global_instance_;
49+
4850
void PlaygroundImplVK::DestroyWindowHandle(WindowHandle handle) {
4951
if (!handle) {
5052
return;
@@ -67,6 +69,8 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
6769
return;
6870
}
6971

72+
InitGlobalVulkanInstance();
73+
7074
::glfwDefaultWindowHints();
7175
::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
7276
::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
@@ -145,4 +149,33 @@ std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
145149
return surface_context_vk->AcquireNextSurface();
146150
}
147151

152+
// Create a global instance of Vulkan in order to prevent unloading of the
153+
// Vulkan library.
154+
// A test suite may repeatedly create and destroy PlaygroundImplVK instances,
155+
// and if the PlaygroundImplVK's Vulkan instance is the only one in the
156+
// process then the Vulkan library will be unloaded when the instance is
157+
// destroyed. Repeated loading and unloading of SwiftShader was leaking
158+
// resources, so this will work around that leak.
159+
// (see https://github.com/flutter/flutter/issues/138028)
160+
void PlaygroundImplVK::InitGlobalVulkanInstance() {
161+
if (global_instance_) {
162+
return;
163+
}
164+
165+
VULKAN_HPP_DEFAULT_DISPATCHER.init(::glfwGetInstanceProcAddress);
166+
167+
vk::ApplicationInfo application_info;
168+
application_info.setApplicationVersion(VK_API_VERSION_1_0);
169+
application_info.setApiVersion(VK_API_VERSION_1_1);
170+
application_info.setEngineVersion(VK_API_VERSION_1_0);
171+
application_info.setPEngineName("PlaygroundImplVK");
172+
application_info.setPApplicationName("PlaygroundImplVK");
173+
174+
auto instance_result =
175+
vk::createInstanceUnique(vk::InstanceCreateInfo({}, &application_info));
176+
FML_CHECK(instance_result.result == vk::Result::eSuccess)
177+
<< "Unable to initialize global Vulkan instance";
178+
global_instance_ = std::move(instance_result.value);
179+
}
180+
148181
} // namespace impeller

impeller/playground/backend/vulkan/playground_impl_vk.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class PlaygroundImplVK final : public PlaygroundImpl {
2424
using UniqueHandle = std::unique_ptr<void, decltype(&DestroyWindowHandle)>;
2525
UniqueHandle handle_;
2626

27+
// A global Vulkan instance which ensures that the Vulkan library will remain
28+
// loaded throughout the lifetime of the process.
29+
static vk::UniqueInstance global_instance_;
30+
2731
// |PlaygroundImpl|
2832
std::shared_ptr<Context> GetContext() const override;
2933

@@ -37,6 +41,8 @@ class PlaygroundImplVK final : public PlaygroundImpl {
3741
PlaygroundImplVK(const PlaygroundImplVK&) = delete;
3842

3943
PlaygroundImplVK& operator=(const PlaygroundImplVK&) = delete;
44+
45+
static void InitGlobalVulkanInstance();
4046
};
4147

4248
} // namespace impeller

0 commit comments

Comments
 (0)