• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef COMPOSITOR_VK_H
2 #define COMPOSITOR_VK_H
3 
4 #include <array>
5 #include <glm/glm.hpp>
6 #include <memory>
7 #include <optional>
8 #include <tuple>
9 #include <variant>
10 #include <vector>
11 
12 #include "Hwc2.h"
13 #include "base/Lock.h"
14 #include "vulkan/cereal/common/goldfish_vk_dispatch.h"
15 #include "vulkan/vk_util.h"
16 
17 class ComposeLayerVk {
18    public:
19     VkSampler m_vkSampler;
20     VkImageView m_vkImageView;
21     struct LayerTransform {
22         glm::mat4 pos;
23         glm::mat4 texcoord;
24     } m_layerTransform;
25 
26     static std::unique_ptr<ComposeLayerVk> createFromHwc2ComposeLayer(
27         VkSampler, VkImageView, const ComposeLayer &, uint32_t cbWidth, uint32_t cbHeight,
28         uint32_t dstWidth, uint32_t dstHeight);
29 
30    private:
31     ComposeLayerVk() = delete;
32     explicit ComposeLayerVk(VkSampler, VkImageView, const LayerTransform &);
33 };
34 
35 // If we want to apply transform to all layers to rotate/clip/position the
36 // virtual display, we should add that functionality here.
37 class Composition {
38    public:
39     std::vector<std::unique_ptr<ComposeLayerVk>> m_composeLayers;
40 
41     Composition() = delete;
42     explicit Composition(std::vector<std::unique_ptr<ComposeLayerVk>> composeLayers);
43 };
44 
45 class CompositorVkRenderTarget;
46 
47 struct CompositorVkBase
48     : public vk_util::RunSingleTimeCommand<
49           CompositorVkBase,
50           vk_util::FindMemoryType<CompositorVkBase,
51                                   vk_util::RecordImageLayoutTransformCommands<CompositorVkBase>>> {
52     const goldfish_vk::VulkanDispatch &m_vk;
53     const VkDevice m_vkDevice;
54     const VkPhysicalDevice m_vkPhysicalDevice;
55     const VkQueue m_vkQueue;
56     std::shared_ptr<android::base::Lock> m_vkQueueLock;
57     VkDescriptorSetLayout m_vkDescriptorSetLayout;
58     VkPipelineLayout m_vkPipelineLayout;
59     VkRenderPass m_vkRenderPass;
60     VkPipeline m_graphicsVkPipeline;
61     VkBuffer m_vertexVkBuffer;
62     VkDeviceMemory m_vertexVkDeviceMemory;
63     VkBuffer m_indexVkBuffer;
64     VkDeviceMemory m_indexVkDeviceMemory;
65     VkDescriptorPool m_vkDescriptorPool;
66     std::vector<VkDescriptorSet> m_vkDescriptorSets;
67 
68     VkCommandPool m_vkCommandPool;
69 
CompositorVkBaseCompositorVkBase70     explicit CompositorVkBase(const goldfish_vk::VulkanDispatch &vk, VkDevice device,
71                               VkPhysicalDevice physicalDevice, VkQueue queue,
72                               std::shared_ptr<android::base::Lock> queueLock,
73                               VkCommandPool commandPool)
74         : m_vk(vk),
75           m_vkDevice(device),
76           m_vkPhysicalDevice(physicalDevice),
77           m_vkQueue(queue),
78           m_vkQueueLock(queueLock),
79           m_vkDescriptorSetLayout(VK_NULL_HANDLE),
80           m_vkPipelineLayout(VK_NULL_HANDLE),
81           m_vkRenderPass(VK_NULL_HANDLE),
82           m_graphicsVkPipeline(VK_NULL_HANDLE),
83           m_vertexVkBuffer(VK_NULL_HANDLE),
84           m_vertexVkDeviceMemory(VK_NULL_HANDLE),
85           m_indexVkBuffer(VK_NULL_HANDLE),
86           m_indexVkDeviceMemory(VK_NULL_HANDLE),
87           m_vkDescriptorPool(VK_NULL_HANDLE),
88           m_vkDescriptorSets(0),
89           m_vkCommandPool(commandPool) {}
90 };
91 
92 class CompositorVk : protected CompositorVkBase {
93    public:
94     static std::unique_ptr<CompositorVk> create(
95         const goldfish_vk::VulkanDispatch &vk, VkDevice, VkPhysicalDevice, VkQueue,
96         std::shared_ptr<android::base::Lock> queueLock, VkFormat, VkImageLayout initialLayout,
97         VkImageLayout finalLayout, uint32_t maxFramesInFlight, VkCommandPool, VkSampler);
98     static bool validateQueueFamilyProperties(const VkQueueFamilyProperties &properties);
99 
100     ~CompositorVk();
101     void recordCommandBuffers(uint32_t renderTargetIndex, VkCommandBuffer,
102                               const CompositorVkRenderTarget &);
103     void setComposition(uint32_t i, std::unique_ptr<Composition> &&composition);
104     std::unique_ptr<CompositorVkRenderTarget> createRenderTarget(VkImageView, uint32_t width,
105                                                                  uint32_t height);
106 
107    private:
108     explicit CompositorVk(const goldfish_vk::VulkanDispatch &, VkDevice, VkPhysicalDevice, VkQueue,
109                           std::shared_ptr<android::base::Lock> queueLock, VkCommandPool,
110                           uint32_t maxFramesInFlight);
111     void setUpGraphicsPipeline(VkFormat renderTargetFormat, VkImageLayout initialLayout,
112                                VkImageLayout finalLayout, VkSampler);
113     void setUpVertexBuffers();
114     void setUpDescriptorSets();
115     void setUpEmptyComposition(VkFormat);
116     void setUpUniformBuffers();
117 
118     std::optional<std::tuple<VkBuffer, VkDeviceMemory>> createBuffer(VkDeviceSize,
119                                                                      VkBufferUsageFlags,
120                                                                      VkMemoryPropertyFlags) const;
121     std::tuple<VkBuffer, VkDeviceMemory> createStagingBufferWithData(const void *data,
122                                                                      VkDeviceSize size) const;
123     void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize) const;
124 
125     struct UniformBufferObject {
126         alignas(16) glm::mat4 pos_transform;
127         alignas(16) glm::mat4 texcoord_transform;
128     };
129 
130     struct Vertex {
131         alignas(8) glm::vec2 pos;
132         alignas(8) glm::vec2 texPos;
133 
134         static VkVertexInputBindingDescription getBindingDescription();
135         static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescription();
136     };
137 
138     static const std::vector<Vertex> k_vertices;
139     static const std::vector<uint16_t> k_indices;
140 
141     uint32_t m_maxFramesInFlight;
142     VkSampler m_vkSampler;
143 
144     std::vector<std::unique_ptr<Composition>> m_currentCompositions;
145     struct UniformStorage {
146         VkBuffer m_vkBuffer;
147         VkDeviceMemory m_vkDeviceMemory;
148         void *m_data;
149         VkDeviceSize m_stride;
150     } m_uniformStorage;
151 };
152 
153 class CompositorVkRenderTarget {
154    public:
155     ~CompositorVkRenderTarget();
156 
157    private:
158     const goldfish_vk::VulkanDispatch &m_vk;
159     VkDevice m_vkDevice;
160     VkFramebuffer m_vkFramebuffer;
161     uint32_t m_width;
162     uint32_t m_height;
163     CompositorVkRenderTarget(const goldfish_vk::VulkanDispatch &, VkDevice, VkImageView,
164                              uint32_t width, uint32_t height, VkRenderPass);
165     friend class CompositorVk;
166 };
167 
168 #endif /* COMPOSITOR_VK_H */
169