mirror of https://github.com/encounter/SDL.git
KMSDRM_LEGACY is no longer legacy
This commit is contained in:
parent
29888bd69a
commit
8746788fea
|
@ -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: */
|
|
|
@ -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: */
|
|
|
@ -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 */
|
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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: */
|
|
|
@ -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: */
|
|
|
@ -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: */
|
|
|
@ -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: */
|
|
|
@ -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
|
@ -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: */
|
|
|
@ -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: */
|
|
|
@ -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: */
|
|
Loading…
Reference in New Issue