KMSDRM_LEGACY is no longer legacy

This commit is contained in:
Sam Lantinga 2021-01-08 11:08:23 -08:00
parent 29888bd69a
commit 8746788fea
13 changed files with 0 additions and 3070 deletions

View File

@ -1,167 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#define DEBUG_DYNAMIC_KMSDRM_LEGACY 0
#include "SDL_kmsdrm_legacy_dyn.h"
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
#include "SDL_name.h"
#include "SDL_loadso.h"
typedef struct
{
void *lib;
const char *libname;
} kmsdrmdynlib;
#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL
#endif
#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM
#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL
#endif
static kmsdrmdynlib kmsdrmlibs[] = {
{NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM},
{NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC}
};
static void *
KMSDRM_LEGACY_GetSym(const char *fnname, int *pHasModule)
{
int i;
void *fn = NULL;
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].lib != NULL) {
fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname);
if (fn != NULL)
break;
}
}
#if DEBUG_DYNAMIC_KMSDRM_LEGACY
if (fn != NULL)
SDL_Log("KMSDRM_LEGACY: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn);
else
SDL_Log("KMSDRM_LEGACY: Symbol '%s' NOT FOUND!\n", fnname);
#endif
if (fn == NULL)
*pHasModule = 0; /* kill this module. */
return fn;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */
/* Define all the function pointers and wrappers... */
#define SDL_KMSDRM_LEGACY_MODULE(modname) int SDL_KMSDRM_LEGACY_HAVE_##modname = 0;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn = NULL;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name = NULL;
#include "SDL_kmsdrm_legacy_sym.h"
static int kmsdrm_load_refcount = 0;
void
SDL_KMSDRM_LEGACY_UnloadSymbols(void)
{
/* Don't actually unload if more than one module is using the libs... */
if (kmsdrm_load_refcount > 0) {
if (--kmsdrm_load_refcount == 0) {
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
int i;
#endif
/* set all the function pointers to NULL. */
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 0;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = NULL;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = NULL;
#include "SDL_kmsdrm_legacy_sym.h"
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].lib != NULL) {
SDL_UnloadObject(kmsdrmlibs[i].lib);
kmsdrmlibs[i].lib = NULL;
}
}
#endif
}
}
}
/* returns non-zero if all needed symbols were loaded. */
int
SDL_KMSDRM_LEGACY_LoadSymbols(void)
{
int rc = 1; /* always succeed if not using Dynamic KMSDRM_LEGACY stuff. */
/* deal with multiple modules needing these symbols... */
if (kmsdrm_load_refcount++ == 0) {
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].libname != NULL) {
kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname);
}
}
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */
#include "SDL_kmsdrm_legacy_sym.h"
#define SDL_KMSDRM_LEGACY_MODULE(modname) thismod = &SDL_KMSDRM_LEGACY_HAVE_##modname;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = (SDL_DYNKMSDRM_LEGACYFN_##fn) KMSDRM_LEGACY_GetSym(#fn,thismod);
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = *(SDL_DYNKMSDRM_LEGACYCONST_##name*) KMSDRM_LEGACY_GetSym(#name,thismod);
#include "SDL_kmsdrm_legacy_sym.h"
if ((SDL_KMSDRM_LEGACY_HAVE_LIBDRM) && (SDL_KMSDRM_LEGACY_HAVE_GBM)) {
/* all required symbols loaded. */
SDL_ClearError();
} else {
/* in case something got loaded... */
SDL_KMSDRM_LEGACY_UnloadSymbols();
rc = 0;
}
#else /* no dynamic KMSDRM_LEGACY */
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = fn;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = name;
#include "SDL_kmsdrm_legacy_sym.h"
#endif
}
return rc;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,53 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_kmsdrmdyn_h_
#define SDL_kmsdrmdyn_h_
#include "../../SDL_internal.h"
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#ifdef __cplusplus
extern "C" {
#endif
int SDL_KMSDRM_LEGACY_LoadSymbols(void);
void SDL_KMSDRM_LEGACY_UnloadSymbols(void);
/* Declare all the function pointers and wrappers... */
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) \
typedef rc (*SDL_DYNKMSDRM_LEGACYFN_##fn) params; \
extern SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name) \
typedef type SDL_DYNKMSDRM_LEGACYCONST_##name; \
extern SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name;
#include "SDL_kmsdrm_legacy_sym.h"
#ifdef __cplusplus
}
#endif
#endif /* SDL_kmsdrmdyn_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,42 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_events.h"
#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif
void KMSDRM_LEGACY_PumpEvents(_THIS)
{
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Poll();
#endif
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */

View File

@ -1,31 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_kmsdrmevents_h_
#define SDL_kmsdrmevents_h_
extern void KMSDRM_LEGACY_PumpEvents(_THIS);
extern void KMSDRM_LEGACY_EventInit(_THIS);
extern void KMSDRM_LEGACY_EventQuit(_THIS);
#endif /* SDL_kmsdrmevents_h_ */

View File

@ -1,474 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_mouse.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/default_cursor.h"
static SDL_Cursor *KMSDRM_LEGACY_CreateDefaultCursor(void);
static SDL_Cursor *KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
static int KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y);
static int KMSDRM_LEGACY_WarpMouseGlobal(int x, int y);
/**************************************************************************************/
/* BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS. */
/* How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have */
/* many cursors in mouse->cursors. */
/* -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many */
/* cursosr with this, not only one. */
/* -SDL stores those cursors in a cursors array, in mouse->cursors. */
/* -Whenever it wants (or the programmer wants) takes a cursor from that array */
/* and shows it on screen with KMSDRM_ShowCursor(). */
/* KMSDRM_ShowCursor() simply shows or hides the cursor it receives: it does NOT */
/* mind if it's mouse->cur_cursor, etc. */
/* -If KMSDRM_ShowCursor() returns succesfully, that cursor becomes mouse->cur_cursor */
/* and mouse->cursor_shown is 1. */
/**************************************************************************************/
static SDL_Cursor *
KMSDRM_LEGACY_CreateDefaultCursor(void)
{
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
}
/* 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 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. */
void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
uint32_t A, R, G, B;
/* Component bytes extraction. */
A = (*pixel >> (3 << 3)) & 0xFF;
R = (*pixel >> (2 << 3)) & 0xFF;
G = (*pixel >> (1 << 3)) & 0xFF;
B = (*pixel >> (0 << 3)) & 0xFF;
/* Alpha pre-multiplication of each component. */
R = (float)A * ((float)R /255);
G = (float)A * ((float)G /255);
B = (float)A * ((float)B /255);
/* ARGB8888 pixel recomposition. */
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
}
/* 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 *
KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
KMSDRM_LEGACY_CursorData *curdata;
SDL_Cursor *cursor, *ret;
curdata = NULL;
ret = NULL;
/* All code below assumes ARGB8888 format for the cursor surface,
like other backends do. Also, the GBM BO pixels have to be
alpha-premultiplied, but the SDL surface we receive has
straight-alpha pixels, so we always have to convert. */
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->pitch == surface->w * 4);
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (!cursor) {
SDL_OutOfMemory();
goto cleanup;
}
curdata = (KMSDRM_LEGACY_CursorData *) SDL_calloc(1, sizeof(*curdata));
if (!curdata) {
SDL_OutOfMemory();
goto cleanup;
}
/* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */
curdata->hot_x = hot_x;
curdata->hot_y = hot_y;
curdata->w = surface->w;
curdata->h = surface->h;
curdata->buffer = NULL;
/* Configure the cursor buffer info.
This buffer has the original size of the cursor surface we are given. */
curdata->buffer_pitch = surface->pitch;
curdata->buffer_size = surface->pitch * surface->h;
curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size);
if (!curdata->buffer) {
SDL_OutOfMemory();
goto cleanup;
}
if (SDL_MUSTLOCK(surface)) {
if (SDL_LockSurface(surface) < 0) {
/* Could not lock surface */
goto cleanup;
}
}
/* Copy the surface pixels to the cursor buffer, for future use in ShowCursor() */
SDL_memcpy(curdata->buffer, surface->pixels, curdata->buffer_size);
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
cursor->driverdata = curdata;
ret = cursor;
cleanup:
if (ret == NULL) {
if (curdata) {
if (curdata->buffer) {
SDL_free(curdata->buffer);
}
SDL_free(curdata);
}
if (cursor) {
SDL_free(cursor);
}
}
return ret;
}
/* When we create a window, we have to test if we have to show the cursor,
and explicily do so if necessary.
This is because when we destroy a window, we take the cursor away from the
cursor plane, and destroy the cusror GBM BO. So we have to re-show it,
so to say. */
void
KMSDRM_LEGACY_InitCursor()
{
SDL_Mouse *mouse = NULL;
mouse = SDL_GetMouse();
if (!mouse) {
return;
}
if (!(mouse->cur_cursor)) {
return;
}
if (!(mouse->cursor_shown)) {
return;
}
KMSDRM_LEGACY_ShowCursor(mouse->cur_cursor);
}
/* Show the specified cursor, or hide if cursor is NULL or has no focus. */
static int
KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor)
{
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
SDL_Mouse *mouse;
KMSDRM_LEGACY_CursorData *curdata;
uint32_t bo_handle;
size_t bo_stride;
size_t bufsize;
uint32_t *ready_buffer = NULL;
uint32_t pixel;
int i,j;
int ret;
mouse = SDL_GetMouse();
if (!mouse) {
return SDL_SetError("No mouse.");
}
/*********************************************************/
/* Hide cursor if it's NULL or it has no focus(=winwow). */
/*********************************************************/
if (!cursor || !mouse->focus) {
/* 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_LEGACY_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 */
/************************************************/
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
if (!curdata || !dispdata->cursor_bo) {
return SDL_SetError("Cursor not initialized properly.");
}
/* Prepare a buffer we can dump to our GBM BO (different
size, alpha premultiplication...) */
bo_stride = KMSDRM_LEGACY_gbm_bo_get_stride(dispdata->cursor_bo);
bufsize = bo_stride * curdata->h;
ready_buffer = (uint32_t*)SDL_malloc(bufsize);
if (!ready_buffer) {
ret = SDL_OutOfMemory();
goto cleanup;
}
/* Clean the whole buffer we are preparing. */
SDL_memset(ready_buffer, 0x00, bo_stride * curdata->h);
/* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
pre-multiplying by alpha each pixel as we go. */
for (i = 0; i < curdata->h; i++) {
for (j = 0; j < curdata->w; j++) {
pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
legacy_alpha_premultiply_ARGB8888 (&pixel);
SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
}
}
/* Dump the cursor buffer to our GBM BO. */
if (KMSDRM_LEGACY_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) {
ret = SDL_SetError("Could not write to GBM cursor BO");
goto cleanup;
}
/* Put the GBM BO buffer on screen using the DRM interface. */
bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(dispdata->cursor_bo).u32;
if (curdata->hot_x == 0 && curdata->hot_y == 0) {
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id,
bo_handle, dispdata->cursor_w, dispdata->cursor_h);
} else {
ret = KMSDRM_LEGACY_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id,
bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y);
}
if (ret) {
ret = SDL_SetError("Failed to set DRM cursor.");
goto cleanup;
}
cleanup:
if (ready_buffer) {
SDL_free(ready_buffer);
}
return ret;
}
/* This is only for freeing the SDL_cursor.*/
static void
KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor)
{
KMSDRM_LEGACY_CursorData *curdata;
/* Even if the cursor is not ours, free it. */
if (cursor) {
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
/* Free cursor buffer */
if (curdata->buffer) {
SDL_free(curdata->buffer);
curdata->buffer = NULL;
}
/* Free cursor itself */
if (cursor->driverdata) {
SDL_free(cursor->driverdata);
}
SDL_free(cursor);
}
}
/* Warp the mouse to (x,y) */
static void
KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y)
{
/* Only one global/fullscreen window is supported */
KMSDRM_LEGACY_WarpMouseGlobal(x, y);
}
/* Warp the mouse to (x,y) */
static int
KMSDRM_LEGACY_WarpMouseGlobal(int x, int y)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
/* Update internal mouse position. */
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
/* And now update the cursor graphic position on screen. */
if (dispdata->cursor_bo) {
int ret, drm_fd;
drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(
KMSDRM_LEGACY_gbm_bo_get_device(dispdata->cursor_bo));
ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, x, y);
if (ret) {
SDL_SetError("drmModeMoveCursor() failed.");
}
return ret;
} else {
return SDL_SetError("Cursor not initialized properly.");
}
} else {
return SDL_SetError("No mouse or current cursor.");
}
return 0;
}
/* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
void
KMSDRM_LEGACY_DeinitMouse(_THIS)
{
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
/* Destroy the curso GBM BO. */
if (video_device && dispdata->cursor_bo) {
KMSDRM_LEGACY_gbm_bo_destroy(dispdata->cursor_bo);
dispdata->cursor_bo = NULL;
}
}
/* Create cursor BO. */
void
KMSDRM_LEGACY_InitMouse(_THIS)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = KMSDRM_LEGACY_CreateCursor;
mouse->ShowCursor = KMSDRM_LEGACY_ShowCursor;
mouse->MoveCursor = KMSDRM_LEGACY_MoveCursor;
mouse->FreeCursor = KMSDRM_LEGACY_FreeCursor;
mouse->WarpMouse = KMSDRM_LEGACY_WarpMouse;
mouse->WarpMouseGlobal = KMSDRM_LEGACY_WarpMouseGlobal;
/************************************************/
/* Create the cursor GBM BO, if we haven't yet. */
/************************************************/
if (!dispdata->cursor_bo) {
if (!KMSDRM_LEGACY_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");
return;
}
if (KMSDRM_LEGACY_drmGetCap(viddata->drm_fd,
DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) ||
KMSDRM_LEGACY_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT,
&dispdata->cursor_h))
{
SDL_SetError("Could not get the recommended GBM cursor size");
goto cleanup;
}
if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) {
SDL_SetError("Could not get an usable GBM cursor size");
goto cleanup;
}
dispdata->cursor_bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm_dev,
dispdata->cursor_w, dispdata->cursor_h,
GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR);
if (!dispdata->cursor_bo) {
SDL_SetError("Could not create GBM cursor BO");
goto cleanup;
}
}
/* SDL expects to set the default cursor on screen when we init the mouse,
but since we have moved the KMSDRM_InitMouse() call to KMSDRM_CreateWindow(),
we end up calling KMSDRM_InitMouse() every time we create a window, so we
have to prevent this from being done every time a new window is created.
If we don't, new default cursors would stack up on mouse->cursors and SDL
would have to hide and delete them at quit, not to mention the memory leak... */
if(dispdata->set_default_cursor_pending) {
SDL_SetDefaultCursor(KMSDRM_LEGACY_CreateDefaultCursor());
dispdata->set_default_cursor_pending = SDL_FALSE;
}
return;
cleanup:
if (dispdata->cursor_bo) {
KMSDRM_LEGACY_gbm_bo_destroy(dispdata->cursor_bo);
dispdata->cursor_bo = NULL;
}
}
void
KMSDRM_LEGACY_QuitMouse(_THIS)
{
/* TODO: ? */
}
/* This is called when a mouse motion event occurs */
static void
KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
int drm_fd, ret;
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
That's why we move the cursor graphic ONLY. */
if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(dispdata->cursor_bo));
ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, dispdata->crtc->crtc_id, mouse->x, mouse->y);
if (ret) {
SDL_SetError("drmModeMoveCursor() failed.");
}
}
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,54 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_KMSDRM_LEGACY_mouse_h_
#define SDL_KMSDRM_LEGACY_mouse_h_
#include <gbm.h>
#define MAX_CURSOR_W 512
#define MAX_CURSOR_H 512
typedef struct _KMSDRM_LEGACY_CursorData
{
int hot_x, hot_y;
int w, h;
/* 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().*/
uint32_t *buffer;
size_t buffer_size;
size_t buffer_pitch;
} KMSDRM_LEGACY_CursorData;
extern void KMSDRM_LEGACY_InitMouse(_THIS);
extern void KMSDRM_LEGACY_DeinitMouse(_THIS);
extern void KMSDRM_LEGACY_QuitMouse(_THIS);
extern void KMSDRM_LEGACY_InitCursor();
#endif /* SDL_KMSDRM_LEGACY_mouse_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,166 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_log.h"
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_opengles.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#ifndef EGL_PLATFORM_GBM_MESA
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif
/* EGL implementation of SDL OpenGL support */
void
KMSDRM_LEGACY_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor)
{
/* if SDL was _also_ built with the Raspberry Pi driver (so we're
definitely a Pi device), default to GLES2. */
#if SDL_VIDEO_DRIVER_RPI
*mask = SDL_GL_CONTEXT_PROFILE_ES;
*major = 2;
*minor = 0;
#endif
}
int
KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path) {
/* Just pretend you do this here, but don't do it until KMSDRM_CreateWindow(),
where we do the same library load we would normally do here.
because this gets called by SDL_CreateWindow() before KMSDR_CreateWindow(),
so gbm dev isn't yet created when this is called, AND we can't alter the
call order in SDL_CreateWindow(). */
#if 0
NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev;
return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA);
#endif
return 0;
}
void
KMSDRM_LEGACY_GLES_UnloadLibrary(_THIS) {
/* As with KMSDRM_GLES_LoadLibrary(), we define our own "dummy" unloading function
so we manually unload the library whenever we want. */
}
SDL_EGL_CreateContext_impl(KMSDRM_LEGACY)
int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval) {
if (!_this->egl_data) {
return SDL_SetError("EGL not initialized");
}
if (interval == 0 || interval == 1) {
_this->egl_data->egl_swapinterval = interval;
} else {
return SDL_SetError("Only swap intervals of 0 or 1 are supported");
}
return 0;
}
int
KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window) {
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
KMSDRM_LEGACY_FBInfo *fb_info;
int ret, timeout;
/* Recreate the GBM / EGL surfaces if the display mode has changed */
if (windata->egl_surface_dirty) {
KMSDRM_LEGACY_CreateSurfaces(_this, window);
}
/* 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;
}
if (!KMSDRM_LEGACY_WaitPageFlip(_this, windata, timeout)) {
return 0;
}
/* Release the previous front buffer */
if (windata->bo) {
KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->bo);
windata->bo = NULL;
}
windata->bo = windata->next_bo;
/* 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 next front buffer so it can't be allocated as a back buffer */
windata->next_bo = KMSDRM_LEGACY_gbm_surface_lock_front_buffer(windata->gs);
if (!windata->next_bo) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
return 0;
}
/* Get the fb_info for the next front buffer. */
fb_info = KMSDRM_LEGACY_FBFromBO(_this, windata->next_bo);
if (!fb_info) {
return 0;
}
/* Issue pageflip on the next front buffer.
The pageflip will be done during the next vblank. */
ret = KMSDRM_LEGACY_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id,
fb_info->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip);
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);
}
}
/* 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_LEGACY_DOUBLE_BUFFER=1 <program_name>"
to enable this. */
if (_this->egl_data->egl_swapinterval == 1 && windata->double_buffer) {
KMSDRM_LEGACY_WaitPageFlip(_this, windata, -1);
}
return 0;
}
SDL_EGL_MakeCurrent_impl(KMSDRM_LEGACY)
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,48 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_kmsdrmopengles_h_
#define SDL_kmsdrmopengles_h_
#if SDL_VIDEO_DRIVER_KMSDRM
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
/* OpenGLES functions */
#define KMSDRM_LEGACY_GLES_GetAttribute SDL_EGL_GetAttribute
#define KMSDRM_LEGACY_GLES_GetProcAddress SDL_EGL_GetProcAddress
#define KMSDRM_LEGACY_GLES_DeleteContext SDL_EGL_DeleteContext
#define KMSDRM_LEGACY_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
extern void KMSDRM_LEGACY_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor);
extern int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval);
extern int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path);
extern SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window);
extern int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window);
extern int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
#endif /* SDL_kmsdrmopengles_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,118 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* *INDENT-OFF* */
#ifndef SDL_KMSDRM_LEGACY_MODULE
#define SDL_KMSDRM_LEGACY_MODULE(modname)
#endif
#ifndef SDL_KMSDRM_LEGACY_SYM
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params)
#endif
#ifndef SDL_KMSDRM_LEGACY_SYM_CONST
#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name)
#endif
SDL_KMSDRM_LEGACY_MODULE(LIBDRM)
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
SDL_KMSDRM_LEGACY_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value))
SDL_KMSDRM_LEGACY_SYM(drmModeResPtr,drmModeGetResources,(int fd))
SDL_KMSDRM_LEGACY_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id))
SDL_KMSDRM_LEGACY_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
SDL_KMSDRM_LEGACY_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
SDL_KMSDRM_LEGACY_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
SDL_KMSDRM_LEGACY_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_LEGACY_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
uint32_t width, uint32_t height))
SDL_KMSDRM_LEGACY_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_LEGACY_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
SDL_KMSDRM_LEGACY_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
SDL_KMSDRM_LEGACY_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
SDL_KMSDRM_LEGACY_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
SDL_KMSDRM_LEGACY_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data))
/* Planes stuff. */
SDL_KMSDRM_LEGACY_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value))
SDL_KMSDRM_LEGACY_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
SDL_KMSDRM_LEGACY_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
SDL_KMSDRM_LEGACY_SYM(drmModeObjectPropertiesPtr,drmModeObjectGetProperties,(int fd,uint32_t object_id,uint32_t object_type))
SDL_KMSDRM_LEGACY_SYM(drmModePropertyPtr,drmModeGetProperty,(int fd, uint32_t propertyId))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr))
SDL_KMSDRM_LEGACY_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_LEGACY_MODULE(GBM)
SDL_KMSDRM_LEGACY_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
SDL_KMSDRM_LEGACY_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm,
uint32_t format, uint32_t usage))
SDL_KMSDRM_LEGACY_SYM(void,gbm_device_destroy,(struct gbm_device *gbm))
SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_create_device,(int fd))
SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data,
void (*destroy_user_data)(struct gbm_bo *, void *)))
SDL_KMSDRM_LEGACY_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t usage))
SDL_KMSDRM_LEGACY_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags))
SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
#undef SDL_KMSDRM_LEGACY_MODULE
#undef SDL_KMSDRM_LEGACY_SYM
#undef SDL_KMSDRM_LEGACY_SYM_CONST
/* *INDENT-ON* */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load Diff

