Browse Source

[KMS/DRM] Go back to the LEGACY interface only because using planes breaks compatibility with HW, so no advantage on using ATOMIC.

Manuel Alfayate Corchete 4 years ago
parent
commit
b24494734b

+ 1 - 2
cmake/sdlchecks.cmake

@@ -1182,8 +1182,7 @@ macro(CheckKMSDRM)
       set(HAVE_SDL_VIDEO TRUE)
       set(HAVE_SDL_VIDEO TRUE)
 
 
       file(GLOB KMSDRM_SOURCES ${SDL2_SOURCE_DIR}/src/video/kmsdrm/*.c)
       file(GLOB KMSDRM_SOURCES ${SDL2_SOURCE_DIR}/src/video/kmsdrm/*.c)
-      file(GLOB KMSDRM_LEGACY_SOURCES ${SDL2_SOURCE_DIR}/src/video/kmsdrm_legacy/*.c)
-      set(SOURCE_FILES ${SOURCE_FILES} ${KMSDRM_SOURCES} ${KMSDRM_LEGACY_SOURCES})
+      set(SOURCE_FILES ${SOURCE_FILES} ${KMSDRM_SOURCES})
 
 
       list(APPEND EXTRA_CFLAGS ${KMSDRM_CFLAGS})
       list(APPEND EXTRA_CFLAGS ${KMSDRM_CFLAGS})
 
 

+ 0 - 1
configure.ac

@@ -2252,7 +2252,6 @@ AS_HELP_STRING([--enable-kmsdrm-shared], [dynamically load kmsdrm support [[defa
 
 
             AC_DEFINE(SDL_VIDEO_DRIVER_KMSDRM, 1, [ ])
             AC_DEFINE(SDL_VIDEO_DRIVER_KMSDRM, 1, [ ])
             SOURCES="$SOURCES $srcdir/src/video/kmsdrm/*.c"
             SOURCES="$SOURCES $srcdir/src/video/kmsdrm/*.c"
-            SOURCES="$SOURCES $srcdir/src/video/kmsdrm_legacy/*.c"
             EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBDRM_CFLAGS $LIBGBM_CFLAGS"
             EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBDRM_CFLAGS $LIBGBM_CFLAGS"
 
 
             AC_MSG_CHECKING(for kmsdrm dynamic loading support)
             AC_MSG_CHECKING(for kmsdrm dynamic loading support)

+ 0 - 1
src/video/SDL_video.c

@@ -96,7 +96,6 @@ static VideoBootStrap *bootstrap[] = {
 #endif
 #endif
 #if SDL_VIDEO_DRIVER_KMSDRM
 #if SDL_VIDEO_DRIVER_KMSDRM
     &KMSDRM_bootstrap,
     &KMSDRM_bootstrap,
-    &KMSDRM_LEGACY_bootstrap,
 #endif
 #endif
 #if SDL_VIDEO_DRIVER_RPI
 #if SDL_VIDEO_DRIVER_RPI
     &RPI_bootstrap,
     &RPI_bootstrap,

+ 0 - 2
src/video/kmsdrm/SDL_kmsdrmdyn.c

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -28,7 +27,6 @@
 
 
 #include "SDL_kmsdrmdyn.h"
 #include "SDL_kmsdrmdyn.h"
 
 
-
 #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
 #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
 
 
 #include "SDL_name.h"
 #include "SDL_name.h"

+ 0 - 1
src/video/kmsdrm/SDL_kmsdrmdyn.h

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages

+ 0 - 1
src/video/kmsdrm/SDL_kmsdrmevents.c

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages

+ 0 - 1
src/video/kmsdrm/SDL_kmsdrmevents.h

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages

+ 68 - 129
src/video/kmsdrm/SDL_kmsdrmmouse.c

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -27,7 +26,6 @@
 #include "SDL_kmsdrmvideo.h"
 #include "SDL_kmsdrmvideo.h"
 #include "SDL_kmsdrmmouse.h"
 #include "SDL_kmsdrmmouse.h"
 #include "SDL_kmsdrmdyn.h"
 #include "SDL_kmsdrmdyn.h"
-#include "SDL_assert.h"
 
 
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/default_cursor.h"
 #include "../../events/default_cursor.h"
@@ -55,40 +53,18 @@ static int KMSDRM_WarpMouseGlobal(int x, int y);
 /*  and mouse->cursor_shown is 1.                                                     */
 /*  and mouse->cursor_shown is 1.                                                     */
 /**************************************************************************************/
 /**************************************************************************************/
 
 
-/**********************************/
-/* Atomic helper functions block. */
-/**********************************/
-
-int
-drm_atomic_movecursor(KMSDRM_CursorData *curdata, uint16_t x, uint16_t y)
+static SDL_Cursor *
+KMSDRM_CreateDefaultCursor(void)
 {
 {
-    SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
-
-    if (!dispdata->cursor_plane) /* We can't move a non-existing cursor, but that's ok. */
-        return 0;
-
-    /* Do we have a set of changes already in the making? If not, allocate a new one. */
-    if (!dispdata->atomic_req)
-        dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc();
-    
-    add_plane_property(dispdata->atomic_req,
-            dispdata->cursor_plane, "CRTC_X", x - curdata->hot_x);
-    add_plane_property(dispdata->atomic_req,
-            dispdata->cursor_plane, "CRTC_Y", y - curdata->hot_y);
-
-    return 0;
+    return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
 }
 }
 
 
-/***************************************/
-/* Atomic helper functions block ends. */
-/***************************************/
-
 /* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has,
 /* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has,
    to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB].
    to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB].
    These multiplications have to be done with floats instead of uint32_t's,
    These multiplications have to be done with floats instead of uint32_t's,
    and the resulting values have to be converted to be relative to the 0-255 interval,
    and the resulting values have to be converted to be relative to the 0-255 interval,
    where 255 is 1.00 and anything between 0 and 255 is 0.xx. */
    where 255 is 1.00 and anything between 0 and 255 is 0.xx. */
-void alpha_premultiply_ARGB8888 (uint32_t *pixel) {
+void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
 
 
     uint32_t A, R, G, B;
     uint32_t A, R, G, B;
 
 
@@ -107,15 +83,9 @@ void alpha_premultiply_ARGB8888 (uint32_t *pixel) {
     (*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
     (*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
 }
 }
 
 
-static SDL_Cursor *
-KMSDRM_CreateDefaultCursor(void)
-{
-    return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
-}
-
-/* This simply gets the cursor soft-buffer ready. We don't copy it to a GBO BO
-   until ShowCursor() because the cusor GBM BO (living in dispata) is destroyed
-   and recreated when we recreate windows, etc. */
+/* This simply gets the cursor soft-buffer ready.
+   We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living
+   in dispata) is destroyed and recreated when we recreate windows, etc. */
 static SDL_Cursor *
 static SDL_Cursor *
 KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
 KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
 {
 {
@@ -225,13 +195,12 @@ static int
 KMSDRM_ShowCursor(SDL_Cursor * cursor)
 KMSDRM_ShowCursor(SDL_Cursor * cursor)
 {
 {
     SDL_VideoDevice *video_device = SDL_GetVideoDevice();
     SDL_VideoDevice *video_device = SDL_GetVideoDevice();
-    //SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
+    SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
     SDL_Mouse *mouse;
     SDL_Mouse *mouse;
     KMSDRM_CursorData *curdata;
     KMSDRM_CursorData *curdata;
 
 
-    KMSDRM_FBInfo *fb;
-    KMSDRM_PlaneInfo info = {0};
+    uint32_t bo_handle;
 
 
     size_t bo_stride;
     size_t bo_stride;
     size_t bufsize;
     size_t bufsize;
@@ -239,7 +208,7 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
     uint32_t pixel;
     uint32_t pixel;
 
 
     int i,j;
     int i,j;
-    int ret = 0;
+    int ret;
 
 
     mouse = SDL_GetMouse();
     mouse = SDL_GetMouse();
     if (!mouse) {
     if (!mouse) {
@@ -250,28 +219,20 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
     /* Hide cursor if it's NULL or it has no focus(=winwow). */
     /* Hide cursor if it's NULL or it has no focus(=winwow). */
     /*********************************************************/
     /*********************************************************/
     if (!cursor || !mouse->focus) {
     if (!cursor || !mouse->focus) {
-        if (dispdata->cursor_plane) {
-	    /* Hide the drm cursor with no more considerations because
-	    SDL_VideoQuit() takes us here after disabling the mouse
-	    so there is no mouse->cur_cursor by now. */
-	    info.plane = dispdata->cursor_plane;
-	    /* The rest of the members are zeroed, so this takes away the cursor
-	       from the cursor plane. */
-	    drm_atomic_set_plane_props(&info);
-	    if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
-		ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
-	    }
-        }
-	return ret;
+        /* Hide the drm cursor with no more considerations because
+           SDL_VideoQuit() takes us here after disabling the mouse
+           so there is no mouse->cur_cursor by now. */
+	ret = KMSDRM_drmModeSetCursor(viddata->drm_fd,
+	    dispdata->crtc->crtc_id, 0, 0, 0);
+	if (ret) {
+	    ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
+	}
+        return ret;
     }
     }
 
 
     /************************************************/
     /************************************************/
     /* If cursor != NULL, DO show cursor on display */
     /* If cursor != NULL, DO show cursor on display */
     /************************************************/
     /************************************************/
-    if (!dispdata->cursor_plane) {
-        return SDL_SetError("Hardware cursor plane not initialized.");
-    }
-    
     curdata = (KMSDRM_CursorData *) cursor->driverdata;
     curdata = (KMSDRM_CursorData *) cursor->driverdata;
 
 
     if (!curdata || !dispdata->cursor_bo) {
     if (!curdata || !dispdata->cursor_bo) {
@@ -297,7 +258,7 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
     for (i = 0; i < curdata->h; i++) {
     for (i = 0; i < curdata->h; i++) {
         for (j = 0; j < curdata->w; j++) {
         for (j = 0; j < curdata->w; j++) {
             pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
             pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
-            alpha_premultiply_ARGB8888 (&pixel);
+            legacy_alpha_premultiply_ARGB8888 (&pixel);
             SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
             SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
         }
         }
     }
     }
@@ -308,29 +269,21 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
         goto cleanup;
         goto cleanup;
     }
     }
 
 
-    /* Get the fb_id for the GBM BO so we can show it on the cursor plane. */
-    fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo);
-
-    /* Show the GBM BO buffer on the cursor plane. */
-    info.plane = dispdata->cursor_plane;
-    info.crtc_id = dispdata->crtc->crtc->crtc_id;
-    info.fb_id = fb->fb_id; 
-    info.src_w = dispdata->cursor_w;
-    info.src_h = dispdata->cursor_h;
-    info.crtc_x = mouse->x - curdata->hot_x;
-    info.crtc_y = mouse->y - curdata->hot_y;
-    info.crtc_w = curdata->w;
-    info.crtc_h = curdata->h; 
-
-    drm_atomic_set_plane_props(&info);
+    /* Put the GBM BO buffer on screen using the DRM interface. */
+    bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32;
+    if (curdata->hot_x == 0 && curdata->hot_y == 0) {
+        ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id,
+            bo_handle, dispdata->cursor_w, dispdata->cursor_h);
+    } else {
+        ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id,
+            bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y);
+    }
 
 
-    if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
-        ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
+    if (ret) {
+        ret = SDL_SetError("Failed to set DRM cursor.");
         goto cleanup;
         goto cleanup;
     }
     }
 
 
-    ret = 0;
-
 cleanup:
 cleanup:
 
 
     if (ready_buffer) {
     if (ready_buffer) {
@@ -373,7 +326,6 @@ KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
 static int
 static int
 KMSDRM_WarpMouseGlobal(int x, int y)
 KMSDRM_WarpMouseGlobal(int x, int y)
 {
 {
-    KMSDRM_CursorData *curdata;
     SDL_Mouse *mouse = SDL_GetMouse();
     SDL_Mouse *mouse = SDL_GetMouse();
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
 
 
@@ -382,11 +334,18 @@ KMSDRM_WarpMouseGlobal(int x, int y)
         SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
         SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
 
 
         /* And now update the cursor graphic position on screen. */
         /* And now update the cursor graphic position on screen. */
-        curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
         if (dispdata->cursor_bo) {
         if (dispdata->cursor_bo) {
-            if (drm_atomic_movecursor(curdata, x, y)) {
-                return SDL_SetError("drm_atomic_movecursor() failed.");
-            }
+	    int ret, drm_fd;
+	    drm_fd = KMSDRM_gbm_device_get_fd(
+		KMSDRM_gbm_bo_get_device(dispdata->cursor_bo));
+	    ret = KMSDRM_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, x, y);
+
+	    if (ret) {
+		SDL_SetError("drmModeMoveCursor() failed.");
+	    }
+
+	    return ret;
+
         } else {
         } else {
             return SDL_SetError("Cursor not initialized properly.");
             return SDL_SetError("Cursor not initialized properly.");
         }
         }
@@ -403,30 +362,15 @@ KMSDRM_DeinitMouse(_THIS)
 {
 {
     SDL_VideoDevice *video_device = SDL_GetVideoDevice();
     SDL_VideoDevice *video_device = SDL_GetVideoDevice();
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
     SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
-    KMSDRM_PlaneInfo info = {0};
- 
-    /* 1- Destroy the curso GBM BO. */
+   
+    /* Destroy the curso GBM BO. */
     if (video_device && dispdata->cursor_bo) {
     if (video_device && dispdata->cursor_bo) {
-	/* Unsethe the cursor BO from the cursor plane.
-	   (The other members of the plane info are zeroed). */
-	info.plane = dispdata->cursor_plane;
-	drm_atomic_set_plane_props(&info);
-	/* Wait until the cursor is unset from the cursor plane
-	   before destroying it's BO. */
-	if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
-	    SDL_SetError("Failed atomic commit in KMSDRM_DenitMouse.");
-	}
-	/* ..and finally destroy the cursor DRM BO! */
 	KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
 	KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
 	dispdata->cursor_bo = NULL;
 	dispdata->cursor_bo = NULL;
     }
     }
-
-    /* 2- Free the cursor plane, on which the cursor was being shown. */
-    if (dispdata->cursor_plane) {
-        free_plane(&dispdata->cursor_plane);
-    }
 }
 }
 
 
+/* Create cursor BO. */
 void
 void
 KMSDRM_InitMouse(_THIS)
 KMSDRM_InitMouse(_THIS)
 {
 {
@@ -442,29 +386,23 @@ KMSDRM_InitMouse(_THIS)
     mouse->WarpMouse = KMSDRM_WarpMouse;
     mouse->WarpMouse = KMSDRM_WarpMouse;
     mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
     mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
 
 
-    /***************************************************************************/
-    /* REMEMBER TO BE SURE OF UNDOING ALL THESE STEPS PROPERLY BEFORE CALLING  */
-    /* gbm_device_destroy, OR YOU WON'T BE ABLE TO CREATE A NEW ONE (ERROR -13 */
-    /* on gbm_create_device).                                                  */
-    /***************************************************************************/
-
-    /* 1- Init cursor plane, if we haven't yet. */
-    if (!dispdata->cursor_plane) {
-        setup_plane(_this, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR);
-    }
-
-    /* 2- Create the cursor GBM BO, if we haven't yet. */
+    /************************************************/
+    /* Create the cursor GBM BO, if we haven't yet. */
+    /************************************************/
     if (!dispdata->cursor_bo) {
     if (!dispdata->cursor_bo) {
 
 
-        if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, GBM_FORMAT_ARGB8888,
-                                               GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
+        if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev,
+              GBM_FORMAT_ARGB8888,
+              GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
         {
         {
             SDL_SetError("Unsupported pixel format for cursor");
             SDL_SetError("Unsupported pixel format for cursor");
             return;
             return;
         }
         }
 
 
-	if (KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_WIDTH,  &dispdata->cursor_w) ||
-	    KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, &dispdata->cursor_h))
+	if (KMSDRM_drmGetCap(viddata->drm_fd,
+              DRM_CAP_CURSOR_WIDTH,  &dispdata->cursor_w) ||
+	      KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT,
+              &dispdata->cursor_h))
 	{
 	{
 	    SDL_SetError("Could not get the recommended GBM cursor size");
 	    SDL_SetError("Could not get the recommended GBM cursor size");
 	    goto cleanup;
 	    goto cleanup;
@@ -477,7 +415,7 @@ KMSDRM_InitMouse(_THIS)
 
 
 	dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
 	dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
 	    dispdata->cursor_w, dispdata->cursor_h,
 	    dispdata->cursor_w, dispdata->cursor_h,
-	    GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+	    GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR);
 
 
 	if (!dispdata->cursor_bo) {
 	if (!dispdata->cursor_bo) {
 	    SDL_SetError("Could not create GBM cursor BO");
 	    SDL_SetError("Could not create GBM cursor BO");
@@ -505,27 +443,28 @@ cleanup:
     }
     }
 }
 }
 
 
+void
+KMSDRM_QuitMouse(_THIS)
+{
+    /* TODO: ? */
+}
+
 /* This is called when a mouse motion event occurs */
 /* This is called when a mouse motion event occurs */
 static void
 static void
 KMSDRM_MoveCursor(SDL_Cursor * cursor)
 KMSDRM_MoveCursor(SDL_Cursor * cursor)
 {
 {
     SDL_Mouse *mouse = SDL_GetMouse();
     SDL_Mouse *mouse = SDL_GetMouse();
-    KMSDRM_CursorData *curdata;
+    SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
+    int drm_fd, ret;
 
 
     /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
     /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
        That's why we move the cursor graphic ONLY. */
        That's why we move the cursor graphic ONLY. */
     if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
     if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
-        curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
-
-        /* Some programs expect cursor movement even while they don't do SwapWindow() calls,
-           and since we ride on the atomic_commit() in SwapWindow() for cursor movement,
-           cursor won't move in these situations. We could do an atomic_commit() here
-           for each cursor movement request, but it cripples the movement to 30FPS,
-           so a future solution is needed. SDLPoP "QUIT?" menu is an example of this
-           situation. */
+        drm_fd = KMSDRM_gbm_device_get_fd(KMSDRM_gbm_bo_get_device(dispdata->cursor_bo));
+        ret = KMSDRM_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, mouse->x, mouse->y);
 
 
-        if (drm_atomic_movecursor(curdata, mouse->x, mouse->y)) {
-            SDL_SetError("drm_atomic_movecursor() failed.");
+        if (ret) {
+            SDL_SetError("drmModeMoveCursor() failed.");
         }
         }
     }
     }
 }
 }

+ 5 - 5
src/video/kmsdrm/SDL_kmsdrmmouse.h

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -30,14 +29,14 @@
 #define MAX_CURSOR_W 512
 #define MAX_CURSOR_W 512
 #define MAX_CURSOR_H 512
 #define MAX_CURSOR_H 512
 
 
-/* Driverdata with driver-side info about the cursor. */
 typedef struct _KMSDRM_CursorData
 typedef struct _KMSDRM_CursorData
 {
 {
-    uint16_t       hot_x, hot_y;
-    uint16_t       w, h;
+    int            hot_x, hot_y;
+    int            w, h;
 
 
     /* The buffer where we store the mouse bitmap ready to be used.
     /* The buffer where we store the mouse bitmap ready to be used.
-       We get it ready and filled in CreateCursor(), and copy it to a GBM BO in ShowCursor().*/     
+       We get it ready and filled in CreateCursor(), and copy it
+       to a GBM BO in ShowCursor().*/     
     uint32_t *buffer;
     uint32_t *buffer;
     size_t buffer_size;
     size_t buffer_size;
     size_t buffer_pitch;
     size_t buffer_pitch;
@@ -46,6 +45,7 @@ typedef struct _KMSDRM_CursorData
 
 
 extern void KMSDRM_InitMouse(_THIS);
 extern void KMSDRM_InitMouse(_THIS);
 extern void KMSDRM_DeinitMouse(_THIS);
 extern void KMSDRM_DeinitMouse(_THIS);
+extern void KMSDRM_QuitMouse(_THIS);
 
 
 extern void KMSDRM_InitCursor();
 extern void KMSDRM_InitCursor();
 
 

+ 48 - 269
src/video/kmsdrm/SDL_kmsdrmopengles.c

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -24,27 +23,16 @@
 
 
 #if SDL_VIDEO_DRIVER_KMSDRM
 #if SDL_VIDEO_DRIVER_KMSDRM
 
 
+#include "SDL_log.h"
+
 #include "SDL_kmsdrmvideo.h"
 #include "SDL_kmsdrmvideo.h"
 #include "SDL_kmsdrmopengles.h"
 #include "SDL_kmsdrmopengles.h"
 #include "SDL_kmsdrmdyn.h"
 #include "SDL_kmsdrmdyn.h"
-#include "SDL_hints.h"
 
 
 #ifndef EGL_PLATFORM_GBM_MESA
 #ifndef EGL_PLATFORM_GBM_MESA
 #define EGL_PLATFORM_GBM_MESA 0x31D7
 #define EGL_PLATFORM_GBM_MESA 0x31D7
 #endif
 #endif
 
 
-#ifndef EGL_SYNC_NATIVE_FENCE_ANDROID
-#define EGL_SYNC_NATIVE_FENCE_ANDROID     0x3144
-#endif
-
-#ifndef EGL_SYNC_NATIVE_FENCE_FD_ANDROID
-#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID  0x3145
-#endif
-
-#ifndef EGL_NO_NATIVE_FENCE_FD_ANDROID
-#define EGL_NO_NATIVE_FENCE_FD_ANDROID    -1
-#endif
-
 /* EGL implementation of SDL OpenGL support */
 /* EGL implementation of SDL OpenGL support */
 
 
 void
 void
@@ -95,291 +83,82 @@ int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
     return 0;
     return 0;
 }
 }
 
 
-/*********************************/
-/* Atomic functions block        */
-/*********************************/
-
-#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
-
-static EGLSyncKHR create_fence(int fd, _THIS)
-{
-    EGLint attrib_list[] = {
-        EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd,
-        EGL_NONE,
-    };
-
-    EGLSyncKHR fence = _this->egl_data->eglCreateSyncKHR
-        (_this->egl_data->egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attrib_list);
-
-    assert(fence);
-    return fence;
-}
-
-/***********************************************************************************/
-/* Comments about buffer access protection mechanism (=fences) are the ones boxed. */
-/* Also, DON'T remove the asserts: if a fence-related call fails, it's better that */
-/* program exits immediately, or we could leave KMS waiting for a failed/missing   */
-/* fence forevever.                                                                */
-/***********************************************************************************/
 int
 int
-KMSDRM_GLES_SwapWindowFenced(_THIS, SDL_Window * window)
-{
+KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
     SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
     SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
     SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
     SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
-    KMSDRM_FBInfo *fb;
-    KMSDRM_PlaneInfo info = {0};
-    SDL_bool modesetting = SDL_FALSE;
-
-    /******************************************************************/
-    /* Create the GPU-side FENCE OBJECT. It will be inserted into the */
-    /* GL 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);
-    assert(dispdata->gpu_fence);
+    SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
+    KMSDRM_FBInfo *fb_info;
+    int ret, timeout;
 
 
-    /******************************************************************/
-    /* eglSwapBuffers flushes the fence down the GL CMDSTREAM, so we  */
-    /* know for sure it's there now.                                  */
-    /* Also it marks, at EGL level, the buffer that we want to become */
-    /* the new front buffer. (Remember that won't really happen until */
-    /* we request a pageflip at the KMS level and it completes.       */
-    /******************************************************************/
-    if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) {
-        return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers");
+    /* Recreate the GBM / EGL surfaces if the display mode has changed */
+    if (windata->egl_surface_dirty) {
+        KMSDRM_CreateSurfaces(_this, window);
     }
     }
 
 
-    /******************************************************************/
-    /* EXPORT the GPU-side FENCE OBJECT to the fence INPUT FD, so we  */
-    /* can pass it into the kernel. Atomic ioctl will pass the        */
-    /* in-fence fd into the kernel, thus telling KMS that it has to   */
-    /* wait for GPU to finish rendering the frame (remember where we  */
-    /* put the fence in the GL CMDSTREAM) before doing the changes    */
-    /* requested in the atomic ioct (the pageflip in this case).      */
-    /* (We export the GPU-side FENCE OJECT to the fence INPUT FD now, */
-    /* not sooner, because now we are sure that the GPU-side fence is */
-    /* in the CMDSTREAM to be lifted when the CMDSTREAM to this point */
-    /* is completed).                                                 */
-    /******************************************************************/
-    dispdata->kms_in_fence_fd = _this->egl_data->eglDupNativeFenceFDANDROID (_this->egl_data->egl_display,
-        dispdata->gpu_fence);
-    
-    _this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->gpu_fence);
-    assert(dispdata->kms_in_fence_fd != -1);
-
-    /* Lock the buffer that is marked by eglSwapBuffers() to become the
-       next front buffer (so it can not be chosen by EGL as back buffer
-       to draw on), and get a handle to it to request the pageflip on it.
-       REMEMBER that gbm_surface_lock_front_buffer() ALWAYS has to be
-       called after eglSwapBuffers(). */
-    windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
-    if (!windata->next_bo) {
-        return SDL_SetError("Failed to lock frontbuffer");
-    }
-    fb = KMSDRM_FBFromBO(_this, windata->next_bo);
-    if (!fb) {
-        return SDL_SetError("Failed to get a new framebuffer from BO");
+    /* Wait for confirmation that the next front buffer has been flipped, at which
+       point the previous front buffer can be released */
+    timeout = 0;
+    if (_this->egl_data->egl_swapinterval == 1) {
+        timeout = -1;
     }
     }
-
-    /* Add the pageflip to the request list. */
-    info.plane = dispdata->display_plane;
-    info.crtc_id = dispdata->crtc->crtc->crtc_id;
-    info.fb_id = fb->fb_id;
-
-    info.src_w = windata->src_w;
-    info.src_h = windata->src_h;
-    info.crtc_w = windata->output_w;
-    info.crtc_h = windata->output_h;
-    info.crtc_x = windata->output_x;
-
-    drm_atomic_set_plane_props(&info);
-
-    /*****************************************************************/
-    /* Tell the display (KMS) that it will have to wait on the fence */
-    /* for the GPU-side FENCE.                                       */
-    /*                                                               */
-    /* Since KMS is a kernel thing, we have to pass an FD into       */
-    /* the kernel, and get another FD out of the kernel.             */
-    /*                                                               */
-    /* 1) To pass the GPU-side fence into the kernel, we set the     */
-    /* INPUT FD as the IN_FENCE_FD prop of the PRIMARY PLANE.        */
-    /* This FD tells KMS (the kernel) to wait for the GPU-side fence.*/
-    /*                                                               */
-    /* 2) To get the KMS-side fence out of the kernel, we set the    */
-    /* OUTPUT FD as the OUT_FEWNCE_FD prop of the CRTC.              */
-    /* This FD will be later imported as a FENCE OBJECT which will be*/
-    /* used to tell the GPU to wait for KMS to complete the changes  */
-    /* requested in atomic_commit (the pageflip in this case).       */ 
-    /*****************************************************************/
-    if (dispdata->kms_in_fence_fd != -1)
-    {
-        add_plane_property(dispdata->atomic_req, dispdata->display_plane,
-            "IN_FENCE_FD", dispdata->kms_in_fence_fd);
-        add_crtc_property(dispdata->atomic_req, dispdata->crtc,
-            "OUT_FENCE_PTR", VOID2U64(&dispdata->kms_out_fence_fd));
+    if (!KMSDRM_WaitPageFlip(_this, windata, timeout)) {
+        return 0;
     }
     }
 
 
-    /* Do we have a pending modesetting? If so, set the necessary 
-       props so it's included in the incoming atomic commit. */
-    if (dispdata->modeset_pending) {
-        uint32_t blob_id;
-        SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
-
-        add_connector_property(dispdata->atomic_req, dispdata->connector, "CRTC_ID", dispdata->crtc->crtc->crtc_id);
-        KMSDRM_drmModeCreatePropertyBlob(viddata->drm_fd, &dispdata->mode, sizeof(dispdata->mode), &blob_id);
-        add_crtc_property(dispdata->atomic_req, dispdata->crtc, "MODE_ID", blob_id);
-        add_crtc_property(dispdata->atomic_req, dispdata->crtc, "active", 1);
-        modesetting = SDL_TRUE;
-        dispdata->modeset_pending = SDL_FALSE;
-    }
-
-    /*****************************************************************/   
-    /* Issue a non-blocking atomic commit: for triple buffering,     */
-    /* this must not block so the game can start building another    */
-    /* frame, even if the just-requested pageflip hasnt't completed. */
-    /*****************************************************************/   
-    if (drm_atomic_commit(_this, SDL_FALSE, modesetting)) {
-        return SDL_SetError("Failed to issue atomic commit on pageflip");
-    }
-
-    /* Release the previous front buffer so EGL can chose it as back buffer
-       and render on it again. */
+    /* Release the previous front buffer */
     if (windata->bo) {
     if (windata->bo) {
         KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
         KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
+        windata->bo = NULL;
     }
     }
 
 
-    /* Take note of the buffer about to become front buffer, so next
-       time we come here we can free it like we just did with the previous
-       front buffer. */
     windata->bo = windata->next_bo;
     windata->bo = windata->next_bo;
 
 
-    /****************************************************************/
-    /* Import the KMS-side FENCE OUTPUT FD from the kernel to the   */
-    /* KMS-side FENCE OBJECT so we can use use it to fence the GPU. */
-    /****************************************************************/
-    dispdata->kms_fence = create_fence(dispdata->kms_out_fence_fd, _this);
-    assert(dispdata->kms_fence);
-
-    /****************************************************************/
-    /* "Delete" the fence OUTPUT FD, because we already have the    */
-    /* KMS FENCE OBJECT, the fence itself is away from us, on the   */
-    /* kernel side.                                                 */
-    /****************************************************************/
-    dispdata->kms_out_fence_fd = -1;
-
-    /*****************************************************************/
-    /* Tell the GPU to wait on the fence for the KMS-side FENCE,     */
-    /* which means waiting until the requested pageflip is completed.*/
-    /*****************************************************************/
-    _this->egl_data->eglWaitSyncKHR(_this->egl_data->egl_display, dispdata->kms_fence, 0);
-
-    return 0;
-}
-
-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};
-    SDL_bool modesetting = SDL_FALSE;
-
-    /**********************************************************************************/
-    /* In double-buffer mode, atomic_commit will always be synchronous/blocking (ie:  */
-    /* won't return until the requested changes are really done).                     */
-    /* Also, there's no need to fence KMS or the GPU, because we won't be entering    */
-    /* game loop again (hence not building or executing a new cmdstring) until        */
-    /* pageflip is done, so we don't need to protect the KMS/GPU access to the buffer.*/     
-    /**********************************************************************************/ 
-
-    /* Mark, at EGL level, the buffer that we want to become the new front buffer.
-       It won't really happen until we request a pageflip at the KMS level and it
-       completes. */
-    if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) {
-        return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers");
+    /* Mark a buffer to becume the next front buffer.
+       This won't happen until pagelip completes. */
+    if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display,
+                                           windata->egl_surface))) {
+        SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
+        return 0;
     }
     }
 
 
