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