| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "impeller/playground/backend/vulkan/playground_impl_vk.h" |
| |
| #include "impeller/renderer/backend/vulkan/vk.h" |
| |
| #define GLFW_INCLUDE_VULKAN |
| #include <GLFW/glfw3.h> |
| |
| #include "flutter/fml/logging.h" |
| #include "flutter/fml/mapping.h" |
| #include "impeller/entity/vk/entity_shaders_vk.h" |
| #include "impeller/entity/vk/modern_shaders_vk.h" |
| #include "impeller/fixtures/vk/fixtures_shaders_vk.h" |
| #include "impeller/playground/imgui/vk/imgui_shaders_vk.h" |
| #include "impeller/renderer/backend/vulkan/context_vk.h" |
| #include "impeller/renderer/backend/vulkan/formats_vk.h" |
| #include "impeller/renderer/backend/vulkan/surface_vk.h" |
| #include "impeller/renderer/backend/vulkan/texture_vk.h" |
| #include "impeller/scene/shaders/vk/scene_shaders_vk.h" |
| |
| namespace impeller { |
| |
| static std::vector<std::shared_ptr<fml::Mapping>> |
| ShaderLibraryMappingsForPlayground() { |
| return { |
| std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data, |
| impeller_entity_shaders_vk_length), |
| std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data, |
| impeller_modern_shaders_vk_length), |
| std::make_shared<fml::NonOwnedMapping>( |
| impeller_fixtures_shaders_vk_data, |
| impeller_fixtures_shaders_vk_length), |
| std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_vk_data, |
| impeller_imgui_shaders_vk_length), |
| std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data, |
| impeller_scene_shaders_vk_length), |
| |
| }; |
| } |
| |
| void PlaygroundImplVK::DestroyWindowHandle(WindowHandle handle) { |
| if (!handle) { |
| return; |
| } |
| ::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle)); |
| } |
| |
| PlaygroundImplVK::PlaygroundImplVK() |
| : concurrent_loop_(fml::ConcurrentMessageLoop::Create()), |
| handle_(nullptr, &DestroyWindowHandle) { |
| if (!::glfwVulkanSupported()) { |
| VALIDATION_LOG << "Attempted to initialize a Vulkan playground on a system " |
| "that does not support Vulkan."; |
| return; |
| } |
| |
| ::glfwDefaultWindowHints(); |
| ::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); |
| ::glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); |
| ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); |
| |
| auto window = |
| ::glfwCreateWindow(800, 600, "Test Vulkan Window", nullptr, nullptr); |
| if (!window) { |
| VALIDATION_LOG << "Unable to create glfw window"; |
| return; |
| } |
| |
| handle_.reset(window); |
| |
| auto context = ContextVK::Create(reinterpret_cast<PFN_vkGetInstanceProcAddr>( |
| &::glfwGetInstanceProcAddress), // |
| ShaderLibraryMappingsForPlayground(), // |
| nullptr, // |
| concurrent_loop_->GetTaskRunner(), // |
| "Playground Library" // |
| ); |
| |
| if (!context || !context->IsValid()) { |
| VALIDATION_LOG << "Could not create Vulkan context in the playground."; |
| return; |
| } |
| |
| context_ = std::move(context); |
| |
| SetupSwapchain(); |
| } |
| |
| void PlaygroundImplVK::SetupSwapchain() { |
| ContextVK* context_vk = reinterpret_cast<ContextVK*>(context_.get()); |
| auto window = reinterpret_cast<GLFWwindow*>(handle_.get()); |
| vk::Instance instance = context_vk->GetInstance(); |
| VkSurfaceKHR surface_tmp; |
| auto res = vk::Result{ |
| ::glfwCreateWindowSurface(instance, window, nullptr, &surface_tmp)}; |
| if (res != vk::Result::eSuccess) { |
| VALIDATION_LOG << "Could not create surface for GLFW window: " |
| << vk::to_string(res); |
| return; |
| } |
| vk::UniqueSurfaceKHR surface{surface_tmp, instance}; |
| context_vk->SetupSwapchain(std::move(surface)); |
| } |
| |
| PlaygroundImplVK::~PlaygroundImplVK() = default; |
| |
| // |PlaygroundImpl| |
| std::shared_ptr<Context> PlaygroundImplVK::GetContext() const { |
| return context_; |
| } |
| |
| // |PlaygroundImpl| |
| PlaygroundImpl::WindowHandle PlaygroundImplVK::GetWindowHandle() const { |
| return handle_.get(); |
| } |
| |
| // |PlaygroundImpl| |
| std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame( |
| std::shared_ptr<Context> context) { |
| ContextVK* context_vk = reinterpret_cast<ContextVK*>(context_.get()); |
| return context_vk->AcquireSurface(current_frame_++); |
| } |
| |
| } // namespace impeller |