-    /* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer
-       (so it can not be chosen by EGL as back buffer to draw on), and get a handle to it,
-       to request the pageflip on it. */
+    /* Lock the next front buffer so it can't be allocated as a back buffer */
     windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
     windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
     if (!windata->next_bo) {
     if (!windata->next_bo) {
-        return SDL_SetError("Failed to lock frontbuffer");
+        SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
+        return 0;
     }
     }
-    fb = KMSDRM_FBFromBO(_this, windata->next_bo);
-    if (!fb) {
-        return SDL_SetError("Failed to get a new framebuffer BO");
-    }
-
-    /* Add the pageflip to the request list. */
-    info.plane = dispdata->display_plane;
-    info.crtc_id = dispdata->crtc->crtc->crtc_id;
-    info.fb_id = fb->fb_id;
-
-    info.src_w = windata->src_w;
-    info.src_h = windata->src_h;
-    info.crtc_w = windata->output_w;
-    info.crtc_h = windata->output_h;
-    info.crtc_x = windata->output_x;
-
-    drm_atomic_set_plane_props(&info);
-
-    /* Do we have a pending modesetting? If so, set the necessary 
-       props so it's included in the incoming atomic commit. */
-    if (dispdata->modeset_pending) {
-        uint32_t blob_id;
 
 
-        SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
-
-        add_connector_property(dispdata->atomic_req, dispdata->connector, "CRTC_ID", dispdata->crtc->crtc->crtc_id);
-        KMSDRM_drmModeCreatePropertyBlob(viddata->drm_fd, &dispdata->mode, sizeof(dispdata->mode), &blob_id);
-        add_crtc_property(dispdata->atomic_req, dispdata->crtc, "MODE_ID", blob_id);
-        add_crtc_property(dispdata->atomic_req, dispdata->crtc, "active", 1);
-        modesetting = SDL_TRUE;
-        dispdata->modeset_pending = SDL_FALSE;
+    /* Get the fb_info for the next front buffer. */
+    fb_info = KMSDRM_FBFromBO(_this, windata->next_bo);
+    if (!fb_info) {
+        return 0;
     }
     }
 
 
