#ifndef DISPLAY_VK_H #define DISPLAY_VK_H #include #include #include #include #include #include #include #include #include "BorrowedImage.h" #include "CompositorVk.h" #include "Display.h" #include "DisplaySurfaceVk.h" #include "Hwc2.h" #include "SwapChainStateVk.h" #include "aemu/base/synchronization/Lock.h" #include "goldfish_vk_dispatch.h" // The DisplayVk class holds the Vulkan and other states required to draw a // frame in a host window. namespace gfxstream { namespace vk { class DisplayVk : public gfxstream::Display { public: DisplayVk(const VulkanDispatch&, VkPhysicalDevice, uint32_t swapChainQueueFamilyIndex, uint32_t compositorQueueFamilyIndex, VkDevice, VkQueue compositorVkQueue, std::shared_ptr compositorVkQueueLock, VkQueue swapChainVkQueue, std::shared_ptr swapChainVkQueueLock); ~DisplayVk(); PostResult post(const BorrowedImageInfo* info); void drainQueues(); protected: void bindToSurfaceImpl(gfxstream::DisplaySurface* surface) override; void surfaceUpdated(gfxstream::DisplaySurface* surface) override; void unbindFromSurfaceImpl() override; private: void destroySwapchain(); bool recreateSwapchain(); // The success component of the result is false when the swapchain is no longer valid and // bindToSurface() needs to be called again. When the success component is true, the waitable // component of the returned result is a future that will complete when the GPU side of work // completes. The caller is responsible to guarantee the synchronization and the layout of // ColorBufferCompositionInfo::m_vkImage is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL. PostResult postImpl(const BorrowedImageInfo* info); VkFormatFeatureFlags getFormatFeatures(VkFormat, VkImageTiling); bool canPost(const VkImageCreateInfo&); const VulkanDispatch& m_vk; VkPhysicalDevice m_vkPhysicalDevice; uint32_t m_swapChainQueueFamilyIndex; uint32_t m_compositorQueueFamilyIndex; VkDevice m_vkDevice; VkQueue m_compositorVkQueue; std::shared_ptr m_compositorVkQueueLock; VkQueue m_swapChainVkQueue; std::shared_ptr m_swapChainVkQueueLock; VkCommandPool m_vkCommandPool; class PostResource { public: const VkFence m_swapchainImageReleaseFence; const VkSemaphore m_swapchainImageAcquireSemaphore; const VkSemaphore m_swapchainImageReleaseSemaphore; const VkCommandBuffer m_vkCommandBuffer; static std::shared_ptr create(const VulkanDispatch&, VkDevice, VkCommandPool); ~PostResource(); DISALLOW_COPY_ASSIGN_AND_MOVE(PostResource); private: PostResource(const VulkanDispatch&, VkDevice, VkCommandPool, VkFence swapchainImageReleaseFence, VkSemaphore swapchainImageAcquireSemaphore, VkSemaphore swapchainImageReleaseSemaphore, VkCommandBuffer); const VulkanDispatch& m_vk; const VkDevice m_vkDevice; const VkCommandPool m_vkCommandPool; }; std::deque> m_freePostResources; std::vector>>> m_postResourceFutures; int m_inFlightFrameIndex; class ImageBorrowResource { public: const VkFence m_completeFence; const VkCommandBuffer m_vkCommandBuffer; static std::unique_ptr create(const VulkanDispatch&, VkDevice, VkCommandPool); ~ImageBorrowResource(); DISALLOW_COPY_ASSIGN_AND_MOVE(ImageBorrowResource); private: ImageBorrowResource(const VulkanDispatch&, VkDevice, VkCommandPool, VkFence, VkCommandBuffer); const VulkanDispatch& m_vk; const VkDevice m_vkDevice; const VkCommandPool m_vkCommandPool; }; std::vector> m_imageBorrowResources; std::unique_ptr m_swapChainStateVk; bool m_needToRecreateSwapChain = true; std::unordered_map m_vkFormatProperties; }; } // namespace vk } // namespace gfxstream #endif