mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-04-22 16:08:45 +00:00
Unify handling of DRM devices between DRM and VAAPI
SDL may not be able to give us a DRM FD for Vulkan windows.
This commit is contained in:
@@ -72,15 +72,6 @@ extern "C" {
|
||||
|
||||
#include <Limelight.h>
|
||||
|
||||
// HACK: Avoid including X11 headers which conflict with QDir
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
#undef SDL_VIDEO_DRIVER_X11
|
||||
#endif
|
||||
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#include <map>
|
||||
|
||||
// This map is used to lookup characteristics of a given DRM format
|
||||
@@ -149,6 +140,7 @@ DrmRenderer::DrmRenderer(AVHWDeviceType hwDeviceType, IFFmpegRenderer *backendRe
|
||||
m_HwDeviceType(hwDeviceType),
|
||||
m_HwContext(nullptr),
|
||||
m_DrmFd(-1),
|
||||
m_DrmIsMaster(false),
|
||||
m_SdlOwnsDrmFd(false),
|
||||
m_SupportsDirectRendering(false),
|
||||
m_VideoFormat(0),
|
||||
@@ -265,6 +257,9 @@ bool DrmRenderer::prepareDecoderContext(AVCodecContext* context, AVDictionary**
|
||||
|
||||
void DrmRenderer::prepareToRender()
|
||||
{
|
||||
// Retake DRM master if we dropped it earlier
|
||||
drmSetMaster(m_DrmFd);
|
||||
|
||||
// Create a dummy renderer to force SDL to complete the modesetting
|
||||
// operation that the KMSDRM backend keeps pending until the next
|
||||
// time we swap buffers. We have to do this before we enumerate
|
||||
@@ -350,68 +345,26 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
||||
m_VideoFormat = params->videoFormat;
|
||||
m_SwFrameMapper.setVideoFormat(params->videoFormat);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 15)
|
||||
SDL_SysWMinfo info;
|
||||
// Try to get the FD that we're sharing with SDL
|
||||
m_DrmFd = StreamUtils::getDrmFdForWindow(m_Window, &m_SdlOwnsDrmFd);
|
||||
if (m_DrmFd >= 0) {
|
||||
// If we got a DRM FD for the window, we can render to it
|
||||
m_DrmIsMaster = true;
|
||||
|
||||
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_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Sharing DRM FD with SDL");
|
||||
|
||||
SDL_assert(info.info.kmsdrm.drm_fd >= 0);
|
||||
m_DrmFd = info.info.kmsdrm.drm_fd;
|
||||
m_SdlOwnsDrmFd = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const char* userDevice = SDL_getenv("DRM_DEV");
|
||||
if (userDevice != nullptr) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Opening user-specified DRM device: %s",
|
||||
userDevice);
|
||||
|
||||
m_DrmFd = open(userDevice, O_RDWR | O_CLOEXEC);
|
||||
// If we just opened a new FD, let's drop master on it
|
||||
// so SDL can take master for Vulkan rendering. We'll
|
||||
// regrab master later if we end up direct rendering.
|
||||
if (!m_SdlOwnsDrmFd) {
|
||||
drmDropMaster(m_DrmFd);
|
||||
}
|
||||
else {
|
||||
QDir driDir("/dev/dri");
|
||||
}
|
||||
else {
|
||||
// Try to open any DRM render node
|
||||
m_DrmFd = StreamUtils::getDrmFd(true);
|
||||
|
||||
// We have to explicitly ask for devices to be returned
|
||||
driDir.setFilter(QDir::Files | QDir::System);
|
||||
|
||||
// Try a render node first since we aren't using DRM for output in this codepath
|
||||
for (QFileInfo& node : driDir.entryInfoList(QStringList("renderD*"))) {
|
||||
QByteArray absolutePath = node.absoluteFilePath().toUtf8();
|
||||
m_DrmFd = open(absolutePath.constData(), O_RDWR | O_CLOEXEC);
|
||||
if (m_DrmFd >= 0) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Opened DRM render node: %s",
|
||||
absolutePath.constData());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If that fails, try to use a primary node and hope for the best
|
||||
if (m_DrmFd < 0) {
|
||||
for (QFileInfo& node : driDir.entryInfoList(QStringList("card*"))) {
|
||||
QByteArray absolutePath = node.absoluteFilePath().toUtf8();
|
||||
m_DrmFd = open(absolutePath.constData(), O_RDWR | O_CLOEXEC);
|
||||
if (m_DrmFd >= 0) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Opened DRM primary node: %s",
|
||||
absolutePath.constData());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drop master in case we somehow got a primary node
|
||||
if (m_DrmFd >= 0) {
|
||||
drmDropMaster(m_DrmFd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +442,7 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
|
||||
// If we're not sharing the DRM FD with SDL, that means we don't
|
||||
// have DRM master, so we can't call drmModeSetPlane(). We can
|
||||
// use EGLRenderer or SDLRenderer to render in this situation.
|
||||
if (!m_SdlOwnsDrmFd) {
|
||||
if (!m_DrmIsMaster) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Direct rendering via DRM is disabled");
|
||||
return DIRECT_RENDERING_INIT_FAILED;
|
||||
|
||||
Reference in New Issue
Block a user