Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions impeller/playground/backend/vulkan/playground_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ ShaderLibraryMappingsForPlayground() {
};
}

vk::UniqueInstance PlaygroundImplVK::global_instance_;

void PlaygroundImplVK::DestroyWindowHandle(WindowHandle handle) {
if (!handle) {
return;
Expand All @@ -67,6 +69,8 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
return;
}

InitGlobalVulkanInstance();

::glfwDefaultWindowHints();
::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
Expand Down Expand Up @@ -145,4 +149,33 @@ std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
return surface_context_vk->AcquireNextSurface();
}

// Create a global instance of Vulkan in order to prevent unloading of the
// Vulkan library.
// A test suite may repeatedly create and destroy PlaygroundImplVK instances,
// and if the PlaygroundImplVK's Vulkan instance is the only one in the
// process then the Vulkan library will be unloaded when the instance is
// destroyed. Repeated loading and unloading of SwiftShader was leaking
// resources, so this will work around that leak.
// (see https://github.com/flutter/flutter/issues/138028)
void PlaygroundImplVK::InitGlobalVulkanInstance() {
if (global_instance_) {
return;
}

VULKAN_HPP_DEFAULT_DISPATCHER.init(::glfwGetInstanceProcAddress);

vk::ApplicationInfo application_info;
application_info.setApplicationVersion(VK_API_VERSION_1_0);
application_info.setApiVersion(VK_API_VERSION_1_1);
application_info.setEngineVersion(VK_API_VERSION_1_0);
application_info.setPEngineName("PlaygroundImplVK");
application_info.setPApplicationName("PlaygroundImplVK");

auto instance_result =
vk::createInstanceUnique(vk::InstanceCreateInfo({}, &application_info));
FML_CHECK(instance_result.result == vk::Result::eSuccess)
<< "Unable to initialize global Vulkan instance";
global_instance_ = std::move(instance_result.value);
}

} // namespace impeller
6 changes: 6 additions & 0 deletions impeller/playground/backend/vulkan/playground_impl_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class PlaygroundImplVK final : public PlaygroundImpl {
using UniqueHandle = std::unique_ptr<void, decltype(&DestroyWindowHandle)>;
UniqueHandle handle_;

// A global Vulkan instance which ensures that the Vulkan library will remain
// loaded throughout the lifetime of the process.
static vk::UniqueInstance global_instance_;

// |PlaygroundImpl|
std::shared_ptr<Context> GetContext() const override;

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

PlaygroundImplVK& operator=(const PlaygroundImplVK&) = delete;

static void InitGlobalVulkanInstance();
};

} // namespace impeller