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
|
// Copyright (c) 2016 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.
#ifndef GPU_VULKAN_VULKAN_SWAP_CHAIN_H_
#define GPU_VULKAN_VULKAN_SWAP_CHAIN_H_
#include <vulkan/vulkan.h>
#include <memory>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/logging.h"
#include "base/optional.h"
#include "gpu/vulkan/vulkan_export.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/swap_result.h"
namespace gpu {
class VulkanCommandBuffer;
class VulkanCommandPool;
class VulkanDeviceQueue;
class VULKAN_EXPORT VulkanSwapChain {
public:
class VULKAN_EXPORT ScopedWrite {
public:
explicit ScopedWrite(VulkanSwapChain* swap_chain);
~ScopedWrite();
bool success() const { return success_; }
VkImage image() const { return image_; }
uint32_t image_index() const { return image_index_; }
VkImageLayout image_layout() const { return image_layout_; }
void set_image_layout(VkImageLayout layout) { image_layout_ = layout; }
// Take the begin write semaphore. The ownership of the semaphore will be
// transferred to the caller.
VkSemaphore TakeBeginSemaphore();
// Get the end write semaphore.
VkSemaphore GetEndSemaphore();
private:
VulkanSwapChain* const swap_chain_;
bool success_ = false;
VkImage image_ = VK_NULL_HANDLE;
uint32_t image_index_ = 0;
VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED;
VkSemaphore begin_semaphore_ = VK_NULL_HANDLE;
VkSemaphore end_semaphore_ = VK_NULL_HANDLE;
DISALLOW_COPY_AND_ASSIGN(ScopedWrite);
};
VulkanSwapChain();
~VulkanSwapChain();
// min_image_count is the minimum number of presentable images.
bool Initialize(VulkanDeviceQueue* device_queue,
VkSurfaceKHR surface,
const VkSurfaceFormatKHR& surface_format,
const gfx::Size& image_size,
uint32_t min_image_count,
VkSurfaceTransformFlagBitsKHR pre_transform,
bool use_protected_memory,
std::unique_ptr<VulkanSwapChain> old_swap_chain);
// Destroy() should be called when all related GPU tasks have been finished.
void Destroy();
// Present the current buffer.
gfx::SwapResult PresentBuffer(const gfx::Rect& rect);
uint32_t num_images() const { return static_cast<uint32_t>(images_.size()); }
const gfx::Size& size() const { return size_; }
bool use_protected_memory() const { return use_protected_memory_; }
private:
bool InitializeSwapChain(VkSurfaceKHR surface,
const VkSurfaceFormatKHR& surface_format,
const gfx::Size& image_size,
uint32_t min_image_count,
VkSurfaceTransformFlagBitsKHR pre_transform,
bool use_protected_memory,
std::unique_ptr<VulkanSwapChain> old_swap_chain);
void DestroySwapChain();
bool InitializeSwapImages(const VkSurfaceFormatKHR& surface_format);
void DestroySwapImages();
bool BeginWriteCurrentImage(VkImage* image,
uint32_t* image_index,
VkImageLayout* layout,
VkSemaphore* semaphore);
void EndWriteCurrentImage(VkImageLayout layout, VkSemaphore semaphore);
bool AcquireNextImage();
bool use_protected_memory_ = false;
VulkanDeviceQueue* device_queue_ = nullptr;
bool is_incremental_present_supported_ = false;
VkSwapchainKHR swap_chain_ = VK_NULL_HANDLE;
std::unique_ptr<VulkanCommandPool> command_pool_;
gfx::Size size_;
struct ImageData {
ImageData();
ImageData(ImageData&& other);
~ImageData();
ImageData& operator=(ImageData&& other);
VkImage image = VK_NULL_HANDLE;
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
std::unique_ptr<VulkanCommandBuffer> command_buffer;
// Semaphore passed to vkQueuePresentKHR to wait on.
VkSemaphore present_begin_semaphore = VK_NULL_HANDLE;
// Semaphore signaled when present engine is done with the image.
VkSemaphore present_end_semaphore = VK_NULL_HANDLE;
};
std::vector<ImageData> images_;
// Acquired image index.
base::circular_deque<uint32_t> in_present_images_;
base::Optional<uint32_t> acquired_image_;
bool is_writing_ = false;
VkSemaphore end_write_semaphore_ = VK_NULL_HANDLE;
DISALLOW_COPY_AND_ASSIGN(VulkanSwapChain);
};
} // namespace gpu
#endif // GPU_VULKAN_VULKAN_SWAP_CHAIN_H_
|