View File

@ -1,162 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef __SDL_KMSDRM_LEGACYVIDEO_H__
#define __SDL_KMSDRM_LEGACYVIDEO_H__
#include "../SDL_sysvideo.h"
#include <fcntl.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#include <EGL/egl.h>
typedef struct SDL_VideoData
{
int devindex; /* device index that was passed on creation */
int drm_fd; /* DRM file desc */
char devpath[32]; /* DRM dev path. */
struct gbm_device *gbm_dev;
SDL_bool video_init; /* Has VideoInit succeeded? */
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;
typedef struct SDL_DisplayModeData
{
int mode_index;
} SDL_DisplayModeData;
typedef struct SDL_DisplayData
{
drmModeConnector *connector;
drmModeCrtc *crtc;
drmModeModeInfo mode;
drmModeModeInfo original_mode;
drmModeCrtc *saved_crtc; /* CRTC to restore on quit */
SDL_bool gbm_init;
/* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
because setting/unsetting up these is done on window creation/destruction,
where we may not have an SDL_Cursor at all (so no SDL_Cursor driverdata).
There's only one cursor GBM BO because we only support one cursor. */
struct gbm_bo *cursor_bo;
uint64_t cursor_w, cursor_h;
SDL_bool modeset_pending;
SDL_bool set_default_cursor_pending;
} SDL_DisplayData;
typedef struct SDL_WindowData
{
SDL_VideoData *viddata;
/* SDL internals expect EGL surface to be here, and in KMSDRM the GBM surface is
what supports the EGL surface on the driver side, so all these surfaces and buffers
are expected to be here, in the struct pointed by SDL_Window driverdata pointer:
this one. So don't try to move these to dispdata! */
struct gbm_surface *gs;
struct gbm_bo *bo;
struct gbm_bo *next_bo;
SDL_bool waiting_for_flip;
SDL_bool double_buffer;
int egl_surface_dirty;
EGLSurface egl_surface;
/* For scaling and AR correction. */
int32_t src_w;
int32_t src_h;
int32_t output_w;
int32_t output_h;
int32_t output_x;
} SDL_WindowData;
typedef struct KMSDRM_LEGACY_FBInfo
{
int drm_fd; /* DRM file desc */
uint32_t fb_id; /* DRM framebuffer ID */
} KMSDRM_LEGACY_FBInfo;
/* Helper functions */
int KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window);
KMSDRM_LEGACY_FBInfo *KMSDRM_LEGACY_FBFromBO(_THIS, struct gbm_bo *bo);
SDL_bool KMSDRM_LEGACY_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout);
/****************************************************************************/
/* SDL_VideoDevice functions declaration */
/****************************************************************************/
/* Display and window functions */
int KMSDRM_LEGACY_VideoInit(_THIS);
void KMSDRM_LEGACY_VideoQuit(_THIS);
void KMSDRM_LEGACY_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
int KMSDRM_LEGACY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
int KMSDRM_LEGACY_CreateWindow(_THIS, SDL_Window * window);
int KMSDRM_LEGACY_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
void KMSDRM_LEGACY_SetWindowTitle(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
void KMSDRM_LEGACY_SetWindowPosition(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowSize(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen);
void KMSDRM_LEGACY_ShowWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_HideWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_RaiseWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_MaximizeWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_MinimizeWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_RestoreWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
void KMSDRM_LEGACY_DestroyWindow(_THIS, SDL_Window * window);
/* Window manager function */
SDL_bool KMSDRM_LEGACY_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
/* OpenGL/OpenGL ES functions */
int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path);
void *KMSDRM_LEGACY_GLES_GetProcAddress(_THIS, const char *proc);
void KMSDRM_LEGACY_GLES_UnloadLibrary(_THIS);
SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window);
int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval);
int KMSDRM_LEGACY_GLES_GetSwapInterval(_THIS);
int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_GLES_DeleteContext(_THIS, SDL_GLContext context);
#endif /* __SDL_KMSDRM_LEGACYVIDEO_H__ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,422 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* @author Manuel Alfayate Corchere <redwindwanderer@gmail.com>.
* Based on Jacob Lifshay's SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_kmsdrm_legacy_vulkan.h"
#include "SDL_syswm.h"
#include "sys/ioctl.h"
#if defined(__OpenBSD__)
#define DEFAULT_VULKAN "libvulkan.so"
#else
#define DEFAULT_VULKAN "libvulkan.so.1"
#endif
int KMSDRM_LEGACY_Vulkan_LoadLibrary(_THIS, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 i, extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasDisplayExtension = SDL_FALSE;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
if(_this->vulkan_config.loader_handle)
return SDL_SetError("Vulkan already loaded");
/* Load the Vulkan library */
if(!path)
path = SDL_getenv("SDL_VULKAN_LIBRARY");
if(!path)
path = DEFAULT_VULKAN;
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
if(!_this->vulkan_config.loader_handle)
return -1;
SDL_strlcpy(_this->vulkan_config.loader_path, path,
SDL_arraysize(_this->vulkan_config.loader_path));
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
if(!vkGetInstanceProcAddr)
goto fail;
_this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
_this->vulkan_config.vkEnumerateInstanceExtensionProperties =
(void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
goto fail;
extensions = SDL_Vulkan_CreateInstanceExtensionsList(
(PFN_vkEnumerateInstanceExtensionProperties)
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
&extensionCount);
if(!extensions)
goto fail;
for(i = 0; i < extensionCount; i++)
{
if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasSurfaceExtension = SDL_TRUE;
else if(SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0)
hasDisplayExtension = SDL_TRUE;
}
SDL_free(extensions);
if(!hasSurfaceExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_SURFACE_EXTENSION_NAME " extension");
goto fail;
}
else if(!hasDisplayExtension)
{
SDL_SetError("Installed Vulkan doesn't implement the "
VK_KHR_DISPLAY_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void KMSDRM_LEGACY_Vulkan_UnloadLibrary(_THIS)
{
if(_this->vulkan_config.loader_handle)
{
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
/*********************************************************************/
/* Here we can put whatever Vulkan extensions we want to be enabled */
/* at instance creation, which is done in the programs, not in SDL. */
/* So: programs call SDL_Vulkan_GetInstanceExtensions() and here */
/* we put the extensions specific to this backend so the programs */
/* get a list with the extension we want, so they can include that */
/* list in the ppEnabledExtensionNames and EnabledExtensionCount */
/* members of the VkInstanceCreateInfo struct passed to */
/* vkCreateInstance(). */
/*********************************************************************/
SDL_bool KMSDRM_LEGACY_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names)
{
static const char *const extensionsForKMSDRM[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME
};
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
return SDL_Vulkan_GetInstanceExtensions_Helper(
count, names, SDL_arraysize(extensionsForKMSDRM),
extensionsForKMSDRM);
}
void KMSDRM_LEGACY_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
if (w) {
*w = window->w;
}
if (h) {
*h = window->h;
}
}
/***********************************************************************/
/* First thing to know is that we don't call vkCreateInstance() here. */
/* Instead, programs using SDL and Vulkan create their Vulkan instance */
/* and we get it here, ready to use. */
/* Extensions specific for this platform are activated in */
/* KMSDRM_LEGACY_Vulkan_GetInstanceExtensions(), like we do with */
/* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */
/***********************************************************************/
SDL_bool KMSDRM_LEGACY_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
VkPhysicalDevice gpu;
uint32_t gpu_count;
uint32_t display_count;
uint32_t mode_count;
uint32_t plane_count;
VkPhysicalDevice *physical_devices = NULL;
VkDisplayPropertiesKHR *displays_props = NULL;
VkDisplayModePropertiesKHR *modes_props = NULL;
VkDisplayPlanePropertiesKHR *planes_props = NULL;
VkDisplayModeCreateInfoKHR display_mode_create_info;
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
VkExtent2D image_size;
VkDisplayModeKHR *display_mode = NULL;
VkDisplayModePropertiesKHR display_mode_props = {0};
VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0};
VkResult result;
SDL_bool ret = SDL_FALSE;
SDL_bool mode_found = SDL_FALSE;
/* We don't receive a display index in KMSDRM_LEGACY_CreateDevice(), only
a device index, which determines the GPU to use, but not the output.
So we simply use the first connected output (ie, the first connected
video output) for now.
In other words, change this index to select a different output. Easy! */
int display_index = 0;
int i;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
/* Get the function pointers for the functions we will use. */
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR =
(PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr(
instance, "vkCreateDisplayPlaneSurfaceKHR");
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices =
(PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(
instance, "vkEnumeratePhysicalDevices");
PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR =
(PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr(
instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR =
(PFN_vkGetDisplayModePropertiesKHR)vkGetInstanceProcAddr(
instance, "vkGetDisplayModePropertiesKHR");
PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR =
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
/*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
instance, "vkGetDisplayPlaneCapabilitiesKHR");
*/
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
instance, "vkCreateDisplayModeKHR");
if(!_this->vulkan_config.loader_handle)
{
SDL_SetError("Vulkan is not loaded");
goto clean;
}
/*************************************/
/* Block for vulkan surface creation */
/*************************************/
/****************************************************************/
/* If we got vkCreateDisplayPlaneSurfaceKHR() pointer, it means */
/* that the VK_KHR_Display extension is active on the instance. */
/* That's the central extension we need for x-less VK! */
/****************************************************************/
if(!vkCreateDisplayPlaneSurfaceKHR)
{
SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
goto clean;
}
/* Get the physical device count. */
vkEnumeratePhysicalDevices(instance, &gpu_count, NULL);
if (gpu_count == 0) {
SDL_SetError("Vulkan can't find physical devices (gpus).");
goto clean;
}
/* Get the physical devices. */
physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count);
vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
/* A GPU (or physical_device, in vkcube terms) is a GPU. A machine with more
than one video output doen't need to have more than one GPU, like the Pi4
which has 1 GPU and 2 video outputs.
We grab the GPU/physical_device with the index we got in KMSDR_CreateDevice(). */
gpu = physical_devices[viddata->devindex];
/* A display is a video output. 1 GPU can have N displays.
Vulkan only counts the connected displays.
Get the display count of the GPU. */
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, NULL);
if (display_count == 0) {
SDL_SetError("Vulkan can't find any displays.");
goto clean;
}
/* Get the props of the displays of the physical device. */
displays_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*displays_props));
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
&display_count,
displays_props);
/* Get the videomode count for the first display. */
vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display,
&mode_count, NULL);
if (mode_count == 0) {
SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0,
displays_props[display_index].displayName);
goto clean;
}
/* Get the props of the videomodes for the first display. */
modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display,
&mode_count, modes_props);
/* Get the planes count of the physical device. */
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
if (plane_count == 0) {
SDL_SetError("Vulkan can't find any planes.");
goto clean;
}
/* Get the props of the planes for the physical device. */
planes_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);
/* Get a video mode equal or smaller than the window size. REMEMBER:
We have to get a small enough videomode for the window size,
because videomode determines how big the scanout region is and we can't
scanout a region bigger than the window (we would be reading past the
buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
for (i = 0; i < mode_count; i++) {
if (modes_props[i].parameters.visibleRegion.width <= window->w &&
modes_props[i].parameters.visibleRegion.height <= window->h)
{
display_mode_props = modes_props[i];
mode_found = SDL_TRUE;
break;
}
}
if (mode_found &&
display_mode_props.parameters.visibleRegion.width > 0 &&
display_mode_props.parameters.visibleRegion.height > 0 ) {
/* Found a suitable mode among the predefined ones. Use that. */
display_mode = &(display_mode_props.displayMode);
} else {
/* Can't find a suitable mode among the predefined ones, so try to create our own. */
new_mode_parameters.visibleRegion.width = window->w;
new_mode_parameters.visibleRegion.height = window->h;
new_mode_parameters.refreshRate = 60000; /* Always use 60Hz for now. */
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
display_mode_create_info.parameters = new_mode_parameters;
result = vkCreateDisplayModeKHR(gpu,
displays_props[display_index].display,
&display_mode_create_info,
NULL, display_mode);
if (result != VK_SUCCESS) {
SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode.");
goto clean;
}
}
/* Just in case we get here without a display_mode. */
if (!display_mode) {
SDL_SetError("Vulkan couldn't get a display mode.");
goto clean;
}
/********************************************/
/* Let's finally create the Vulkan surface! */
/********************************************/
image_size.width = window->w;
image_size.height = window->h;
display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
display_plane_surface_create_info.displayMode = *display_mode;
/* For now, simply use the first plane. */
display_plane_surface_create_info.planeIndex = 0;
display_plane_surface_create_info.imageExtent = image_size;
result = vkCreateDisplayPlaneSurfaceKHR(instance,
&display_plane_surface_create_info,
NULL,
surface);
if(result != VK_SUCCESS)
{
SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
goto clean;
}
ret = SDL_TRUE;
clean:
if (physical_devices)
SDL_free (physical_devices);
if (displays_props)
SDL_free (displays_props);
if (planes_props)
SDL_free (planes_props);
if (modes_props)
SDL_free (modes_props);
return ret;
}
#endif
/* vim: set ts=4 sw=4 expandtab: */

View File

@ -1,53 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* @author Manuel Alfayate Corchere <redwindwanderer@gmail.com>.
* Based on Jacob Lifshay's SDL_x11vulkan.c.
*/
#include "../../SDL_internal.h"
#ifndef SDL_kmsdrm_legacy_vulkan_h_
#define SDL_kmsdrm_legacy_vulkan_h_
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_KMSDRM
int KMSDRM_LEGACY_Vulkan_LoadLibrary(_THIS, const char *path);
void KMSDRM_LEGACY_Vulkan_UnloadLibrary(_THIS);
SDL_bool KMSDRM_LEGACY_Vulkan_GetInstanceExtensions(_THIS,
SDL_Window *window,
unsigned *count,
const char **names);
void KMSDRM_LEGACY_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
SDL_bool KMSDRM_LEGACY_Vulkan_CreateSurface(_THIS,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* SDL_kmsdrm_legacy_vulkan_h_ */
/* vi: set ts=4 sw=4 expandtab: */