1 #ifndef DISPLAY_VK_H 2 #define DISPLAY_VK_H 3 4 #include <functional> 5 #include <memory> 6 #include <unordered_map> 7 8 #include "CompositorVk.h" 9 #include "Hwc2.h" 10 #include "RenderContext.h" 11 #include "SwapChainStateVk.h" 12 #include "vulkan/cereal/common/goldfish_vk_dispatch.h" 13 14 // The DisplayVk class holds the Vulkan and other states required to draw a 15 // frame in a host window. 16 17 class DisplayVk { 18 public: 19 class DisplayBufferInfo { 20 public: 21 ~DisplayBufferInfo(); 22 23 private: 24 DisplayBufferInfo(const goldfish_vk::VulkanDispatch &, VkDevice, 25 uint32_t width, uint32_t height, VkFormat, VkImage); 26 27 const goldfish_vk::VulkanDispatch &m_vk; 28 VkDevice m_vkDevice; 29 uint32_t m_width; 30 uint32_t m_height; 31 VkFormat m_vkFormat; 32 33 VkImageView m_vkImageView; 34 35 friend class DisplayVk; 36 }; 37 DisplayVk(const goldfish_vk::VulkanDispatch &, VkPhysicalDevice, 38 uint32_t swapChainQueueFamilyIndex, 39 uint32_t compositorQueueFamilyIndex, VkDevice, 40 VkQueue compositorVkQueue, VkQueue swapChainVkQueue); 41 ~DisplayVk(); 42 void bindToSurface(VkSurfaceKHR, uint32_t width, uint32_t height); 43 // The caller is responsible to make sure the VkImage lives longer than the 44 // DisplayBufferInfo created here. However, given that DisplayBufferInfo 45 // lives in a shared_ptr, the potential lifetime of DisplayBufferInfo is 46 // aligned to DisplayVk when DisplayVk::m_surfaceState::m_prevDisplayBuffer 47 // is locked and upgraded to a shared_ptr in DisplayVk::post. 48 std::shared_ptr<DisplayBufferInfo> createDisplayBuffer(VkImage, VkFormat, 49 uint32_t width, 50 uint32_t height); 51 void post(const std::shared_ptr<DisplayBufferInfo> &); 52 53 void compose( 54 uint32_t numLayers, const ComposeLayer layers[], 55 const std::vector<std::shared_ptr<DisplayBufferInfo>> &composeBuffers); 56 57 private: 58 bool canComposite(VkFormat); 59 // Returns if the composition specified by the parameter is different from 60 // the previous composition. If the composition is different, update the 61 // previous composition stored in m_surfaceState. Must be called after 62 // bindToSurface() is called. 63 bool compareAndSaveComposition( 64 uint32_t renderTargetIndex, uint32_t numLayers, 65 const ComposeLayer layers[], 66 const std::vector<std::shared_ptr<DisplayBufferInfo>> &composeBuffers); 67 68 const goldfish_vk::VulkanDispatch &m_vk; 69 VkPhysicalDevice m_vkPhysicalDevice; 70 uint32_t m_swapChainQueueFamilyIndex; 71 uint32_t m_compositorQueueFamilyIndex; 72 VkDevice m_vkDevice; 73 VkQueue m_compositorVkQueue; 74 VkQueue m_swapChainVkQueue; 75 VkCommandPool m_vkCommandPool; 76 VkSampler m_compositionVkSampler; 77 VkFence m_frameDrawCompleteFence; 78 VkSemaphore m_imageReadySem; 79 VkSemaphore m_frameDrawCompleteSem; 80 81 std::unique_ptr<SwapChainStateVk> m_swapChainStateVk; 82 std::unique_ptr<CompositorVk> m_compositorVk; 83 struct SurfaceState { 84 struct Layer { 85 ComposeLayer m_hwc2Layer; 86 std::weak_ptr<DisplayBufferInfo> m_displayBuffer; 87 }; 88 89 uint32_t m_width = 0; 90 uint32_t m_height = 0; 91 std::unordered_map<uint32_t, std::vector<std::unique_ptr<Layer>>> 92 m_prevCompositions; 93 }; 94 std::unique_ptr<SurfaceState> m_surfaceState; 95 std::unordered_map<VkFormat, bool> m_canComposite; 96 }; 97 98 #endif 99