From 0e2d5bf4417d7c87b0e8ad76246bf105ad0c571f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 23 Sep 2024 21:32:09 -0500 Subject: [PATCH] Fix EGLFS state restoration after Vulkan rendering --- app/masterhook.c | 35 +++++++++++++++++++++++++++++++++-- app/masterhook_internal.c | 12 +++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/masterhook.c b/app/masterhook.c index eff42fb2..5ea02c82 100644 --- a/app/masterhook.c +++ b/app/masterhook.c @@ -36,8 +36,12 @@ int g_QtDrmMasterFd = -1; struct stat g_DrmMasterStat; +// Last CRTC state for us to restore later +drmModeCrtcPtr g_QtCrtcState; +uint32_t* g_QtCrtcConnectors; +int g_QtCrtcConnectorCount; + bool removeSdlFd(int fd); -bool createSdlFd(); int drmIsMaster(int fd) { @@ -62,7 +66,16 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, } // Call into the real thing - return ((typeof(drmModeSetCrtc)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, crtcId, bufferId, x, y, connectors, count, mode); + int err = ((typeof(drmModeSetCrtc)*)dlsym(RTLD_NEXT, __FUNCTION__))(fd, crtcId, bufferId, x, y, connectors, count, mode); + if (err == 0 && fd == g_QtDrmMasterFd) { + // Store the CRTC configuration so we can restore it later + drmModeFreeCrtc(g_QtCrtcState); + g_QtCrtcState = drmModeGetCrtc(fd, crtcId); + g_QtCrtcConnectors = calloc(count, sizeof(*g_QtCrtcConnectors)); + memcpy(g_QtCrtcConnectors, connectors, count * sizeof(*connectors)); + g_QtCrtcConnectorCount = count; + } + return err; } // This hook will handle atomic DRM rendering @@ -124,6 +137,24 @@ int close(int fd) "Failed to restore master to Qt DRM FD: %d", errno); } + + // Reset the CRTC state to how Qt configured it + if (g_QtCrtcState) { + int err = ((typeof(drmModeSetCrtc)*)dlsym(RTLD_NEXT, "drmModeSetCrtc"))(g_QtDrmMasterFd, + g_QtCrtcState->crtc_id, + g_QtCrtcState->buffer_id, + g_QtCrtcState->x, + g_QtCrtcState->y, + g_QtCrtcConnectors, + g_QtCrtcConnectorCount, + g_QtCrtcState->mode_valid ? + &g_QtCrtcState->mode : NULL); + if (err < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Failed to restore CRTC state to Qt DRM FD: %d", + errno); + } + } } return ret; diff --git a/app/masterhook_internal.c b/app/masterhook_internal.c index 60e81490..0a177a31 100644 --- a/app/masterhook_internal.c +++ b/app/masterhook_internal.c @@ -149,9 +149,15 @@ int openHook(const char *funcname, const char *pathname, int flags, va_list va) } } - // Insert the FD into the table - g_SdlDrmMasterFds[freeFdIndex] = fd; - g_SdlDrmMasterFdCount++; + if (fd >= 0) { + // Start with DRM master on the new FD + drmSetMaster(fd); + + // Insert the FD into the table + g_SdlDrmMasterFds[freeFdIndex] = fd; + g_SdlDrmMasterFdCount++; + } + SDL_AtomicUnlock(&g_FdTableLock); } }