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:
Cameron Gutman
2026-04-06 19:25:03 -05:00
parent 9c11dca454
commit c8d18f8a8e

View File

@@ -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;
}