Allow Qt to borrow DRM master from SDL to update the UI

This commit is contained in:
Cameron Gutman 2024-09-23 22:15:31 -05:00
parent 6d023c2dfa
commit 054e334066
2 changed files with 54 additions and 1 deletions

View File

@ -42,6 +42,7 @@ uint32_t* g_QtCrtcConnectors;
int g_QtCrtcConnectorCount; int g_QtCrtcConnectorCount;
bool removeSdlFd(int fd); bool removeSdlFd(int fd);
int takeMasterFromSdlFd(void);
int drmIsMaster(int fd) int drmIsMaster(int fd)
{ {
@ -78,6 +79,24 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
return err; return err;
} }
// This hook will temporarily retake DRM master to allow Qt to render while SDL has a DRM FD open
int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, void *user_data)
{
// Call into the real thing
int err = ((typeof(drmModePageFlip)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, crtc_id, fb_id, flags, user_data);
if (err == -EACCES && fd == g_QtDrmMasterFd) {
// If SDL took master from us, try to grab it back temporarily
int oldMasterFd = takeMasterFromSdlFd();
drmSetMaster(fd);
err = ((typeof(drmModePageFlip)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, crtc_id, fb_id, flags, user_data);
drmDropMaster(fd);
if (oldMasterFd != -1) {
drmSetMaster(oldMasterFd);
}
}
return err;
}
// This hook will handle atomic DRM rendering // This hook will handle atomic DRM rendering
int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req,
uint32_t flags, void *user_data) uint32_t flags, void *user_data)
@ -93,7 +112,18 @@ int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req,
} }
// Call into the real thing // Call into the real thing
return ((typeof(drmModeAtomicCommit)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, req, flags, user_data); int err = ((typeof(drmModeAtomicCommit)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, req, flags, user_data);
if (err == -EACCES && fd == g_QtDrmMasterFd) {
// If SDL took master from us, try to grab it back temporarily
int oldMasterFd = takeMasterFromSdlFd();
drmSetMaster(fd);
err = ((typeof(drmModeAtomicCommit)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, req, flags, user_data);
drmDropMaster(fd);
if (oldMasterFd != -1) {
drmSetMaster(oldMasterFd);
}
}
return err;
} }
// This hook will handle SDL's open() on the DRM device. We just need to // This hook will handle SDL's open() on the DRM device. We just need to

View File

@ -51,6 +51,7 @@ int getSdlFdEntryIndex(bool unused)
return -1; return -1;
} }
// Returns true if the final SDL FD was removed
bool removeSdlFd(int fd) bool removeSdlFd(int fd)
{ {
SDL_AtomicLock(&g_FdTableLock); SDL_AtomicLock(&g_FdTableLock);
@ -73,6 +74,28 @@ bool removeSdlFd(int fd)
return false; return false;
} }
// Returns the previous master FD or -1 if none
int takeMasterFromSdlFd()
{
int fd = -1;
// Since all SDL FDs are actually dups of each other
// we can take master from any one of them.
SDL_AtomicLock(&g_FdTableLock);
int fdIndex = getSdlFdEntryIndex(false);
if (fdIndex != -1) {
fd = g_SdlDrmMasterFds[fdIndex];
}
SDL_AtomicUnlock(&g_FdTableLock);
if (fd >= 0 && drmDropMaster(fd) == 0) {
return fd;
}
else {
return -1;
}
}
int openHook(const char *funcname, const char *pathname, int flags, va_list va) int openHook(const char *funcname, const char *pathname, int flags, va_list va)
{ {
int fd; int fd;