Share DRM FD and GBM device with SDL

Depends on https://hg.libsdl.org/SDL/rev/d75deb75464a
This commit is contained in:
Cameron Gutman 2021-01-30 21:11:52 -06:00
parent a97912e297
commit dbfdc2fd14
4 changed files with 50 additions and 41 deletions

View file

@ -18,6 +18,8 @@ extern "C" {
#include <SDL_egl.h> #include <SDL_egl.h>
#endif #endif
#include <SDL_syswm.h>
DrmRenderer::DrmRenderer() DrmRenderer::DrmRenderer()
: m_HwContext(nullptr), : m_HwContext(nullptr),
m_DrmFd(-1), m_DrmFd(-1),
@ -33,13 +35,16 @@ DrmRenderer::~DrmRenderer()
drmModeRmFB(m_DrmFd, m_CurrentFbId); drmModeRmFB(m_DrmFd, m_CurrentFbId);
} }
if (m_DrmFd != -1) {
close(m_DrmFd);
}
if (m_HwContext != nullptr) { if (m_HwContext != nullptr) {
av_buffer_unref(&m_HwContext); 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**) bool DrmRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**)
@ -52,11 +57,34 @@ bool DrmRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**)
return true; return true;
} }
bool DrmRenderer::initialize(PDECODER_PARAMETERS) bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
{ {
const char* device = SDL_getenv("DRM_DEV");
int i; 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) { if (device == nullptr) {
device = "/dev/dri/card0"; device = "/dev/dri/card0";
} }
@ -72,6 +100,7 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS)
errno); errno);
return false; return false;
} }
#endif
drmModeRes* resources = drmModeGetResources(m_DrmFd); drmModeRes* resources = drmModeGetResources(m_DrmFd);
if (resources == nullptr) { if (resources == nullptr) {

View file

@ -34,6 +34,9 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platf
#ifndef EGL_PLATFORM_X11_KHR #ifndef EGL_PLATFORM_X11_KHR
#define EGL_PLATFORM_X11_KHR 0x31D5 #define EGL_PLATFORM_X11_KHR 0x31D5
#endif #endif
#ifndef EGL_PLATFORM_GBM_KHR
#define EGL_PLATFORM_GBM_KHR 0x31D7
#endif
typedef struct _OVERLAY_VERTEX typedef struct _OVERLAY_VERTEX
{ {
@ -479,6 +482,13 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params)
return false; return false;
} }
break; 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 #endif
default: default:
EGL_LOG(Error, "not compatible with SYSWM"); EGL_LOG(Error, "not compatible with SYSWM");

View file

@ -14,7 +14,6 @@
VAAPIRenderer::VAAPIRenderer() VAAPIRenderer::VAAPIRenderer()
: m_HwContext(nullptr), : m_HwContext(nullptr),
m_DrmFd(-1),
m_BlacklistedForDirectRendering(false) m_BlacklistedForDirectRendering(false)
{ {
#ifdef HAVE_EGL #ifdef HAVE_EGL
@ -39,10 +38,6 @@ VAAPIRenderer::~VAAPIRenderer()
vaTerminate(display); vaTerminate(display);
} }
} }
if (m_DrmFd != -1) {
close(m_DrmFd);
}
} }
VADisplay VADisplay
@ -90,41 +85,17 @@ VAAPIRenderer::openDisplay(SDL_Window* window)
return nullptr; return nullptr;
#endif #endif
} }
// TODO: Upstream a better solution for SDL_GetWindowWMInfo on KMSDRM #if defined(SDL_VIDEO_DRIVER_KMSDRM) && defined(HAVE_LIBVA_DRM) && SDL_VERSION_ATLEAST(2, 0, 15)
else if (strcmp(SDL_GetCurrentVideoDriver(), "KMSDRM") == 0) { else if (info.subsystem == SDL_SYSWM_KMSDRM) {
#ifdef HAVE_LIBVA_DRM SDL_assert(info.info.kmsdrm.drm_fd >= 0);
if (m_DrmFd < 0) { display = vaGetDisplayDRM(info.info.kmsdrm.drm_fd);
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 (display == nullptr) { if (display == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unable to open DRM display for VAAPI"); "Unable to open DRM display for VAAPI");
return nullptr; return nullptr;
} }
#else
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Moonlight not compiled with VAAPI DRM support!");
return nullptr;
#endif
} }
#endif
else { else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Unsupported VAAPI rendering subsystem: %d", "Unsupported VAAPI rendering subsystem: %d",

View file

@ -54,7 +54,6 @@ private:
int m_WindowSystem; int m_WindowSystem;
AVBufferRef* m_HwContext; AVBufferRef* m_HwContext;
int m_DrmFd;
bool m_BlacklistedForDirectRendering; bool m_BlacklistedForDirectRendering;
#ifdef HAVE_LIBVA_X11 #ifdef HAVE_LIBVA_X11