-    /* Issue the one and only atomic commit where all changes will be requested!. 
-       Blocking for double buffering: won't return until completed. */
-    if (drm_atomic_commit(_this, SDL_TRUE, modesetting)) {
-        return SDL_SetError("Failed to issue atomic commit on pageflip");
-    }
+    /* Issue pageflip on the next front buffer.
+       The pageflip will be done during the next vblank. */
+    ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id,
+	     fb_info->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip);
 
 
-    /* Release last front buffer so EGL can chose it as back buffer and render on it again. */
-    if (windata->bo) {
-        KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
+    if (_this->egl_data->egl_swapinterval == 1) {
+	if (ret == 0) {
+	    windata->waiting_for_flip = SDL_TRUE;
+	} else {
+	    SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
+	}
     }
     }
 
 
-    /* Take note of current front buffer, so we can free it next time we come here. */
-    windata->bo = windata->next_bo;
-
-    return 0;
-}
-
-int
-KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
-{
-    SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
-
-    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;
-        }
+    /* If we are in double-buffer mode, wait immediately for vsync
+       (as if we only had two buffers),
+       Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
+       to enable this. */
+    if (_this->egl_data->egl_swapinterval == 1 && windata->double_buffer) {
+	KMSDRM_WaitPageFlip(_this, windata, -1);
     }
     }
 
 
