diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c index 55902fc47..ec560be8c 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.c +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -39,6 +39,84 @@ static void KMSDRM_FreeCursor(SDL_Cursor * cursor); static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y); static int KMSDRM_WarpMouseGlobal(int x, int y); +/**********************************/ +/* Atomic helper functions block. */ +/**********************************/ + +int +drm_atomic_setcursor(KMSDRM_CursorData *curdata, int x, int y) +{ + KMSDRM_FBInfo *fb; + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(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(); + + if (curdata) + { + if (!dispdata->cursor_plane) { + setup_plane(curdata->video, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR); + /* "curdata->video" is the _THIS pointer, which points to an SDL_Display, as passed from kmsdrmmouse.c */ + } + + fb = KMSDRM_FBFromBO(curdata->video, curdata->bo); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", fb->fb_id); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", dispdata->crtc->crtc->crtc_id); + + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", curdata->w << 16); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", curdata->h << 16); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_X", x); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_Y", y); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", curdata->w); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", curdata->h); + } + else if (dispdata->cursor_plane) /* Don't go further if plane has already been freed. */ + { + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", 0); + + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", 0); + add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", 0); + + free_plane(&dispdata->cursor_plane); + } + + /* GPU <-> DISPLAY synchronization is done ON the display_plane, + so no need to set any fence props here, we do that only on the main + display plane. */ + + return 0; +} + +int +drm_atomic_movecursor(KMSDRM_CursorData *curdata, int x, int y) +{ + 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; +} + +/***************************************/ +/* Atomic helper functions block ends. */ +/***************************************/ + /* 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]. These multiplications have to be done with floats instead of uint32_t's, and the resulting values have diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.h b/src/video/kmsdrm/SDL_kmsdrmmouse.h index 4d2144843..030bde4f9 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.h +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.h @@ -29,6 +29,19 @@ #define MAX_CURSOR_W 512 #define MAX_CURSOR_H 512 +/* Driverdata with driver-side info about the cursor. */ +typedef struct _KMSDRM_CursorData +{ + struct gbm_bo *bo; + uint32_t crtc_id; + int hot_x, hot_y; + int w, h; + /* The video devide implemented on SDL_kmsdrmvideo.c + * to be used as _THIS pointer in SDL_kmsdrmvideo.c + * functions that need it. */ + SDL_VideoDevice *video; +} KMSDRM_CursorData; + extern void KMSDRM_InitMouse(_THIS); extern void KMSDRM_QuitMouse(_THIS); diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index b8f0d1cfc..2ff495185 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -194,8 +194,8 @@ static int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc, return KMSDRM_drmModeAtomicAddProperty(req, crtc->crtc->crtc_id, prop_id, value); } -static int add_plane_property(drmModeAtomicReq *req, struct plane *plane, - const char *name, uint64_t value) +int add_plane_property(drmModeAtomicReq *req, struct plane *plane, + const char *name, uint64_t value) { unsigned int i; int prop_id = -1; @@ -389,9 +389,9 @@ static uint32_t get_plane_id(_THIS, uint32_t plane_type) } /* Setup cursor plane and it's props. */ -static int -setup_plane(_THIS, struct plane **plane, uint32_t plane_type ) { - +int +setup_plane(_THIS, struct plane **plane, uint32_t plane_type) +{ uint32_t plane_id; SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); @@ -430,8 +430,9 @@ cleanup: } /* Free a plane and it's props. */ -static void -free_plane(struct plane **plane) { +void +free_plane(struct plane **plane) +{ SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); if (dispdata && (*plane)) { @@ -492,76 +493,6 @@ drm_atomic_setbuffer(_THIS, struct plane *plane, uint32_t fb_id, uint32_t crtc_i } } -int -drm_atomic_setcursor(KMSDRM_CursorData *curdata, int x, int y) -{ - KMSDRM_FBInfo *fb; - SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(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(); - - if (curdata) - { - if (!dispdata->cursor_plane) { - setup_plane(curdata->video, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR); - /* "curdata->video" is the _THIS pointer, which points to an SDL_Display, as passed from kmsdrmmouse.c */ - } - - fb = KMSDRM_FBFromBO(curdata->video, curdata->bo); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", fb->fb_id); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", dispdata->crtc->crtc->crtc_id); - - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", curdata->w << 16); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", curdata->h << 16); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_X", x); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_Y", y); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", curdata->w); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", curdata->h); - } - else if (dispdata->cursor_plane) /* Don't go further if plane has already been freed. */ - { - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", 0); - - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", 0); - add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", 0); - - free_plane(&dispdata->cursor_plane); - } - - /* GPU <-> DISPLAY synchronization is done ON the display_plane, - so no need to set any fence props here, we do that only on the main - display plane. */ - - return 0; -} - -int -drm_atomic_movecursor(KMSDRM_CursorData *curdata, int x, int y) -{ - 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; -} - int drm_atomic_commit(_THIS, SDL_bool blocking) { SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0); diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index 994889773..1fa82ec37 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -119,30 +119,18 @@ typedef struct KMSDRM_FBInfo uint32_t fb_id; /* DRM framebuffer ID */ } KMSDRM_FBInfo; -/* Driverdata with driver-side info about the cursor. */ -typedef struct _KMSDRM_CursorData -{ - struct gbm_bo *bo; - uint32_t crtc_id; - int hot_x, hot_y; - int w, h; - /* The video devide implemented on SDL_kmsdrmvideo.c - * to be used as _THIS pointer in SDL_kmsdrmvideo.c - * functions that need it. */ - SDL_VideoDevice *video; -} KMSDRM_CursorData; - /* Helper functions */ int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window); 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_modeset(_THIS, int mode_index); void drm_atomic_setbuffer(_THIS, struct plane *plane, uint32_t fb_id, uint32_t crtc_id); void drm_atomic_waitpending(_THIS); int drm_atomic_commit(_THIS, SDL_bool blocking); -int drm_atomic_setcursor(KMSDRM_CursorData *curdata, int x, int y); -int drm_atomic_movecursor(KMSDRM_CursorData *curdata, int x, int y); +int add_plane_property(drmModeAtomicReq *req, struct plane *plane, + const char *name, uint64_t value); +int setup_plane(_THIS, struct plane **plane, uint32_t plane_type); +void free_plane(struct plane **plane); /****************************************************************************/ /* SDL_VideoDevice functions declaration */