From b6a818b6a286c5ec7a1b695c56e38a5a6bbde4ca Mon Sep 17 00:00:00 2001 From: Manuel Alfayate Corchete Date: Sun, 19 Jul 2020 18:45:29 +0200 Subject: [PATCH] Fix SDL_Window recreation: drmModeSetCrtc() has to be called everytime the EGL and GBM surfaces are recreated. --- src/video/kmsdrm/SDL_kmsdrmopengles.c | 11 ++++------- src/video/kmsdrm/SDL_kmsdrmvideo.c | 16 ++++++++++++---- src/video/kmsdrm/SDL_kmsdrmvideo.h | 3 ++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index 355d57bfd..dcc8d4763 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -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. @@ -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) { @@ -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, @@ -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; } diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 387d95e5c..02092aa16 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -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; } @@ -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; @@ -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; } diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index 63dcf6ffd..df6133e31 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -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;