Fix SDL_Window recreation: drmModeSetCrtc() has to be called everytime the EGL and GBM surfaces are recreated.

This commit is contained in:
Manuel Alfayate Corchete 2020-07-19 18:45:29 +02:00
parent 71e9df99c7
commit b6a818b6a2
3 changed files with 18 additions and 12 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;