-    return windata->swap_window(_this, window);
+    return 0;
 }
 }
 
 
-/***************************************/
-/* End of Atomic functions block       */
-/***************************************/
-
 SDL_EGL_MakeCurrent_impl(KMSDRM)
 SDL_EGL_MakeCurrent_impl(KMSDRM)
 
 
 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
 #endif /* SDL_VIDEO_DRIVER_KMSDRM */

+ 0 - 1
src/video/kmsdrm/SDL_kmsdrmopengles.h

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages

+ 20 - 29
src/video/kmsdrm/SDL_kmsdrmsym.h

@@ -41,32 +41,29 @@ SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
 SDL_KMSDRM_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value))
 SDL_KMSDRM_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value))
-SDL_KMSDRM_SYM(int,drmIoctl,(int fd, unsigned long request, void *arg))
 SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
 SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
-
 SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
 SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
                                  uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
                                  uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
                                  uint32_t *buf_id))
                                  uint32_t *buf_id))
-
-SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height,
-                                  uint32_t pixel_format, const uint32_t bo_handles[4],
-                                  const uint32_t pitches[4], const uint32_t offsets[4],
-                                  uint32_t *buf_id, uint32_t flags))
-
-SDL_KMSDRM_SYM(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width, uint32_t height,
-                                               uint32_t pixel_format, const uint32_t bo_handles[4],
-                                               const uint32_t pitches[4], const uint32_t offsets[4],
-                                               const uint64_t modifier[4], uint32_t *buf_id,
-                                               uint32_t flags))
-
 SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
 SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
 SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
 SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
 SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
 SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
+SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
+                                   uint32_t x, uint32_t y, uint32_t *connectors, int count,
+                                   drmModeModeInfoPtr mode))
+SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
+                                     uint32_t width, uint32_t height))
+SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
+                                      uint32_t width, uint32_t height,
+                                      int32_t hot_x, int32_t hot_y))
+SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
 SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
 SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
 SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
 SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
+SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
+SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
+                                    uint32_t flags, void *user_data))
 
 
-/* Atomic functions */
-
+/* Planes stuff. */
 SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value))
 SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value))
 SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
 SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
 SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
 SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
@@ -77,14 +74,13 @@ SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr))
 SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr))
-
-SDL_KMSDRM_SYM(drmModeAtomicReqPtr,drmModeAtomicAlloc,(void))
-SDL_KMSDRM_SYM(void,drmModeAtomicFree,(drmModeAtomicReqPtr req))
-SDL_KMSDRM_SYM(int,drmModeAtomicCommit,(int fd,drmModeAtomicReqPtr req,uint32_t flags,void *user_data))
-SDL_KMSDRM_SYM(int,drmModeAtomicAddProperty,(drmModeAtomicReqPtr req,uint32_t object_id,uint32_t property_id,uint64_t value))
-SDL_KMSDRM_SYM(int,drmModeCreatePropertyBlob,(int fd,const void *data,size_t size,uint32_t *id))
-
-/* End of atomic fns */
+SDL_KMSDRM_SYM(int,drmModeSetPlane,(int fd, uint32_t plane_id, uint32_t crtc_id,
+			   uint32_t fb_id, uint32_t flags,
+			   int32_t crtc_x, int32_t crtc_y,
+			   uint32_t crtc_w, uint32_t crtc_h,
+			   uint32_t src_x, uint32_t src_y,
+			   uint32_t src_w, uint32_t src_h))
+/* Planes stuff ends. */
 
 
 SDL_KMSDRM_MODULE(GBM)
 SDL_KMSDRM_MODULE(GBM)
 SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
 SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
