1 // Copyright (c) 2016 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_SWAP_CHAIN_H_ 6 #define GPU_VULKAN_VULKAN_SWAP_CHAIN_H_ 7 8 #include <vulkan/vulkan.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/containers/circular_deque.h" 14 #include "base/logging.h" 15 #include "base/optional.h" 16 #include "gpu/vulkan/vulkan_export.h" 17 #include "ui/gfx/geometry/rect.h" 18 #include "ui/gfx/geometry/size.h" 19 #include "ui/gfx/swap_result.h" 20 21 namespace gpu { 22 23 class VulkanCommandBuffer; 24 class VulkanCommandPool; 25 class VulkanDeviceQueue; 26 27 class VULKAN_EXPORT VulkanSwapChain { 28 public: 29 class VULKAN_EXPORT ScopedWrite { 30 public: 31 explicit ScopedWrite(VulkanSwapChain* swap_chain); 32 ~ScopedWrite(); 33 success()34 bool success() const { return success_; } image()35 VkImage image() const { return image_; } image_index()36 uint32_t image_index() const { return image_index_; } image_layout()37 VkImageLayout image_layout() const { return image_layout_; } set_image_layout(VkImageLayout layout)38 void set_image_layout(VkImageLayout layout) { image_layout_ = layout; } 39 40 // Take the begin write semaphore. The ownership of the semaphore will be 41 // transferred to the caller. 42 VkSemaphore TakeBeginSemaphore(); 43 44 // Get the end write semaphore. 45 VkSemaphore GetEndSemaphore(); 46 47 private: 48 VulkanSwapChain* const swap_chain_; 49 bool success_ = false; 50 VkImage image_ = VK_NULL_HANDLE; 51 uint32_t image_index_ = 0; 52 VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; 53 VkSemaphore begin_semaphore_ = VK_NULL_HANDLE; 54 VkSemaphore end_semaphore_ = VK_NULL_HANDLE; 55 56 DISALLOW_COPY_AND_ASSIGN(ScopedWrite); 57 }; 58 59 VulkanSwapChain(); 60 ~VulkanSwapChain(); 61 62 // min_image_count is the minimum number of presentable images. 63 bool Initialize(VulkanDeviceQueue* device_queue, 64 VkSurfaceKHR surface, 65 const VkSurfaceFormatKHR& surface_format, 66 const gfx::Size& image_size, 67 uint32_t min_image_count, 68 VkSurfaceTransformFlagBitsKHR pre_transform, 69 bool use_protected_memory, 70 std::unique_ptr<VulkanSwapChain> old_swap_chain); 71 72 // Destroy() should be called when all related GPU tasks have been finished. 73 void Destroy(); 74 75 // Present the current buffer. 76 gfx::SwapResult PresentBuffer(const gfx::Rect& rect); 77 num_images()78 uint32_t num_images() const { return static_cast<uint32_t>(images_.size()); } size()79 const gfx::Size& size() const { return size_; } use_protected_memory()80 bool use_protected_memory() const { return use_protected_memory_; } 81 82 private: 83 bool InitializeSwapChain(VkSurfaceKHR surface, 84 const VkSurfaceFormatKHR& surface_format, 85 const gfx::Size& image_size, 86 uint32_t min_image_count, 87 VkSurfaceTransformFlagBitsKHR pre_transform, 88 bool use_protected_memory, 89 std::unique_ptr<VulkanSwapChain> old_swap_chain); 90 void DestroySwapChain(); 91 92 bool InitializeSwapImages(const VkSurfaceFormatKHR& surface_format); 93 void DestroySwapImages(); 94 95 bool BeginWriteCurrentImage(VkImage* image, 96 uint32_t* image_index, 97 VkImageLayout* layout, 98 VkSemaphore* semaphore); 99 void EndWriteCurrentImage(VkImageLayout layout, VkSemaphore semaphore); 100 bool AcquireNextImage(); 101 102 bool use_protected_memory_ = false; 103 VulkanDeviceQueue* device_queue_ = nullptr; 104 bool is_incremental_present_supported_ = false; 105 VkSwapchainKHR swap_chain_ = VK_NULL_HANDLE; 106 107 std::unique_ptr<VulkanCommandPool> command_pool_; 108 109 gfx::Size size_; 110 111 struct ImageData { 112 ImageData(); 113 ImageData(ImageData&& other); 114 ~ImageData(); 115 116 ImageData& operator=(ImageData&& other); 117 118 VkImage image = VK_NULL_HANDLE; 119 VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; 120 std::unique_ptr<VulkanCommandBuffer> command_buffer; 121 // Semaphore passed to vkQueuePresentKHR to wait on. 122 VkSemaphore present_begin_semaphore = VK_NULL_HANDLE; 123 // Semaphore signaled when present engine is done with the image. 124 VkSemaphore present_end_semaphore = VK_NULL_HANDLE; 125 }; 126 std::vector<ImageData> images_; 127 128 // Acquired image index. 129 base::circular_deque<uint32_t> in_present_images_; 130 base::Optional<uint32_t> acquired_image_; 131 bool is_writing_ = false; 132 VkSemaphore end_write_semaphore_ = VK_NULL_HANDLE; 133 134 DISALLOW_COPY_AND_ASSIGN(VulkanSwapChain); 135 }; 136 137 } // namespace gpu 138 139 #endif // GPU_VULKAN_VULKAN_SWAP_CHAIN_H_ 140