1 #ifndef DISPLAY_VK_H
2 #define DISPLAY_VK_H
3 
4 #include <deque>
5 #include <functional>
6 #include <future>
7 #include <memory>
8 #include <optional>
9 #include <tuple>
10 #include <unordered_map>
11 #include <unordered_set>
12 
13 #include "BorrowedImage.h"
14 #include "CompositorVk.h"
15 #include "Display.h"
16 #include "DisplaySurfaceVk.h"
17 #include "Hwc2.h"
18 #include "SwapChainStateVk.h"
19 #include "aemu/base/synchronization/Lock.h"
20 #include "goldfish_vk_dispatch.h"
21 
22 // The DisplayVk class holds the Vulkan and other states required to draw a
23 // frame in a host window.
24 
25 namespace gfxstream {
26 namespace vk {
27 
28 class DisplayVk : public gfxstream::Display {
29    public:
30     DisplayVk(const VulkanDispatch&, VkPhysicalDevice, uint32_t swapChainQueueFamilyIndex,
31               uint32_t compositorQueueFamilyIndex, VkDevice, VkQueue compositorVkQueue,
32               std::shared_ptr<android::base::Lock> compositorVkQueueLock, VkQueue swapChainVkQueue,
33               std::shared_ptr<android::base::Lock> swapChainVkQueueLock);
34     ~DisplayVk();
35 
36     PostResult post(const BorrowedImageInfo* info);
37 
38     void drainQueues();
39 
40    protected:
41     void bindToSurfaceImpl(gfxstream::DisplaySurface* surface) override;
42     void surfaceUpdated(gfxstream::DisplaySurface* surface) override;
43     void unbindFromSurfaceImpl() override;
44 
45    private:
46     void destroySwapchain();
47     bool recreateSwapchain();
48 
49     // The success component of the result is false when the swapchain is no longer valid and
50     // bindToSurface() needs to be called again. When the success component is true, the waitable
51     // component of the returned result is a future that will complete when the GPU side of work
52     // completes. The caller is responsible to guarantee the synchronization and the layout of
53     // ColorBufferCompositionInfo::m_vkImage is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL.
54     PostResult postImpl(const BorrowedImageInfo* info);
55 
56     VkFormatFeatureFlags getFormatFeatures(VkFormat, VkImageTiling);
57     bool canPost(const VkImageCreateInfo&);
58 
59     const VulkanDispatch& m_vk;
60     VkPhysicalDevice m_vkPhysicalDevice;
61     uint32_t m_swapChainQueueFamilyIndex;
62     uint32_t m_compositorQueueFamilyIndex;
63     VkDevice m_vkDevice;
64     VkQueue m_compositorVkQueue;
65     std::shared_ptr<android::base::Lock> m_compositorVkQueueLock;
66     VkQueue m_swapChainVkQueue;
67     std::shared_ptr<android::base::Lock> m_swapChainVkQueueLock;
68     VkCommandPool m_vkCommandPool;
69 
70     class PostResource {
71        public:
72         const VkFence m_swapchainImageReleaseFence;
73         const VkSemaphore m_swapchainImageAcquireSemaphore;
74         const VkSemaphore m_swapchainImageReleaseSemaphore;
75         const VkCommandBuffer m_vkCommandBuffer;
76         static std::shared_ptr<PostResource> create(const VulkanDispatch&, VkDevice, VkCommandPool);
77         ~PostResource();
78         DISALLOW_COPY_ASSIGN_AND_MOVE(PostResource);
79 
80        private:
81         PostResource(const VulkanDispatch&, VkDevice, VkCommandPool,
82                      VkFence swapchainImageReleaseFence, VkSemaphore swapchainImageAcquireSemaphore,
83                      VkSemaphore swapchainImageReleaseSemaphore, VkCommandBuffer);
84         const VulkanDispatch& m_vk;
85         const VkDevice m_vkDevice;
86         const VkCommandPool m_vkCommandPool;
87     };
88 
89     std::deque<std::shared_ptr<PostResource>> m_freePostResources;
90     std::vector<std::optional<std::shared_future<std::shared_ptr<PostResource>>>>
91         m_postResourceFutures;
92     int m_inFlightFrameIndex;
93 
94     class ImageBorrowResource {
95        public:
96         const VkFence m_completeFence;
97         const VkCommandBuffer m_vkCommandBuffer;
98         static std::unique_ptr<ImageBorrowResource> create(const VulkanDispatch&, VkDevice,
99                                                            VkCommandPool);
100         ~ImageBorrowResource();
101         DISALLOW_COPY_ASSIGN_AND_MOVE(ImageBorrowResource);
102 
103        private:
104         ImageBorrowResource(const VulkanDispatch&, VkDevice, VkCommandPool, VkFence,
105                             VkCommandBuffer);
106         const VulkanDispatch& m_vk;
107         const VkDevice m_vkDevice;
108         const VkCommandPool m_vkCommandPool;
109     };
110     std::vector<std::unique_ptr<ImageBorrowResource>> m_imageBorrowResources;
111 
112     std::unique_ptr<SwapChainStateVk> m_swapChainStateVk;
113     bool m_needToRecreateSwapChain = true;
114 
115     std::unordered_map<VkFormat, VkFormatProperties> m_vkFormatProperties;
116 };
117 
118 }  // namespace vk
119 }  // namespace gfxstream
120 
121 #endif
122