@@ -95,11 +91,6 @@ SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd))
 SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
-SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo,int plane))
-SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_format,(struct gbm_bo *bo))
-SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane))
-SDL_KMSDRM_SYM(int,gbm_bo_get_plane_count,(struct gbm_bo *bo))
-
 SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
 SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
 SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
 SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))

File diff suppressed because it is too large
+ 124 - 633
src/video/kmsdrm/SDL_kmsdrmvideo.c


+ 18 - 85
src/video/kmsdrm/SDL_kmsdrmvideo.h

@@ -1,7 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
   Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
-  Atomic KMSDRM backend by Manuel Alfayate Corchete <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -31,17 +30,8 @@
 #include <unistd.h>
 #include <unistd.h>
 #include <xf86drm.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 #include <xf86drmMode.h>
-
 #include <gbm.h>
 #include <gbm.h>
-#include <assert.h>
 #include <EGL/egl.h>
 #include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-/****************************************************************************************/
-/* Driverdata pointers are void struct* used to store backend-specific variables        */
-/* and info that supports the SDL-side structs like SDL Display Devices, SDL_Windows... */
-/* which need to be "supported" with backend-side info and mechanisms to work.          */ 
-/****************************************************************************************/
 
 
 typedef struct SDL_VideoData
 typedef struct SDL_VideoData
 {
 {
@@ -51,56 +41,30 @@ typedef struct SDL_VideoData
 
 
     struct gbm_device *gbm_dev;
     struct gbm_device *gbm_dev;
 
 
-    SDL_Window **windows;
-    unsigned int max_windows;
-    unsigned int num_windows;
-
     SDL_bool video_init;        /* Has VideoInit succeeded? */
     SDL_bool video_init;        /* Has VideoInit succeeded? */
-
     SDL_bool vulkan_mode;       /* Are we in Vulkan mode? One VK window is enough to be. */
     SDL_bool vulkan_mode;       /* Are we in Vulkan mode? One VK window is enough to be. */
 
 
+    SDL_Window **windows;
+    int max_windows;
+    int num_windows;
 } SDL_VideoData;
 } SDL_VideoData;
 
 
