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