kmsdrm: Choose how to swap buffers based on EGL extension availability.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c
index af55f50..5eaa11b 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 0d944ee..2718f96 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 9c05927..0fe093b 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 535ee6e..8a36778 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