-typedef struct plane {
-    drmModePlane *plane;
-    drmModeObjectProperties *props;
-    drmModePropertyRes **props_info;
-} plane;
 
 
-typedef struct crtc {
-    drmModeCrtc *crtc;
-    drmModeObjectProperties *props;
-    drmModePropertyRes **props_info;
-} crtc;
+typedef struct SDL_DisplayModeData
+{
+    int mode_index;
+} SDL_DisplayModeData;
 
 
-typedef struct connector {
-    drmModeConnector *connector;
-    drmModeObjectProperties *props;
-    drmModePropertyRes **props_info;
-} connector;
 
 
-/* More general driverdata info that gives support and substance to the SDL_Display. */
 typedef struct SDL_DisplayData
 typedef struct SDL_DisplayData
 {
 {
+    drmModeConnector *connector;
+    drmModeCrtc *crtc;
     drmModeModeInfo mode;
     drmModeModeInfo mode;
     drmModeModeInfo original_mode;
     drmModeModeInfo original_mode;
 
 
-    plane *display_plane;
-    plane *cursor_plane;
-    crtc *crtc;
-    connector *connector;
-
-    /* Central atomic request list, used for the prop
-       changeset related to pageflip in SwapWindow. */ 
-    drmModeAtomicReq *atomic_req;
-
-    int kms_in_fence_fd;
-    int kms_out_fence_fd;
+    drmModeCrtc *saved_crtc;    /* CRTC to restore on quit */
 
 
-    EGLSyncKHR kms_fence;
-    EGLSyncKHR gpu_fence;
-
-    SDL_bool modeset_pending;
     SDL_bool gbm_init;
     SDL_bool gbm_init;
 
 
     /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
     /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
@@ -110,11 +74,12 @@ typedef struct SDL_DisplayData
     struct gbm_bo *cursor_bo;
     struct gbm_bo *cursor_bo;
     uint64_t cursor_w, cursor_h;
     uint64_t cursor_w, cursor_h;
 
 
+    SDL_bool modeset_pending;
+
     SDL_bool set_default_cursor_pending;
     SDL_bool set_default_cursor_pending;
 
 
 } SDL_DisplayData;
 } SDL_DisplayData;
 
 
