Skip to content

Commit

Permalink
Fix SDL_Window recreation: drmModeSetCrtc() has to be called everytim…
Browse files Browse the repository at this point in the history
…e the EGL and GBM surfaces are recreated.
  • Loading branch information
vanfanel committed Jul 19, 2020
1 parent 71e9df9 commit b6a818b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
11 changes: 4 additions & 7 deletions src/video/kmsdrm/SDL_kmsdrmopengles.c
Expand Up @@ -61,7 +61,6 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
KMSDRM_FBInfo *fb_info;
SDL_bool crtc_setup_pending = SDL_FALSE;

/* ALWAYS wait for each pageflip to complete before issuing another, vsync or not,
or drmModePageFlip() will start returning EBUSY if there are pending pageflips.
Expand All @@ -79,8 +78,6 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
/* Recreate the GBM / EGL surfaces if the display mode has changed */
if (windata->egl_surface_dirty) {
KMSDRM_CreateSurfaces(_this, window);
/* Do this later, when a fb_id is obtained. */
crtc_setup_pending = SDL_TRUE;
}

if (windata->double_buffer) {
Expand Down Expand Up @@ -121,12 +118,12 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
}

/* When needed, this is done once we have the needed fb_id, not before. */
if (crtc_setup_pending) {
if (windata->crtc_setup_pending) {
if (KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC on video mode setting.");
}
crtc_setup_pending = SDL_FALSE;
windata->crtc_setup_pending = SDL_FALSE;
}

if (!KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id,
Expand Down Expand Up @@ -210,12 +207,12 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
}

/* When needed, this is done once we have the needed fb_id, not before. */
if (crtc_setup_pending) {
if (windata->crtc_setup_pending) {
if (KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC on video mode setting.");
}
crtc_setup_pending = SDL_FALSE;
windata->crtc_setup_pending = SDL_FALSE;
}


Expand Down
16 changes: 12 additions & 4 deletions src/video/kmsdrm/SDL_kmsdrmvideo.c
Expand Up @@ -433,9 +433,13 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)

SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);

windata->egl_surface_dirty = 0;
windata->egl_surface_dirty = SDL_FALSE;
#endif

/* We can't call KMSDRM_SetCRTC() until we have a fb_id, in KMSDRM_GLES_SwapWindow().
So we take note here to do it there. */
windata->crtc_setup_pending = SDL_TRUE;

return 0;
}

Expand Down Expand Up @@ -757,7 +761,7 @@ KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
#if SDL_VIDEO_OPENGL_EGL
/* Can't recreate EGL surfaces right now, need to wait until SwapWindow
so the correct thread-local surface and context state are available */
windata->egl_surface_dirty = 1;
windata->egl_surface_dirty = SDL_TRUE;
#else
if (KMSDRM_CreateSurfaces(_this, window)) {
return -1;
Expand Down Expand Up @@ -793,9 +797,13 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
goto error;
}

/* In case low-latency is wanted, double-buffered video will be used. We take note here */
windata->double_buffer = SDL_FALSE;
/* Init windata fields. */
windata->waiting_for_flip = SDL_FALSE;
windata->double_buffer = SDL_FALSE;
windata->crtc_setup_pending = SDL_FALSE;
windata->egl_surface_dirty = SDL_FALSE;

/* In case low-latency is wanted, double-buffered video will be used. We take note here */
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
windata->double_buffer = SDL_TRUE;
}
Expand Down
3 changes: 2 additions & 1 deletion src/video/kmsdrm/SDL_kmsdrmvideo.h
Expand Up @@ -71,8 +71,9 @@ typedef struct SDL_WindowData
struct gbm_bo *crtc_bo;
SDL_bool waiting_for_flip;
SDL_bool double_buffer;
SDL_bool crtc_setup_pending;
#if SDL_VIDEO_OPENGL_EGL
int egl_surface_dirty;
SDL_bool egl_surface_dirty;
EGLSurface egl_surface;
#endif
} SDL_WindowData;
Expand Down

0 comments on commit b6a818b

Please sign in to comment.