mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-04-10 09:46:09 +00:00
Bring back DRM atomic test commit using new DRM master lock
The DRM master lock avoids race conditions between Qt taking master to draw the GUI and the DRM renderer performing a test commit.
This commit is contained in:
@@ -75,6 +75,13 @@ extern "C" {
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef HAVE_DRM_MASTER_HOOKS
|
||||
extern "C" {
|
||||
void lockDrmMaster();
|
||||
void unlockDrmMaster();
|
||||
}
|
||||
#endif
|
||||
|
||||
// This map is used to lookup characteristics of a given DRM format
|
||||
//
|
||||
// All DRM formats that we want to try when selecting a plane must
|
||||
@@ -1653,8 +1660,8 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode
|
||||
drmFrame = (AVDRMFrameDescriptor*)frame->data[0];
|
||||
}
|
||||
|
||||
// If we're testing, check the IN_FORMATS property or legacy plane formats
|
||||
if (testMode) {
|
||||
// For non-atomic drivers, check the IN_FORMATS property or legacy plane formats
|
||||
if (testMode && !m_PropSetter.isAtomic()) {
|
||||
bool formatMatch = false;
|
||||
|
||||
uint64_t maskedModifier = drmFrame->objects[0].format_modifier;
|
||||
@@ -1785,6 +1792,75 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode
|
||||
return false;
|
||||
}
|
||||
|
||||
// For atomic drivers, we'll use a test-only commit to confirm this plane+FB works
|
||||
if (testMode && m_PropSetter.isAtomic()) {
|
||||
SDL_Rect src, dst;
|
||||
src.x = src.y = 0;
|
||||
src.w = frame->width;
|
||||
src.h = frame->height;
|
||||
|
||||
// This isn't a completely accurate test since SDL hasn't modeset to the new
|
||||
// display resolution that we'll actually be using for streaming (since we're
|
||||
// still not committed to even using DrmRenderer for rendering yet). Hopefully,
|
||||
// it will be good enough though.
|
||||
dst.x = dst.y = 0;
|
||||
drmModeCrtc* crtc = drmModeGetCrtc(m_DrmFd, m_Crtc.objectId());
|
||||
if (crtc != nullptr) {
|
||||
dst.w = crtc->width;
|
||||
dst.h = crtc->height;
|
||||
drmModeFreeCrtc(crtc);
|
||||
}
|
||||
else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"drmModeGetCrtc() failed: %d",
|
||||
errno);
|
||||
|
||||
// We'll just hope for the best here
|
||||
dst.w = frame->width;
|
||||
dst.h = frame->height;
|
||||
}
|
||||
|
||||
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
|
||||
|
||||
// Temporarily take DRM master if we dropped it after initialization
|
||||
if (!m_DrmStateModified) {
|
||||
#ifdef HAVE_DRM_MASTER_HOOKS
|
||||
lockDrmMaster();
|
||||
#endif
|
||||
drmSetMaster(m_DrmFd);
|
||||
}
|
||||
bool testResult = m_PropSetter.testPlane(m_VideoPlane,
|
||||
m_Crtc.objectId(),
|
||||
*newFbId,
|
||||
dst.x, dst.y,
|
||||
dst.w, dst.h,
|
||||
0, 0,
|
||||
frame->width << 16,
|
||||
frame->height << 16);
|
||||
if (!m_DrmStateModified) {
|
||||
drmDropMaster(m_DrmFd);
|
||||
#ifdef HAVE_DRM_MASTER_HOOKS
|
||||
unlockDrmMaster();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (testResult) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Selected DRM plane supports chosen decoding format and modifier: " FOURCC_FMT " %016" PRIx64,
|
||||
FOURCC_FMT_ARGS(drmFrame->layers[0].format),
|
||||
drmFrame->objects[0].format_modifier);
|
||||
}
|
||||
else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Selected DRM plane doesn't support chosen decoding format and modifier: " FOURCC_FMT " %016" PRIx64,
|
||||
FOURCC_FMT_ARGS(drmFrame->layers[0].format),
|
||||
drmFrame->objects[0].format_modifier);
|
||||
drmModeRmFB(m_DrmFd, *newFbId);
|
||||
*newFbId = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user