99 lines
3.5 KiB
99 lines
3.5 KiB
#ifndef DISPLAY_VK_H
|
|
#define DISPLAY_VK_H
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
#include "CompositorVk.h"
|
|
#include "Hwc2.h"
|
|
#include "RenderContext.h"
|
|
#include "SwapChainStateVk.h"
|
|
#include "vulkan/cereal/common/goldfish_vk_dispatch.h"
|
|
|
|
// The DisplayVk class holds the Vulkan and other states required to draw a
|
|
// frame in a host window.
|
|
|
|
class DisplayVk {
|
|
public:
|
|
class DisplayBufferInfo {
|
|
public:
|
|
~DisplayBufferInfo();
|
|
|
|
private:
|
|
DisplayBufferInfo(const goldfish_vk::VulkanDispatch &, VkDevice,
|
|
uint32_t width, uint32_t height, VkFormat, VkImage);
|
|
|
|
const goldfish_vk::VulkanDispatch &m_vk;
|
|
VkDevice m_vkDevice;
|
|
uint32_t m_width;
|
|
uint32_t m_height;
|
|
VkFormat m_vkFormat;
|
|
|
|
VkImageView m_vkImageView;
|
|
|
|
friend class DisplayVk;
|
|
};
|
|
DisplayVk(const goldfish_vk::VulkanDispatch &, VkPhysicalDevice,
|
|
uint32_t swapChainQueueFamilyIndex,
|
|
uint32_t compositorQueueFamilyIndex, VkDevice,
|
|
VkQueue compositorVkQueue, VkQueue swapChainVkQueue);
|
|
~DisplayVk();
|
|
void bindToSurface(VkSurfaceKHR, uint32_t width, uint32_t height);
|
|
// The caller is responsible to make sure the VkImage lives longer than the
|
|
// DisplayBufferInfo created here. However, given that DisplayBufferInfo
|
|
// lives in a shared_ptr, the potential lifetime of DisplayBufferInfo is
|
|
// aligned to DisplayVk when DisplayVk::m_surfaceState::m_prevDisplayBuffer
|
|
// is locked and upgraded to a shared_ptr in DisplayVk::post.
|
|
std::shared_ptr<DisplayBufferInfo> createDisplayBuffer(VkImage, VkFormat,
|
|
uint32_t width,
|
|
uint32_t height);
|
|
void post(const std::shared_ptr<DisplayBufferInfo> &);
|
|
|
|
void compose(
|
|
uint32_t numLayers, const ComposeLayer layers[],
|
|
const std::vector<std::shared_ptr<DisplayBufferInfo>> &composeBuffers);
|
|
|
|
private:
|
|
bool canComposite(VkFormat);
|
|
// Returns if the composition specified by the parameter is different from
|
|
// the previous composition. If the composition is different, update the
|
|
// previous composition stored in m_surfaceState. Must be called after
|
|
// bindToSurface() is called.
|
|
bool compareAndSaveComposition(
|
|
uint32_t renderTargetIndex, uint32_t numLayers,
|
|
const ComposeLayer layers[],
|
|
const std::vector<std::shared_ptr<DisplayBufferInfo>> &composeBuffers);
|
|
|
|
const goldfish_vk::VulkanDispatch &m_vk;
|
|
VkPhysicalDevice m_vkPhysicalDevice;
|
|
uint32_t m_swapChainQueueFamilyIndex;
|
|
uint32_t m_compositorQueueFamilyIndex;
|
|
VkDevice m_vkDevice;
|
|
VkQueue m_compositorVkQueue;
|
|
VkQueue m_swapChainVkQueue;
|
|
VkCommandPool m_vkCommandPool;
|
|
VkSampler m_compositionVkSampler;
|
|
VkFence m_frameDrawCompleteFence;
|
|
VkSemaphore m_imageReadySem;
|
|
VkSemaphore m_frameDrawCompleteSem;
|
|
|
|
std::unique_ptr<SwapChainStateVk> m_swapChainStateVk;
|
|
std::unique_ptr<CompositorVk> m_compositorVk;
|
|
struct SurfaceState {
|
|
struct Layer {
|
|
ComposeLayer m_hwc2Layer;
|
|
std::weak_ptr<DisplayBufferInfo> m_displayBuffer;
|
|
};
|
|
|
|
uint32_t m_width = 0;
|
|
uint32_t m_height = 0;
|
|
std::unordered_map<uint32_t, std::vector<std::unique_ptr<Layer>>>
|
|
m_prevCompositions;
|
|
};
|
|
std::unique_ptr<SurfaceState> m_surfaceState;
|
|
std::unordered_map<VkFormat, bool> m_canComposite;
|
|
};
|
|
|
|
#endif
|