1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/flatland/vulkan_implementation_flatland.h"
#include <lib/zx/channel.h>
#include <vulkan/vulkan.h>
#include <memory>
#include <tuple>
#include "base/files/file_path.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/functional/callback_helpers.h"
#include "base/notimplemented.h"
#include "gpu/ipc/common/vulkan_ycbcr_info.h"
#include "gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
#include "gpu/vulkan/vulkan_image.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "gpu/vulkan/vulkan_util.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer_handle.h"
#include "ui/ozone/platform/flatland/flatland_surface.h"
#include "ui/ozone/platform/flatland/flatland_surface_factory.h"
#include "ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.h"
#include "ui/ozone/platform/flatland/flatland_window.h"
#include "ui/ozone/platform/flatland/flatland_window_manager.h"
namespace ui {
VulkanImplementationFlatland::VulkanImplementationFlatland(
FlatlandSurfaceFactory* flatland_surface_factory,
FlatlandSysmemBufferManager* flatland_sysmem_buffer_manager,
bool use_swiftshader,
bool allow_protected_memory)
: VulkanImplementation(use_swiftshader, allow_protected_memory),
flatland_sysmem_buffer_manager_(flatland_sysmem_buffer_manager) {}
VulkanImplementationFlatland::~VulkanImplementationFlatland() = default;
bool VulkanImplementationFlatland::InitializeVulkanInstance(
bool using_surface) {
DCHECK(!using_surface);
base::FilePath path(use_swiftshader() ? "libvk_swiftshader.so"
: "libvulkan.so");
std::vector<const char*> required_extensions;
std::vector<const char*> required_layers;
return vulkan_instance_.Initialize(path, required_extensions,
required_layers);
}
gpu::VulkanInstance* VulkanImplementationFlatland::GetVulkanInstance() {
return &vulkan_instance_;
}
std::unique_ptr<gpu::VulkanSurface>
VulkanImplementationFlatland::CreateViewSurface(gfx::AcceleratedWidget window) {
NOTREACHED();
}
bool VulkanImplementationFlatland::GetPhysicalDevicePresentationSupport(
VkPhysicalDevice physical_device,
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) {
return true;
}
std::vector<const char*>
VulkanImplementationFlatland::GetRequiredDeviceExtensions() {
std::vector<const char*> result = {
VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
VK_KHR_MAINTENANCE1_EXTENSION_NAME,
};
// Following extensions are not supported by Swiftshader.
if (!use_swiftshader()) {
result.push_back(VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME);
result.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
}
return result;
}
std::vector<const char*>
VulkanImplementationFlatland::GetOptionalDeviceExtensions() {
return {};
}
VkFence VulkanImplementationFlatland::CreateVkFenceForGpuFence(
VkDevice vk_device) {
NOTIMPLEMENTED();
return VK_NULL_HANDLE;
}
std::unique_ptr<gfx::GpuFence>
VulkanImplementationFlatland::ExportVkFenceToGpuFence(VkDevice vk_device,
VkFence vk_fence) {
NOTIMPLEMENTED();
return nullptr;
}
VkExternalSemaphoreHandleTypeFlagBits
VulkanImplementationFlatland::GetExternalSemaphoreHandleType() {
return VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
}
bool VulkanImplementationFlatland::CanImportGpuMemoryBuffer(
gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferType memory_buffer_type) {
return memory_buffer_type == gfx::NATIVE_PIXMAP;
}
std::unique_ptr<gpu::VulkanImage>
VulkanImplementationFlatland::CreateImageFromGpuMemoryHandle(
gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferHandle gmb_handle,
gfx::Size size,
VkFormat vk_format,
const gfx::ColorSpace& color_space) {
if (gmb_handle.type != gfx::NATIVE_PIXMAP)
return nullptr;
if (!gmb_handle.native_pixmap_handle().buffer_collection_handle) {
DLOG(ERROR) << "NativePixmapHandle.buffer_collection_handle is not set.";
return nullptr;
}
auto collection = flatland_sysmem_buffer_manager_->GetCollectionByHandle(
gmb_handle.native_pixmap_handle().buffer_collection_handle);
if (!collection) {
DLOG(ERROR) << "Tried to use an unknown buffer collection ID.";
return nullptr;
}
VkImage vk_image = VK_NULL_HANDLE;
VkImageCreateInfo vk_image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
VkDeviceMemory vk_device_memory = VK_NULL_HANDLE;
VkDeviceSize vk_device_size = 0;
if (!collection->CreateVkImage(gmb_handle.native_pixmap_handle().buffer_index,
device_queue->GetVulkanDevice(), size,
&vk_image, &vk_image_info, &vk_device_memory,
&vk_device_size)) {
DLOG(ERROR) << "CreateVkImage failed.";
return nullptr;
}
std::optional<gpu::VulkanYCbCrInfo> ycbcr_info;
if (collection->format() == gfx::BufferFormat::YUV_420_BIPLANAR) {
VkSamplerYcbcrModelConversion ycbcr_conversion =
(color_space.GetMatrixID() == gfx::ColorSpace::MatrixID::BT709)
? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709
: VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
// Currently sysmem doesn't specify location of chroma samples relative to
// luma (see fxbug.dev/13677). Assume they are cosited with luma. Y'CbCr
// info here must match the values passed for the same buffer in
// FuchsiaVideoDecoder. |format_features| are resolved later in the GPU
// process before the ycbcr info is passed to Skia.
ycbcr_info = gpu::VulkanYCbCrInfo(
vk_image_info.format, /*external_format=*/0, ycbcr_conversion,
VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, VK_CHROMA_LOCATION_COSITED_EVEN,
VK_CHROMA_LOCATION_COSITED_EVEN, /*format_features=*/0);
}
auto image = gpu::VulkanImage::Create(
device_queue, vk_image, vk_device_memory, size, vk_image_info.format,
vk_image_info.tiling, vk_device_size, 0 /* memory_type_index */,
ycbcr_info, vk_image_info.usage, vk_image_info.flags);
if (image->format() != vk_format) {
DLOG(ERROR) << "Unexpected format " << vk_format << " vs "
<< image->format();
image->Destroy();
return nullptr;
}
image->set_queue_family_index(VK_QUEUE_FAMILY_EXTERNAL);
image->set_native_pixmap(collection->CreateNativePixmap(
std::move(gmb_handle).native_pixmap_handle(), size));
return image;
}
void VulkanImplementationFlatland::RegisterSysmemBufferCollection(
VkDevice device,
zx::eventpair service_handle,
zx::channel sysmem_token,
gfx::BufferFormat format,
gfx::BufferUsage usage,
gfx::Size size,
size_t min_buffer_count,
bool register_with_flatland_allocator) {
flatland_sysmem_buffer_manager_->ImportSysmemBufferCollection(
device, std::move(service_handle), std::move(sysmem_token), size, format,
usage, min_buffer_count, register_with_flatland_allocator);
}
} // namespace ui
|