Fixed bug 3902 - Add a specific KMSDRM hint for low latency video
authorBrandon Schaefer <brandon.schaefer@canonical.com>
Thu, 26 Oct 2017 16:37:20 -0700
changeset 11658fbfdee28682d
parent 11657 26ce9cdde7f4
child 11659 b2fd0f264cd3
Fixed bug 3902 - Add a specific KMSDRM hint for low latency video
include/SDL_hints.h
src/video/kmsdrm/SDL_kmsdrmopengles.c
src/video/kmsdrm/SDL_kmsdrmvideo.c
src/video/kmsdrm/SDL_kmsdrmvideo.h
     1.1 --- a/include/SDL_hints.h	Thu Oct 26 10:49:33 2017 -0700
     1.2 +++ b/include/SDL_hints.h	Thu Oct 26 16:37:20 2017 -0700
     1.3 @@ -798,6 +798,16 @@
     1.4  #define SDL_HINT_RPI_VIDEO_LAYER           "SDL_RPI_VIDEO_LAYER"
     1.5  
     1.6  /**
     1.7 + * \brief Tell SDL the KMS/DRM video driver that we want double buffer only.
     1.8 + *
     1.9 + * By default KMS/DRM will use a triple buffer solution that wastes no CPU
    1.10 + * time on waiting for vsync after issuing a flip, but introduces a frame of
    1.11 + * latency. Waiting for vsync immediately after issuing a flip on the other
    1.12 + * hand is recommended for cases where low latency is an important factor.
    1.13 + */
    1.14 +#define SDL_HINT_KMSDRM_DOUBLE_BUFFER      "SDL_KMSDRM_DOUBLE_BUFFER"
    1.15 +
    1.16 +/**
    1.17   *  \brief  A variable controlling what driver to use for OpenGL ES contexts.
    1.18   *
    1.19   *  On some platforms, currently Windows and X11, OpenGL drivers may support
     2.1 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c	Thu Oct 26 10:49:33 2017 -0700
     2.2 +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c	Thu Oct 26 16:37:20 2017 -0700
     2.3 @@ -71,7 +71,7 @@
     2.4         return SDL_FALSE;
     2.5  
     2.6      }
     2.7 -    
     2.8 +
     2.9      wdata->crtc_ready = SDL_TRUE;
    2.10      return SDL_TRUE;
    2.11  }
    2.12 @@ -159,7 +159,7 @@
    2.13              if(!KMSDRM_GLES_SetupCrtc(_this, window)) {
    2.14                  SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips");
    2.15                  return 0;
    2.16 -            } 
    2.17 +            }
    2.18  	}
    2.19  
    2.20          /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)",
    2.21 @@ -171,6 +171,12 @@
    2.22          } else {
    2.23              SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
    2.24          }
    2.25 +
    2.26 +        /* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
    2.27 +           Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>" to enable this. */
    2.28 +        if (wdata->double_buffer) {
    2.29 +            KMSDRM_WaitPageFlip(_this, wdata, -1);
    2.30 +        }
    2.31      }
    2.32  
    2.33      return 0;
     3.1 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c	Thu Oct 26 10:49:33 2017 -0700
     3.2 +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c	Thu Oct 26 16:37:20 2017 -0700
     3.3 @@ -27,6 +27,7 @@
     3.4  #include "../SDL_sysvideo.h"
     3.5  #include "SDL_syswm.h"
     3.6  #include "SDL_log.h"
     3.7 +#include "SDL_hints.h"
     3.8  #include "../../events/SDL_mouse_c.h"
     3.9  #include "../../events/SDL_keyboard_c.h"
    3.10  
    3.11 @@ -522,11 +523,17 @@
    3.12      }
    3.13  #endif /* SDL_VIDEO_OPENGL_EGL */
    3.14  
    3.15 +    /* In case we want low-latency, double-buffer video, we take note here */
    3.16 +    wdata->double_buffer = SDL_FALSE;
    3.17 +    if (SDL_GetHintBoolean(SDL_HINT_KMSDRM_DOUBLE_BUFFER, SDL_FALSE)) {
    3.18 +        wdata->double_buffer = SDL_TRUE;
    3.19 +    }
    3.20 +
    3.21      /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want
    3.22         drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
    3.23 -       need to do eglSwapBuffers so we can get a valid GBM buffer object to call 
    3.24 +       need to do eglSwapBuffers so we can get a valid GBM buffer object to call
    3.25         drmModeSetCrtc on it. */
    3.26 -    wdata->crtc_ready = SDL_FALSE;    
    3.27 +    wdata->crtc_ready = SDL_FALSE;
    3.28  
    3.29      /* Setup driver data for this window */
    3.30      window->driverdata = wdata;
     4.1 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h	Thu Oct 26 10:49:33 2017 -0700
     4.2 +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h	Thu Oct 26 16:37:20 2017 -0700
     4.3 @@ -63,6 +63,7 @@
     4.4      struct gbm_bo *next_bo;
     4.5      SDL_bool waiting_for_flip;
     4.6      SDL_bool crtc_ready;
     4.7 +    SDL_bool double_buffer;
     4.8  #if SDL_VIDEO_OPENGL_EGL
     4.9      EGLSurface egl_surface;
    4.10  #endif