From 3c6004feb79b2b24c6ace7809b2f205d79c64c7e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 10 Sep 2020 15:07:23 -0400 Subject: [PATCH] kmsdrm: Choose how to swap buffers based on EGL extension availability. --- src/video/kmsdrm/SDL_kmsdrmopengles.c | 60 +++++++++++++++------------ src/video/kmsdrm/SDL_kmsdrmopengles.h | 1 - src/video/kmsdrm/SDL_kmsdrmvideo.c | 13 +----- src/video/kmsdrm/SDL_kmsdrmvideo.h | 2 + 4 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index af55f506d..5eaa11bc3 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -27,6 +27,7 @@ #include "SDL_kmsdrmvideo.h" #include "SDL_kmsdrmopengles.h" #include "SDL_kmsdrmdyn.h" +#include "SDL_hints.h" #ifndef EGL_PLATFORM_GBM_MESA #define EGL_PLATFORM_GBM_MESA 0x31D7 @@ -99,30 +100,18 @@ static EGLSyncKHR create_fence(int fd, _THIS) return fence; } -int -KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) +static int +KMSDRM_GLES_SwapWindowFenced(_THIS, SDL_Window * window) { SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; KMSDRM_FBInfo *fb; KMSDRM_PlaneInfo info = {0}; - /* Get the EGL context, now that SDL_CreateRenderer() has already been called, - and call eglMakeCurrent() on it and the EGL surface. */ -#if SDL_VIDEO_OPENGL_EGL - if (windata->egl_context_pending) { - EGLContext egl_context; - egl_context = (EGLContext)SDL_GL_GetCurrentContext(); - SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); - windata->egl_context_pending = SDL_FALSE; - } -#endif - /*************************************************************************/ /* Block for telling KMS to wait for GPU rendering of the current frame */ /* before applying the KMS changes requested in the atomic ioctl. */ /*************************************************************************/ - /* Create the fence that will be inserted in the cmdstream exactly at the end of the gl commands that form a frame. KMS will have to wait on it before doing a pageflip. */ dispdata->gpu_fence = create_fence(EGL_NO_NATIVE_FENCE_FD_ANDROID, _this); @@ -222,25 +211,14 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) return 0; } -int -KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window) +static int +KMSDRM_GLES_SwapWindowDoubleBuffered(_THIS, SDL_Window * window) { SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; KMSDRM_FBInfo *fb; KMSDRM_PlaneInfo info = {0}; - /* Get the EGL context, now that SDL_CreateRenderer() has already been called, - and call eglMakeCurrent() on it and the EGL surface. */ -#if SDL_VIDEO_OPENGL_EGL - if (windata->egl_context_pending) { - EGLContext egl_context; - egl_context = (EGLContext)SDL_GL_GetCurrentContext(); - SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); - windata->egl_context_pending = SDL_FALSE; - } -#endif - /****************************************************************************************************/ /* In double-buffer mode, atomic commit will always be synchronous/blocking (ie: won't return until */ /* the requested changes are really done). */ @@ -306,6 +284,34 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window) return 0; } +int +KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata); + + /* Get the EGL context, now that SDL_CreateRenderer() has already been called, + and call eglMakeCurrent() on it and the EGL surface. */ +#if SDL_VIDEO_OPENGL_EGL + if (windata->egl_context_pending) { + EGLContext egl_context = (EGLContext)SDL_GL_GetCurrentContext(); + SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); + windata->egl_context_pending = SDL_FALSE; + } +#endif + + if (windata->swap_window == NULL) { + /* We want the fenced version by default, but it needs extensions. */ + if ( (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) || + (!SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_ANDROID_native_fence_sync")) ) { + windata->swap_window = KMSDRM_GLES_SwapWindowDoubleBuffered; + } else { + windata->swap_window = KMSDRM_GLES_SwapWindowFenced; + } + } + + return windata->swap_window(_this, window); +} + /***************************************/ /* End of Atomic functions block */ diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.h b/src/video/kmsdrm/SDL_kmsdrmopengles.h index 0d944ee65..2718f96c6 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.h +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.h @@ -41,7 +41,6 @@ extern int KMSDRM_GLES_SetSwapInterval(_THIS, int interval); extern int KMSDRM_GLES_LoadLibrary(_THIS, const char *path); extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window); extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window); extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); #endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 9c059278e..0fe093b60 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -27,7 +27,6 @@ /* SDL internals */ #include "../SDL_sysvideo.h" #include "SDL_syswm.h" -#include "SDL_hints.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" @@ -50,7 +49,6 @@ #define KMSDRM_DRI_PATH "/dev/dri/" #define AMDGPU_COMPAT 1 -#define RPI4_COMPAT 0 static int check_modesetting(int devindex) @@ -792,16 +790,7 @@ KMSDRM_CreateDevice(int devindex) device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent; device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval; device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval; - -#if RPI4_COMPAT - device->GL_SwapWindow = KMSDRM_GLES_SwapWindowDB; -#else - if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) - device->GL_SwapWindow = KMSDRM_GLES_SwapWindowDB; - else - device->GL_SwapWindow = KMSDRM_GLES_SwapWindow; -#endif - + device->GL_SwapWindow = KMSDRM_GLES_SwapWindow; device->GL_DeleteContext = KMSDRM_GLES_DeleteContext; #endif device->PumpEvents = KMSDRM_PumpEvents; diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index 535ee6e15..8a367789d 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -171,6 +171,8 @@ typedef struct SDL_WindowData the EGL context is available, but we need the EGL surface sooner. */ SDL_bool egl_context_pending; + /* This dictates what approach we'll use for SwapBuffers. */ + int (*swap_window)(_THIS, SDL_Window * window); } SDL_WindowData; typedef struct SDL_DisplayModeData