From 5a296e25895d0d57eabc1c71dae17274494c1b43 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Tue, 8 Jun 2021 20:48:24 -0400 Subject: [PATCH] kmsdrm: avoid overriding the mode requested by SDL_SetWindowDisplayMode when recreating surfaces --- src/video/kmsdrm/SDL_kmsdrmvideo.c | 102 ++++++++++------------------- src/video/kmsdrm/SDL_kmsdrmvideo.h | 2 +- 2 files changed, 35 insertions(+), 69 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 5059df71f..094558dfe 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -639,9 +639,8 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource which is the mode currently setup on the CRTC we found for the active connector. */ dispdata->mode = crtc->mode; - - /* Save the original mode for restoration on quit. */ - dispdata->original_mode = dispdata->mode; + dispdata->original_mode = crtc->mode; + dispdata->fullscreen_mode = crtc->mode; if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) { ret = SDL_SetError("Couldn't get a valid connector videomode."); @@ -900,6 +899,27 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window) } } +static void +KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + if ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) { + *out_mode = dispdata->fullscreen_mode; + } else { + drmModeModeInfo *mode; + + mode = KMSDRM_GetClosestDisplayMode(display, + window->windowed.w, window->windowed.h, 0); + + if (mode) { + *out_mode = *mode; + } else { + *out_mode = dispdata->original_mode; + } + } +} + /* This determines the size of the fb, which comes from the GBM surface that we create here. */ int @@ -916,9 +936,7 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window) int ret = 0; - /* If the current window already has surfaces, destroy them before creating other. - This is mainly for ReconfigureWindow(), where we simply call CreateSurfaces() - for regenerating a window's surfaces. */ + /* If the current window already has surfaces, destroy them before creating other. */ if (windata->gs) { KMSDRM_DestroySurfaces(_this, window); } @@ -929,6 +947,8 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window) "GBM surface format not supported. Trying anyway."); } + KMSDRM_GetModeToSet(window, &dispdata->mode); + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, dispdata->mode.hdisplay, dispdata->mode.vdisplay, surface_fmt, surface_flags); @@ -953,6 +973,9 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window) egl_context = (EGLContext)SDL_GL_GetCurrentContext(); ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + dispdata->mode.hdisplay, dispdata->mode.vdisplay); + windata->egl_surface_dirty = SDL_FALSE; cleanup: @@ -1072,7 +1095,7 @@ KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) /* Take note of the new mode to be set, and leave the CRTC modeset pending so it's done in SwapWindow. */ - dispdata->mode = conn->modes[modedata->mode_index]; + dispdata->fullscreen_mode = conn->modes[modedata->mode_index]; for (i = 0; i < viddata->num_windows; i++) { SDL_Window *window = viddata->windows[i]; @@ -1245,14 +1268,13 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) are considered "windowed" at this point of their life. If a window is fullscreen, SDL internals will call KMSDRM_SetWindowFullscreen() to reconfigure it if necessary. */ - mode = KMSDRM_GetClosestDisplayMode(display, window->windowed.w, window->windowed.h, 0 ); if (mode) { - dispdata->mode = *mode; + dispdata->fullscreen_mode = *mode; } else { - dispdata->mode = dispdata->original_mode; + dispdata->fullscreen_mode = dispdata->original_mode; } /* Create the window surfaces with the size we have just chosen. @@ -1260,12 +1282,6 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) if ((ret = KMSDRM_CreateSurfaces(_this, window))) { return (SDL_SetError("Can't window GBM/EGL surfaces on window creation.")); } - - /* Tell app about the size we have determined for the window, - so SDL pre-scales to that size for us. */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, - dispdata->mode.hdisplay, dispdata->mode.vdisplay); - } /* NON-Vulkan block ends. */ /* Add window to the internal list of tracked windows. Note, while it may @@ -1301,56 +1317,6 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) return ret; } -/*****************************************************************************/ -/* Re-create a window surfaces without destroying the window itself, */ -/* and set a videomode on the CRTC that matches the surfaces size. */ -/* To be used by SetWindowSize() and SetWindowFullscreen(). */ -/*****************************************************************************/ -void -KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window) -{ - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - SDL_DisplayData *dispdata = display->driverdata; - - if ((window->flags & SDL_WINDOW_FULLSCREEN) == - SDL_WINDOW_FULLSCREEN) - { - /* Nothing to do, honor the most recent mode requested by the user */ - } - else if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == - SDL_WINDOW_FULLSCREEN_DESKTOP) - { - /* Update the current mode to the desktop mode. */ - dispdata->mode = dispdata->original_mode; - } else { - drmModeModeInfo *mode; - - /* Try to find a valid video mode matching the size of the window. */ - mode = KMSDRM_GetClosestDisplayMode(display, - window->windowed.w, window->windowed.h, 0); - - if (mode) { - /* If matching mode found, recreate the GBM surface with the size - of that mode and configure it on the CRTC. */ - dispdata->mode = *mode; - } else { - /* If not matching mode found, recreate the GBM surfaces with the - size of the mode that was originally configured on the CRTC, - and setup that mode on the CRTC. */ - dispdata->mode = dispdata->original_mode; - } - } - - /* Recreate the GBM (and EGL) surfaces, and mark the CRTC mode/fb setting - as pending so it's done on SwapWindow. */ - KMSDRM_CreateSurfaces(_this, window); - - /* Tell app about the size we have determined for the window, - so SDL pre-scales to that size for us. */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, - dispdata->mode.hdisplay, dispdata->mode.vdisplay); -} - int KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { @@ -1410,7 +1376,7 @@ KMSDRM_SetWindowSize(_THIS, SDL_Window * window) { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); if (!viddata->vulkan_mode) { - KMSDRM_ReconfigureWindow(_this, window); + KMSDRM_CreateSurfaces(_this, window); } } void @@ -1419,7 +1385,7 @@ KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * displa { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); if (!viddata->vulkan_mode) { - KMSDRM_ReconfigureWindow(_this, window); + KMSDRM_CreateSurfaces(_this, window); } } void diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index c82a849df..b172eb90f 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -68,7 +68,7 @@ typedef struct SDL_DisplayData drmModeCrtc *crtc; drmModeModeInfo mode; drmModeModeInfo original_mode; - drmModeModeInfo next_mode; /* New mode to be set on the CRTC. */ + drmModeModeInfo fullscreen_mode; drmModeCrtc *saved_crtc; /* CRTC to restore on quit */