-/* Driverdata info that gives KMSDRM-side support and substance to the SDL_Window. */
 typedef struct SDL_WindowData
 typedef struct SDL_WindowData
 {
 {
     SDL_VideoData *viddata;
     SDL_VideoData *viddata;
@@ -126,6 +91,10 @@ typedef struct SDL_WindowData
     struct gbm_bo *bo;
     struct gbm_bo *bo;
     struct gbm_bo *next_bo;
     struct gbm_bo *next_bo;
 
 
+    SDL_bool waiting_for_flip;
+    SDL_bool double_buffer;
+
+    int egl_surface_dirty;
     EGLSurface egl_surface;
     EGLSurface egl_surface;
 
 
     /* For scaling and AR correction. */
     /* For scaling and AR correction. */
@@ -135,54 +104,18 @@ typedef struct SDL_WindowData
     int32_t output_h;
     int32_t output_h;
     int32_t output_x;
     int32_t output_x;
 
 
-    /* This dictates what approach we'll use for SwapBuffers. */
-    int (*swap_window)(_THIS, SDL_Window * window);
-
 } SDL_WindowData;
 } SDL_WindowData;
 
 
-typedef struct SDL_DisplayModeData
-{
-    int mode_index;
-} SDL_DisplayModeData;
-
 typedef struct KMSDRM_FBInfo
 typedef struct KMSDRM_FBInfo
 {
 {
     int drm_fd;         /* DRM file desc */
     int drm_fd;         /* DRM file desc */
     uint32_t fb_id;     /* DRM framebuffer ID */
     uint32_t fb_id;     /* DRM framebuffer ID */
 } KMSDRM_FBInfo;
 } KMSDRM_FBInfo;
 
 
-typedef struct KMSDRM_PlaneInfo
-{
-    struct plane *plane;
-    uint32_t fb_id;
-    uint32_t crtc_id;
-    int32_t src_x;
-    int32_t src_y;
-    int32_t src_w;
-    int32_t src_h;
-    int32_t crtc_x;
-    int32_t crtc_y;
-    int32_t crtc_w;
-    int32_t crtc_h;
-} KMSDRM_PlaneInfo;
-
 /* Helper functions */
 /* Helper functions */
-int KMSDRM_CreateEGLSurface(_THIS, SDL_Window * window);
+int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window);
 KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
 KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
-
-/* Atomic functions that are used from SDL_kmsdrmopengles.c and SDL_kmsdrmmouse.c */
-void drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info); 
-
-void drm_atomic_waitpending(_THIS);
-int drm_atomic_commit(_THIS, SDL_bool blocking, SDL_bool allow_modeset);
-int add_plane_property(drmModeAtomicReq *req, struct plane *plane,
-                             const char *name, uint64_t value);
-int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc,
-                             const char *name, uint64_t value);
-int add_connector_property(drmModeAtomicReq *req, struct connector *connector,
-                             const char *name, uint64_t value);
-int setup_plane(_THIS, struct plane **plane, uint32_t plane_type);
-void free_plane(struct plane **plane);
+SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout);
 
 
 /****************************************************************************/
 /****************************************************************************/
 /* SDL_VideoDevice functions declaration                                    */
 /* SDL_VideoDevice functions declaration                                    */

+ 2 - 2
src/video/kmsdrm/SDL_kmsdrmvulkan.c

@@ -174,7 +174,7 @@ void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
 /* Instead, programs using SDL and Vulkan create their Vulkan instance */
 /* Instead, programs using SDL and Vulkan create their Vulkan instance */
 /* and we get it here, ready to use.                                   */
 /* and we get it here, ready to use.                                   */
 /* Extensions specific for this platform are activated in              */
 /* Extensions specific for this platform are activated in              */
-/* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with              */
+/* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with       */
 /* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */                
 /* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */                
 /***********************************************************************/
 /***********************************************************************/
 SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
 SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
@@ -397,7 +397,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
                                      surface);
                                      surface);
     if(result != VK_SUCCESS)
     if(result != VK_SUCCESS)
     {
     {
-        SDL_SetError("vkCreateKMSDRMSurfaceKHR failed: %s",
+        SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
             SDL_Vulkan_GetResultString(result));
             SDL_Vulkan_GetResultString(result));
         goto clean;
         goto clean;
     }
     }

+ 3 - 3
src/video/kmsdrm/SDL_kmsdrmvulkan.h

@@ -26,8 +26,8 @@
 
 
 #include "../../SDL_internal.h"
 #include "../../SDL_internal.h"
 
 
-#ifndef SDL_kmsdrmvulkan_h_
-#define SDL_kmsdrmvulkan_h_
+#ifndef SDL_kmsdrm_vulkan_h_
+#define SDL_kmsdrm_vulkan_h_
 
 
 #include "../SDL_vulkan_internal.h"
 #include "../SDL_vulkan_internal.h"
 #include "../SDL_sysvideo.h"
 #include "../SDL_sysvideo.h"
@@ -48,6 +48,6 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
 
 
 #endif
 #endif
 
 
-#endif /* SDL_kmsdrmvulkan_h_ */
+#endif /* SDL_kmsdrm_vulkan_h_ */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

Some files were not shown because too many files changed in this diff