Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kmsdrm: Keep fd around if we can drop master #10915

Merged
merged 1 commit into from
Sep 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/video/kmsdrm/SDL_kmsdrmvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display,
/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */
static void KMSDRM_DeinitDisplays(_THIS)
{

SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_DisplayData *dispdata;
int num_displays, i;

Expand All @@ -557,6 +557,11 @@ static void KMSDRM_DeinitDisplays(_THIS)
dispdata->crtc = NULL;
}
}

if (viddata->drm_fd >= 0) {
close(viddata->drm_fd);
viddata->drm_fd = -1;
}
}

static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd,
Expand Down Expand Up @@ -912,8 +917,6 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re

/* Initializes the list of SDL displays: we build a new display for each
connecter connector we find.
Inoffeensive for VK compatibility, except we must leave the drm_fd
closed when we get to the end of this function.
This is to be called early, in VideoInit(), because it gets us
the videomode information, which SDL needs immediately after VideoInit(). */
static int KMSDRM_InitDisplays(_THIS)
Expand Down Expand Up @@ -986,10 +989,13 @@ static int KMSDRM_InitDisplays(_THIS)
/* Block for Vulkan compatibility. */
/***********************************/

/* THIS IS FOR VULKAN! Leave the FD closed, so VK can work.
Will reopen this in CreateWindow, but only if requested a non-VK window. */
close(viddata->drm_fd);
viddata->drm_fd = -1;
/* Vulkan requires DRM master on its own FD to work, so try to drop master
on our FD. This will only work without root on kernels v5.8 and later.
If it doesn't work, just close the FD and we'll reopen it later. */
if (KMSDRM_drmDropMaster(viddata->drm_fd) < 0) {
close(viddata->drm_fd);
viddata->drm_fd = -1;
}

cleanup:
if (resources) {
Expand Down Expand Up @@ -1017,10 +1023,15 @@ static int KMSDRM_GBMInit(_THIS, SDL_DisplayData *dispdata)
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
int ret = 0;

/* Reopen the FD! */
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
/* Reopen the FD if we weren't able to drop master on the original one */
if (viddata->drm_fd < 0) {
viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC);
if (viddata->drm_fd < 0) {
return SDL_SetError("Could not reopen %s", viddata->devpath);
}
}

/* Set the FD we just opened as current DRM master. */
/* Set the FD as current DRM master. */
KMSDRM_drmSetMaster(viddata->drm_fd);

/* Create the GBM device. */
Expand Down
Loading