From c8d18f8a8e5067c976ed7f560e4c8d0d393a2409 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 6 Apr 2026 19:25:03 -0500 Subject: [PATCH] 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. --- app/streaming/video/ffmpeg-renderers/drm.cpp | 80 +++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index c2a345ac..e3846a1d 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -75,6 +75,13 @@ extern "C" { #include +#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; }