浏览代码

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

Manuel Alfayate Corchete 5 年之前
父节点
当前提交
b6a818b6a2
共有 3 个文件被更改,包括 18 次插入12 次删除
  1. 4 7
      src/video/kmsdrm/SDL_kmsdrmopengles.c
  2. 12 4
      src/video/kmsdrm/SDL_kmsdrmvideo.c
  3. 2 1
      src/video/kmsdrm/SDL_kmsdrmvideo.h

+ 4 - 7
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_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
     SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
     SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
     KMSDRM_FBInfo *fb_info;
     KMSDRM_FBInfo *fb_info;
-    SDL_bool crtc_setup_pending = SDL_FALSE;
 
 
     /* ALWAYS wait for each pageflip to complete before issuing another, vsync or not,
     /* ALWAYS wait for each pageflip to complete before issuing another, vsync or not,
        or drmModePageFlip() will start returning EBUSY if there are pending pageflips.
        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 */
     /* Recreate the GBM / EGL surfaces if the display mode has changed */
     if (windata->egl_surface_dirty) {
     if (windata->egl_surface_dirty) {
         KMSDRM_CreateSurfaces(_this, window);
         KMSDRM_CreateSurfaces(_this, window);
-        /* Do this later, when a fb_id is obtained. */
-        crtc_setup_pending = SDL_TRUE;
     }
     }
 
 
     if (windata->double_buffer) {
     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. */
         /* 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,
 	    if (KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
 					0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
 					0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
 		SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC on video mode setting.");
 		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,
         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. */
         /* 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,
 	    if (KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
 					0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
 					0, &dispdata->conn->connector_id, 1, &dispdata->mode)) {
 		SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC on video mode setting.");
 		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;
         }
         }
 
 
 
 

+ 12 - 4
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);
     SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
 
 
-    windata->egl_surface_dirty = 0;
+    windata->egl_surface_dirty = SDL_FALSE;
 #endif
 #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;
     return 0;
 }
 }
 
 
@@ -757,7 +761,7 @@ KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 #if SDL_VIDEO_OPENGL_EGL
 #if SDL_VIDEO_OPENGL_EGL
         /* Can't recreate EGL surfaces right now, need to wait until SwapWindow
         /* Can't recreate EGL surfaces right now, need to wait until SwapWindow
            so the correct thread-local surface and context state are available */
            so the correct thread-local surface and context state are available */
-        windata->egl_surface_dirty = 1;
+        windata->egl_surface_dirty = SDL_TRUE;
 #else
 #else
         if (KMSDRM_CreateSurfaces(_this, window)) {
         if (KMSDRM_CreateSurfaces(_this, window)) {
             return -1;
             return -1;
@@ -793,9 +797,13 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
         goto error;
         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)) {
     if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
         windata->double_buffer = SDL_TRUE;
         windata->double_buffer = SDL_TRUE;
     }
     }

+ 2 - 1
src/video/kmsdrm/SDL_kmsdrmvideo.h

@@ -71,8 +71,9 @@ typedef struct SDL_WindowData
     struct gbm_bo *crtc_bo;
     struct gbm_bo *crtc_bo;
     SDL_bool waiting_for_flip;
     SDL_bool waiting_for_flip;
     SDL_bool double_buffer;
     SDL_bool double_buffer;
+    SDL_bool crtc_setup_pending;
 #if SDL_VIDEO_OPENGL_EGL
 #if SDL_VIDEO_OPENGL_EGL
-    int egl_surface_dirty;
+    SDL_bool egl_surface_dirty;
     EGLSurface egl_surface;
     EGLSurface egl_surface;
 #endif
 #endif
 } SDL_WindowData;
 } SDL_WindowData;