| // Copyright 2018 The Chromium 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 "ui/ozone/platform/scenic/vulkan_implementation_scenic.h" |
| |
| #include <lib/ui/scenic/cpp/commands.h> |
| #include <lib/ui/scenic/cpp/session.h> |
| #include <lib/zx/channel.h> |
| #include <vulkan/vulkan.h> |
| |
| #include "base/bind_helpers.h" |
| #include "base/files/file_path.h" |
| #include "base/fuchsia/fuchsia_logging.h" |
| #include "base/macros.h" |
| #include "base/native_library.h" |
| #include "gpu/vulkan/vulkan_function_pointers.h" |
| #include "gpu/vulkan/vulkan_instance.h" |
| #include "gpu/vulkan/vulkan_surface.h" |
| #include "mojo/public/cpp/system/platform_handle.h" |
| #include "ui/gfx/gpu_fence.h" |
| #include "ui/ozone/platform/scenic/scenic_surface.h" |
| #include "ui/ozone/platform/scenic/scenic_surface_factory.h" |
| #include "ui/ozone/platform/scenic/scenic_window.h" |
| #include "ui/ozone/platform/scenic/scenic_window_manager.h" |
| |
| namespace ui { |
| |
| VulkanImplementationScenic::VulkanImplementationScenic( |
| ScenicSurfaceFactory* scenic_surface_factory) |
| : scenic_surface_factory_(scenic_surface_factory) {} |
| |
| VulkanImplementationScenic::~VulkanImplementationScenic() = default; |
| |
| bool VulkanImplementationScenic::InitializeVulkanInstance() { |
| base::NativeLibraryLoadError error; |
| base::NativeLibrary handle = |
| base::LoadNativeLibrary(base::FilePath("libvulkan.so"), &error); |
| if (!handle) { |
| LOG(ERROR) << "Failed to load vulkan: " << error.ToString(); |
| return false; |
| } |
| |
| gpu::VulkanFunctionPointers* vulkan_function_pointers = |
| gpu::GetVulkanFunctionPointers(); |
| vulkan_function_pointers->vulkan_loader_library_ = handle; |
| std::vector<const char*> required_extensions = { |
| VK_KHR_SURFACE_EXTENSION_NAME, |
| VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME, |
| }; |
| std::vector<const char*> required_layers = { |
| "VK_LAYER_FUCHSIA_imagepipe_swapchain", |
| }; |
| if (!vulkan_instance_.Initialize(required_extensions, required_layers)) { |
| vulkan_instance_.Destroy(); |
| return false; |
| } |
| |
| vkCreateImagePipeSurfaceFUCHSIA_ = |
| reinterpret_cast<PFN_vkCreateImagePipeSurfaceFUCHSIA>( |
| vkGetInstanceProcAddr(vulkan_instance_.vk_instance(), |
| "vkCreateImagePipeSurfaceFUCHSIA")); |
| if (!vkCreateImagePipeSurfaceFUCHSIA_) { |
| vulkan_instance_.Destroy(); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| VkInstance VulkanImplementationScenic::GetVulkanInstance() { |
| return vulkan_instance_.vk_instance(); |
| } |
| |
| std::unique_ptr<gpu::VulkanSurface> |
| VulkanImplementationScenic::CreateViewSurface(gfx::AcceleratedWidget window) { |
| ScenicSurface* scenic_surface = scenic_surface_factory_->GetSurface(window); |
| |
| // Attach the surface to the window. |
| scenic_surface->LinkToParent(); |
| |
| fuchsia::images::ImagePipePtr image_pipe; |
| scenic_surface->SetTextureToNewImagePipe(image_pipe.NewRequest()); |
| |
| VkSurfaceKHR surface; |
| VkImagePipeSurfaceCreateInfoFUCHSIA surface_create_info = {}; |
| surface_create_info.sType = |
| VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA; |
| surface_create_info.flags = 0; |
| surface_create_info.imagePipeHandle = |
| image_pipe.Unbind().TakeChannel().release(); |
| |
| VkResult result = vkCreateImagePipeSurfaceFUCHSIA_( |
| GetVulkanInstance(), &surface_create_info, nullptr, &surface); |
| if (result != VK_SUCCESS) { |
| // This shouldn't fail, and we don't know whether imagePipeHandle was closed |
| // if it does. |
| LOG(FATAL) << "vkCreateImagePipeSurfaceFUCHSIA failed: " << result; |
| } |
| |
| // Execute the initialization commands. Once this is done we won't need to |
| // make any further changes to ScenicSurface other than to keep it alive; the |
| // texture can be replaced through the vulkan swapchain API. |
| scenic_surface->Commit(); |
| |
| return std::make_unique<gpu::VulkanSurface>(GetVulkanInstance(), surface); |
| } |
| |
| bool VulkanImplementationScenic::GetPhysicalDevicePresentationSupport( |
| VkPhysicalDevice physical_device, |
| const std::vector<VkQueueFamilyProperties>& queue_family_properties, |
| uint32_t queue_family_index) { |
| // TODO(spang): vkGetPhysicalDeviceMagmaPresentationSupportKHR returns false |
| // here. Use it once it is fixed. |
| NOTIMPLEMENTED(); |
| return true; |
| } |
| |
| std::vector<const char*> |
| VulkanImplementationScenic::GetRequiredDeviceExtensions() { |
| return {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; |
| } |
| |
| VkFence VulkanImplementationScenic::CreateVkFenceForGpuFence( |
| VkDevice vk_device) { |
| NOTIMPLEMENTED(); |
| return VK_NULL_HANDLE; |
| } |
| |
| std::unique_ptr<gfx::GpuFence> |
| VulkanImplementationScenic::ExportVkFenceToGpuFence(VkDevice vk_device, |
| VkFence vk_fence) { |
| NOTIMPLEMENTED(); |
| return nullptr; |
| } |
| |
| } // namespace ui |