From dbfdc2fd149ea4ae9558b6d971674d2b158b7aa9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 30 Jan 2021 21:11:52 -0600 Subject: [PATCH] Share DRM FD and GBM device with SDL Depends on https://hg.libsdl.org/SDL/rev/d75deb75464a --- app/streaming/video/ffmpeg-renderers/drm.cpp | 41 ++++++++++++++++--- .../video/ffmpeg-renderers/eglvid.cpp | 10 +++++ .../video/ffmpeg-renderers/vaapi.cpp | 39 +++--------------- app/streaming/video/ffmpeg-renderers/vaapi.h | 1 - 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 5d40dae6..fb70a613 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -18,6 +18,8 @@ extern "C" { #include #endif +#include + DrmRenderer::DrmRenderer() : m_HwContext(nullptr), m_DrmFd(-1), @@ -33,13 +35,16 @@ DrmRenderer::~DrmRenderer() drmModeRmFB(m_DrmFd, m_CurrentFbId); } - if (m_DrmFd != -1) { - close(m_DrmFd); - } - if (m_HwContext != nullptr) { av_buffer_unref(&m_HwContext); } + +#if !SDL_VERSION_ATLEAST(2, 0, 15) + // This is owned by us on SDL 2.0.14 and earlier + if (m_DrmFd != -1) { + close(m_DrmFd); + } +#endif } bool DrmRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**) @@ -52,11 +57,34 @@ bool DrmRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**) return true; } -bool DrmRenderer::initialize(PDECODER_PARAMETERS) +bool DrmRenderer::initialize(PDECODER_PARAMETERS params) { - const char* device = SDL_getenv("DRM_DEV"); int i; +#if SDL_VERSION_ATLEAST(2, 0, 15) + SDL_SysWMinfo info; + + SDL_VERSION(&info.version); + + if (!SDL_GetWindowWMInfo(params->window, &info)) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_GetWindowWMInfo() failed: %s", + SDL_GetError()); + return false; + } + + if (info.subsystem != SDL_SYSWM_KMSDRM) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Unexpected subsystem in DRM renderer: %d", + info.subsystem); + return false; + } + + SDL_assert(info.info.kmsdrm.drm_fd >= 0); + m_DrmFd = info.info.kmsdrm.drm_fd; +#else + const char* device = SDL_getenv("DRM_DEV"); + if (device == nullptr) { device = "/dev/dri/card0"; } @@ -72,6 +100,7 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS) errno); return false; } +#endif drmModeRes* resources = drmModeGetResources(m_DrmFd); if (resources == nullptr) { diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index c92a108a..e2007e59 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -34,6 +34,9 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platf #ifndef EGL_PLATFORM_X11_KHR #define EGL_PLATFORM_X11_KHR 0x31D5 #endif +#ifndef EGL_PLATFORM_GBM_KHR +#define EGL_PLATFORM_GBM_KHR 0x31D7 +#endif typedef struct _OVERLAY_VERTEX { @@ -479,6 +482,13 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) return false; } break; +#endif +#if SDL_VERSION_ATLEAST(2, 0, 15) && defined(SDL_VIDEO_DRIVER_KMSDRM) + case SDL_SYSWM_KMSDRM: + if (!openDisplay(EGL_PLATFORM_GBM_KHR, info.info.kmsdrm.gbm_dev)) { + return false; + } + break; #endif default: EGL_LOG(Error, "not compatible with SYSWM"); diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index 6c23ee44..8c73b142 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -14,7 +14,6 @@ VAAPIRenderer::VAAPIRenderer() : m_HwContext(nullptr), - m_DrmFd(-1), m_BlacklistedForDirectRendering(false) { #ifdef HAVE_EGL @@ -39,10 +38,6 @@ VAAPIRenderer::~VAAPIRenderer() vaTerminate(display); } } - - if (m_DrmFd != -1) { - close(m_DrmFd); - } } VADisplay @@ -90,41 +85,17 @@ VAAPIRenderer::openDisplay(SDL_Window* window) return nullptr; #endif } - // TODO: Upstream a better solution for SDL_GetWindowWMInfo on KMSDRM - else if (strcmp(SDL_GetCurrentVideoDriver(), "KMSDRM") == 0) { -#ifdef HAVE_LIBVA_DRM - if (m_DrmFd < 0) { - const char* device = SDL_getenv("DRM_DEV"); - - if (device == nullptr) { - device = "/dev/dri/card0"; - } - - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, - "Opening DRM device: %s", - device); - - m_DrmFd = open(device, O_RDWR | O_CLOEXEC); - if (m_DrmFd < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to open DRM device: %d", - errno); - return nullptr; - } - } - - display = vaGetDisplayDRM(m_DrmFd); +#if defined(SDL_VIDEO_DRIVER_KMSDRM) && defined(HAVE_LIBVA_DRM) && SDL_VERSION_ATLEAST(2, 0, 15) + else if (info.subsystem == SDL_SYSWM_KMSDRM) { + SDL_assert(info.info.kmsdrm.drm_fd >= 0); + display = vaGetDisplayDRM(info.info.kmsdrm.drm_fd); if (display == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open DRM display for VAAPI"); return nullptr; } -#else - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Moonlight not compiled with VAAPI DRM support!"); - return nullptr; -#endif } +#endif else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported VAAPI rendering subsystem: %d", diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index 4c424458..9435a9ce 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -54,7 +54,6 @@ private: int m_WindowSystem; AVBufferRef* m_HwContext; - int m_DrmFd; bool m_BlacklistedForDirectRendering; #ifdef HAVE_LIBVA_X11