mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2025-01-10 10:18:46 +00:00
101 lines
4.7 KiB
C++
101 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include "renderer.h"
|
|
|
|
#ifdef Q_OS_WIN32
|
|
#define VK_USE_PLATFORM_WIN32_KHR
|
|
#endif
|
|
|
|
#include <libplacebo/log.h>
|
|
#include <libplacebo/renderer.h>
|
|
#include <libplacebo/vulkan.h>
|
|
|
|
class PlVkRenderer : public IFFmpegRenderer {
|
|
public:
|
|
PlVkRenderer(IFFmpegRenderer* backendRenderer);
|
|
virtual ~PlVkRenderer() override;
|
|
virtual bool initialize(PDECODER_PARAMETERS params) override;
|
|
virtual bool prepareDecoderContext(AVCodecContext* context, AVDictionary** options) override;
|
|
virtual void renderFrame(AVFrame* frame) override;
|
|
virtual bool testRenderFrame(AVFrame* frame) override;
|
|
virtual void waitToRender() override;
|
|
virtual void cleanupRenderContext() override;
|
|
virtual void notifyOverlayUpdated(Overlay::OverlayType) override;
|
|
virtual bool notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO) override;
|
|
virtual int getRendererAttributes() override;
|
|
virtual int getDecoderCapabilities() override;
|
|
virtual bool needsTestFrame() override;
|
|
virtual bool isPixelFormatSupported(int videoFormat, enum AVPixelFormat pixelFormat) override;
|
|
virtual AVPixelFormat getPreferredPixelFormat(int videoFormat) override;
|
|
virtual RendererType getRendererType() override;
|
|
|
|
private:
|
|
static void lockQueue(AVHWDeviceContext *dev_ctx, uint32_t queue_family, uint32_t index);
|
|
static void unlockQueue(AVHWDeviceContext *dev_ctx, uint32_t queue_family, uint32_t index);
|
|
static void overlayUploadComplete(void* opaque);
|
|
|
|
bool mapAvFrameToPlacebo(const AVFrame *frame, pl_frame* mappedFrame);
|
|
bool getQueue(VkQueueFlags requiredFlags, uint32_t* queueIndex, uint32_t* queueCount);
|
|
bool chooseVulkanDevice(PDECODER_PARAMETERS params);
|
|
bool tryInitializeDevice(VkPhysicalDevice device, VkPhysicalDeviceProperties* deviceProps, PDECODER_PARAMETERS decoderParams);
|
|
bool isExtensionSupportedByPhysicalDevice(VkPhysicalDevice device, const char* extensionName);
|
|
bool isPresentModeSupportedByPhysicalDevice(VkPhysicalDevice device, VkPresentModeKHR presentMode);
|
|
bool isColorSpaceSupportedByPhysicalDevice(VkPhysicalDevice device, VkColorSpaceKHR colorSpace);
|
|
bool isSurfacePresentationSupportedByPhysicalDevice(VkPhysicalDevice device);
|
|
|
|
// The backend renderer if we're frontend-only
|
|
IFFmpegRenderer* m_Backend;
|
|
|
|
// SDL state
|
|
SDL_Window* m_Window = nullptr;
|
|
|
|
// The libplacebo rendering state
|
|
pl_log m_Log = nullptr;
|
|
pl_vk_inst m_PlVkInstance = nullptr;
|
|
VkSurfaceKHR m_VkSurface = nullptr;
|
|
pl_vulkan m_Vulkan = nullptr;
|
|
pl_swapchain m_Swapchain = nullptr;
|
|
pl_renderer m_Renderer = nullptr;
|
|
pl_tex m_Textures[PL_MAX_PLANES] = {};
|
|
pl_color_space m_LastColorspace = {};
|
|
|
|
// Pending swapchain state shared between waitToRender(), renderFrame(), and cleanupRenderContext()
|
|
pl_swapchain_frame m_SwapchainFrame = {};
|
|
bool m_HasPendingSwapchainFrame = false;
|
|
|
|
// Overlay state
|
|
SDL_SpinLock m_OverlayLock = 0;
|
|
struct {
|
|
// The staging overlay state is copied here under the overlay lock in the render thread.
|
|
//
|
|
// These values can be safely read by the render thread outside of the overlay lock,
|
|
// but the copy from stagingOverlay to overlay must only happen under the overlay
|
|
// lock when hasStagingOverlay is true.
|
|
bool hasOverlay;
|
|
pl_overlay overlay;
|
|
|
|
// This state is written by the overlay update thread
|
|
//
|
|
// NB: hasStagingOverlay may be false even if there is a staging overlay texture present,
|
|
// because this is how the overlay update path indicates that the overlay is not currently
|
|
// safe for the render thread to read.
|
|
//
|
|
// It is safe for the overlay update thread to write to stagingOverlay outside of the lock,
|
|
// as long as hasStagingOverlay is false.
|
|
bool hasStagingOverlay;
|
|
pl_overlay stagingOverlay;
|
|
} m_Overlays[Overlay::OverlayMax] = {};
|
|
|
|
// Device context used for hwaccel decoders
|
|
AVBufferRef* m_HwDeviceCtx = nullptr;
|
|
|
|
// Vulkan functions we call directly
|
|
PFN_vkDestroySurfaceKHR fn_vkDestroySurfaceKHR = nullptr;
|
|
PFN_vkGetPhysicalDeviceQueueFamilyProperties fn_vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
|
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fn_vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
|
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fn_vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
|
|
PFN_vkEnumeratePhysicalDevices fn_vkEnumeratePhysicalDevices = nullptr;
|
|
PFN_vkGetPhysicalDeviceProperties fn_vkGetPhysicalDeviceProperties = nullptr;
|
|
PFN_vkGetPhysicalDeviceSurfaceSupportKHR fn_vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
|
PFN_vkEnumerateDeviceExtensionProperties fn_vkEnumerateDeviceExtensionProperties = nullptr;
|
|
};
|