1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef GPU_VULKAN_VULKAN_IMAGE_H_
6 #define GPU_VULKAN_VULKAN_IMAGE_H_
7
8 #include <vulkan/vulkan.h>
9
10 #include "base/component_export.h"
11 #include "base/files/scoped_file.h"
12 #include "base/optional.h"
13 #include "base/util/type_safety/pass_key.h"
14 #include "build/build_config.h"
15 #include "gpu/ipc/common/vulkan_ycbcr_info.h"
16 #include "ui/gfx/geometry/size.h"
17 #include "ui/gfx/gpu_memory_buffer.h"
18 #include "ui/gfx/native_pixmap.h"
19
20 #if defined(OS_WIN)
21 #include "base/win/scoped_handle.h"
22 #endif
23
24 #if defined(OS_FUCHSIA)
25 #include <lib/zx/vmo.h>
26 #endif
27
28 namespace gpu {
29
30 class VulkanDeviceQueue;
31
COMPONENT_EXPORT(VULKAN)32 class COMPONENT_EXPORT(VULKAN) VulkanImage {
33 public:
34 explicit VulkanImage(util::PassKey<VulkanImage> pass_key);
35 ~VulkanImage();
36
37 VulkanImage(VulkanImage&) = delete;
38 VulkanImage& operator=(VulkanImage&) = delete;
39
40 static std::unique_ptr<VulkanImage> Create(
41 VulkanDeviceQueue* device_queue,
42 const gfx::Size& size,
43 VkFormat format,
44 VkImageUsageFlags usage,
45 VkImageCreateFlags flags = 0,
46 VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL,
47 void* vk_image_create_info_next = nullptr,
48 void* vk_memory_allocation_info_next = nullptr);
49
50 // Create VulkanImage with external memory, it can be exported and used by
51 // foreign API
52 static std::unique_ptr<VulkanImage> CreateWithExternalMemory(
53 VulkanDeviceQueue* device_queue,
54 const gfx::Size& size,
55 VkFormat format,
56 VkImageUsageFlags usage,
57 VkImageCreateFlags flags = 0,
58 VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL);
59
60 static std::unique_ptr<VulkanImage> CreateFromGpuMemoryBufferHandle(
61 VulkanDeviceQueue* device_queue,
62 gfx::GpuMemoryBufferHandle gmb_handle,
63 const gfx::Size& size,
64 VkFormat format,
65 VkImageUsageFlags usage,
66 VkImageCreateFlags flags = 0,
67 VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL);
68
69 static std::unique_ptr<VulkanImage> Create(
70 VulkanDeviceQueue* device_queue,
71 VkImage image,
72 VkDeviceMemory device_memory,
73 const gfx::Size& size,
74 VkFormat format,
75 VkImageTiling image_tiling,
76 VkDeviceSize device_size,
77 uint32_t memory_type_index,
78 base::Optional<VulkanYCbCrInfo>& ycbcr_info,
79 VkImageUsageFlags usage,
80 VkImageCreateFlags flags);
81
82 void Destroy();
83
84 #if defined(OS_POSIX)
85 base::ScopedFD GetMemoryFd(VkExternalMemoryHandleTypeFlagBits handle_type =
86 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
87 #endif
88
89 #if defined(OS_WIN)
90 base::win::ScopedHandle GetMemoryHandle(
91 VkExternalMemoryHandleTypeFlagBits handle_type =
92 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT);
93 #endif
94
95 #if defined(OS_FUCHSIA)
96 zx::vmo GetMemoryZirconHandle();
97 #endif
98
99 VulkanDeviceQueue* device_queue() const { return device_queue_; }
100 const gfx::Size& size() const { return size_; }
101 VkFormat format() const { return format_; }
102 VkImageCreateFlags flags() const { return flags_; }
103 VkImageUsageFlags usage() const { return usage_; }
104 VkDeviceSize device_size() const { return device_size_; }
105 uint32_t memory_type_index() const { return memory_type_index_; }
106 VkImageTiling image_tiling() const { return image_tiling_; }
107 VkImageLayout image_layout() const { return image_layout_; }
108 void set_image_layout(VkImageLayout layout) { image_layout_ = layout; }
109 uint32_t queue_family_index() const { return queue_family_index_; }
110 void set_queue_family_index(uint32_t index) { queue_family_index_ = index; }
111 const base::Optional<VulkanYCbCrInfo>& ycbcr_info() const {
112 return ycbcr_info_;
113 }
114 VkImage image() const { return image_; }
115 VkDeviceMemory device_memory() const { return device_memory_; }
116 VkExternalMemoryHandleTypeFlags handle_types() const { return handle_types_; }
117 void set_native_pixmap(scoped_refptr<gfx::NativePixmap> pixmap) {
118 native_pixmap_ = std::move(pixmap);
119 }
120 const scoped_refptr<gfx::NativePixmap>& native_pixmap() const {
121 return native_pixmap_;
122 }
123
124 private:
125 bool Initialize(VulkanDeviceQueue* device_queue,
126 const gfx::Size& size,
127 VkFormat format,
128 VkImageUsageFlags usage,
129 VkImageCreateFlags flags,
130 VkImageTiling image_tiling,
131 void* image_create_info_next,
132 void* memory_allocation_info_next,
133 const VkMemoryRequirements* requirements);
134 bool InitializeWithExternalMemory(VulkanDeviceQueue* device_queue,
135 const gfx::Size& size,
136 VkFormat format,
137 VkImageUsageFlags usage,
138 VkImageCreateFlags flags,
139 VkImageTiling image_tiling);
140 bool InitializeFromGpuMemoryBufferHandle(
141 VulkanDeviceQueue* device_queue,
142 gfx::GpuMemoryBufferHandle gmb_handle,
143 const gfx::Size& size,
144 VkFormat format,
145 VkImageUsageFlags usage,
146 VkImageCreateFlags flags,
147 VkImageTiling image_tiling);
148
149 VulkanDeviceQueue* device_queue_ = nullptr;
150 gfx::Size size_;
151 VkFormat format_ = VK_FORMAT_UNDEFINED;
152 VkImageCreateFlags flags_ = 0;
153 VkImageUsageFlags usage_ = 0;
154 VkDeviceSize device_size_ = 0;
155 uint32_t memory_type_index_ = 0;
156 VkImageTiling image_tiling_ = VK_IMAGE_TILING_OPTIMAL;
157 VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED;
158 uint32_t queue_family_index_ = VK_QUEUE_FAMILY_IGNORED;
159 base::Optional<VulkanYCbCrInfo> ycbcr_info_;
160 VkImage image_ = VK_NULL_HANDLE;
161 VkDeviceMemory device_memory_ = VK_NULL_HANDLE;
162 VkExternalMemoryHandleTypeFlags handle_types_ = 0;
163 scoped_refptr<gfx::NativePixmap> native_pixmap_;
164 };
165
166 } // namespace gpu
167
168 #endif // GPU_VULKAN_VULKAN_IMAGE_H_
169