mirror of https://github.com/encounter/SDL.git
[KMS/DRM] Prevent creating another default cursor everytime a window is created. Other fixes and cleanups.
This commit is contained in:
parent
7032539785
commit
cef1bd0639
|
@ -40,6 +40,21 @@ static void KMSDRM_FreeCursor(SDL_Cursor * cursor);
|
||||||
static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y);
|
static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y);
|
||||||
static int KMSDRM_WarpMouseGlobal(int x, int y);
|
static int KMSDRM_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. */
|
||||||
|
/**************************************************************************************/
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
/* Atomic helper functions block. */
|
/* Atomic helper functions block. */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
@ -98,8 +113,9 @@ KMSDRM_CreateDefaultCursor(void)
|
||||||
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
|
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This simply gets the cursor soft-buffer ready. We don't copy it to a GBO BO until ShowCursor()
|
/* This simply gets the cursor soft-buffer ready. We don't copy it to a GBO BO
|
||||||
because the cusor GBM BO (living in dispata) is destroyed and recreated when we recreate windows, etc. */
|
until ShowCursor() because the cusor GBM BO (living in dispata) is destroyed
|
||||||
|
and recreated when we recreate windows, etc. */
|
||||||
static SDL_Cursor *
|
static SDL_Cursor *
|
||||||
KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||||
{
|
{
|
||||||
|
@ -204,20 +220,16 @@ KMSDRM_InitCursor()
|
||||||
KMSDRM_ShowCursor(mouse->cur_cursor);
|
KMSDRM_ShowCursor(mouse->cur_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show the specified cursor, or hide if cursor is NULL.
|
/* Show the specified cursor, or hide if cursor is NULL or has no focus. */
|
||||||
cur_cursor is the current cursor, and cursor is the new cursor.
|
|
||||||
A cursor is displayed on a display, so we have to add a pointer to dispdata
|
|
||||||
to the driverdata
|
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
||||||
//SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
//SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata);
|
||||||
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
SDL_Mouse *mouse;
|
SDL_Mouse *mouse;
|
||||||
KMSDRM_CursorData *curdata;
|
KMSDRM_CursorData *curdata;
|
||||||
SDL_VideoDisplay *display = NULL;
|
|
||||||
SDL_DisplayData *dispdata = NULL;
|
|
||||||
KMSDRM_FBInfo *fb;
|
KMSDRM_FBInfo *fb;
|
||||||
KMSDRM_PlaneInfo info = {0};
|
KMSDRM_PlaneInfo info = {0};
|
||||||
|
|
||||||
|
@ -234,41 +246,28 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
return SDL_SetError("No mouse.");
|
return SDL_SetError("No mouse.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse->focus) {
|
/*********************************************************/
|
||||||
display = SDL_GetDisplayForWindow(mouse->focus);
|
/* Hide cursor if it's NULL or it has no focus(=winwow). */
|
||||||
if (display) {
|
/*********************************************************/
|
||||||
dispdata = (SDL_DisplayData*) display->driverdata;
|
if (!cursor || !mouse->focus) {
|
||||||
}
|
if (dispdata->cursor_plane) {
|
||||||
}
|
/* Hide the drm cursor with no more considerations because
|
||||||
|
SDL_VideoQuit() takes us here after disabling the mouse
|
||||||
/**********************************/
|
so there is no mouse->cur_cursor by now. */
|
||||||
/* if cursor == NULL, HIDE cursor */
|
|
||||||
/**********************************/
|
|
||||||
if (!cursor) {
|
|
||||||
/* Hide CURRENT cursor, a cursor that is already on screen
|
|
||||||
and SDL is stored in mouse->cur_cursor. */
|
|
||||||
if (mouse->cur_cursor && mouse->cur_cursor->driverdata) {
|
|
||||||
if (dispdata && dispdata->cursor_plane) {
|
|
||||||
info.plane = dispdata->cursor_plane;
|
info.plane = dispdata->cursor_plane;
|
||||||
/* The rest of the members are zeroed. */
|
/* The rest of the members are zeroed, so this takes away the cursor
|
||||||
|
from the cursor plane. */
|
||||||
drm_atomic_set_plane_props(&info);
|
drm_atomic_set_plane_props(&info);
|
||||||
if (drm_atomic_commit(display->device, SDL_TRUE, SDL_FALSE))
|
if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
|
||||||
return SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
|
ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return SDL_SetError("Couldn't find cursor to hide.");
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************/
|
/************************************************/
|
||||||
/* If cursor != NULL, DO show cursor on display */
|
/* If cursor != NULL, DO show cursor on display */
|
||||||
/************************************************/
|
/************************************************/
|
||||||
if (!display) {
|
|
||||||
return SDL_SetError("Could not get display for mouse.");
|
|
||||||
}
|
|
||||||
if (!dispdata) {
|
|
||||||
return SDL_SetError("Could not get display driverdata.");
|
|
||||||
}
|
|
||||||
if (!dispdata->cursor_plane) {
|
if (!dispdata->cursor_plane) {
|
||||||
return SDL_SetError("Hardware cursor plane not initialized.");
|
return SDL_SetError("Hardware cursor plane not initialized.");
|
||||||
}
|
}
|
||||||
|
@ -279,7 +278,8 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
return SDL_SetError("Cursor not initialized properly.");
|
return SDL_SetError("Cursor not initialized properly.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare a buffer we can dump to our GBM BO (different size, alpha premultiplication...) */
|
/* Prepare a buffer we can dump to our GBM BO (different
|
||||||
|
size, alpha premultiplication...) */
|
||||||
bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
|
||||||
bufsize = bo_stride * curdata->h;
|
bufsize = bo_stride * curdata->h;
|
||||||
|
|
||||||
|
@ -315,8 +315,8 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
info.plane = dispdata->cursor_plane;
|
info.plane = dispdata->cursor_plane;
|
||||||
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
info.fb_id = fb->fb_id;
|
info.fb_id = fb->fb_id;
|
||||||
info.src_w = curdata->w;
|
info.src_w = dispdata->cursor_w;
|
||||||
info.src_h = curdata->h;
|
info.src_h = dispdata->cursor_h;
|
||||||
info.crtc_x = mouse->x - curdata->hot_x;
|
info.crtc_x = mouse->x - curdata->hot_x;
|
||||||
info.crtc_y = mouse->y - curdata->hot_y;
|
info.crtc_y = mouse->y - curdata->hot_y;
|
||||||
info.crtc_w = curdata->w;
|
info.crtc_w = curdata->w;
|
||||||
|
@ -324,7 +324,7 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
|
|
||||||
drm_atomic_set_plane_props(&info);
|
drm_atomic_set_plane_props(&info);
|
||||||
|
|
||||||
if (drm_atomic_commit(display->device, SDL_TRUE, SDL_FALSE)) {
|
if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
|
||||||
ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
|
ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -339,8 +339,7 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have destroyed the cursor by now, in KMSDRM_DestroyCursor.
|
/* This is only for freeing the SDL_cursor.*/
|
||||||
This is only for freeing the SDL_cursor.*/
|
|
||||||
static void
|
static void
|
||||||
KMSDRM_FreeCursor(SDL_Cursor * cursor)
|
KMSDRM_FreeCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
|
@ -398,13 +397,40 @@ KMSDRM_WarpMouseGlobal(int x, int y)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
|
||||||
|
void
|
||||||
|
KMSDRM_DeinitMouse(_THIS)
|
||||||
|
{
|
||||||
|
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
||||||
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
KMSDRM_PlaneInfo info = {0};
|
||||||
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
|
|
||||||
|
/* 1- Destroy the curso GBM BO. */
|
||||||
|
if (video_device && dispdata->cursor_bo) {
|
||||||
|
/* Unsethe the cursor BO from the cursor plane.
|
||||||
|
(The other members of the plane info are zeroed). */
|
||||||
|
info.plane = dispdata->cursor_plane;
|
||||||
|
drm_atomic_set_plane_props(&info);
|
||||||
|
/* Wait until the cursor is unset from the cursor plane
|
||||||
|
before destroying it's BO. */
|
||||||
|
if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
|
||||||
|
SDL_SetError("Failed atomic commit in KMSDRM_DenitMouse.");
|
||||||
|
}
|
||||||
|
/* ..and finally destroy the cursor DRM BO! */
|
||||||
|
KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
||||||
|
dispdata->cursor_bo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2- Free the cursor plane, on which the cursor was being shown. */
|
||||||
|
if (dispdata->cursor_plane) {
|
||||||
|
free_plane(&dispdata->cursor_plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
KMSDRM_InitMouse(_THIS)
|
KMSDRM_InitMouse(_THIS)
|
||||||
{
|
{
|
||||||
/* FIXME: Using UDEV it should be possible to scan all mice
|
|
||||||
* but there's no point in doing so as there's no multimice support...yet!
|
|
||||||
*/
|
|
||||||
|
|
||||||
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
@ -420,7 +446,7 @@ KMSDRM_InitMouse(_THIS)
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* REMEMBER TO BE SURE OF UNDOING ALL THESE STEPS PROPERLY BEFORE CALLING */
|
/* REMEMBER TO BE SURE OF UNDOING ALL THESE STEPS PROPERLY BEFORE CALLING */
|
||||||
/* gbm_device_destroy, OR YOU WON'T BE ABLE TO CREATE A NEW ONE (ERROR -13 */
|
/* gbm_device_destroy, OR YOU WON'T BE ABLE TO CREATE A NEW ONE (ERROR -13 */
|
||||||
/* ON gbm_create_device). */
|
/* on gbm_create_device). */
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
/* 1- Init cursor plane, if we haven't yet. */
|
/* 1- Init cursor plane, if we haven't yet. */
|
||||||
|
@ -460,8 +486,16 @@ KMSDRM_InitMouse(_THIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDL expects to set the default cursor on screen when we init the mouse. */
|
/* 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_CreateDefaultCursor());
|
SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
|
||||||
|
dispdata->set_default_cursor_pending = SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -472,40 +506,6 @@ cleanup:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
KMSDRM_DeinitMouse(_THIS)
|
|
||||||
{
|
|
||||||
SDL_VideoDevice *video_device = SDL_GetVideoDevice();
|
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
KMSDRM_PlaneInfo info = {0};
|
|
||||||
|
|
||||||
/*******************************************/
|
|
||||||
/* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
|
|
||||||
/*******************************************/
|
|
||||||
|
|
||||||
/* 1- Destroy the curso GBM BO. */
|
|
||||||
if (video_device && dispdata->cursor_bo) {
|
|
||||||
/* Unsethe the cursor BO from the cursor plane.
|
|
||||||
(The other members of the plane info are zeroed). */
|
|
||||||
info.plane = dispdata->cursor_plane;
|
|
||||||
drm_atomic_set_plane_props(&info);
|
|
||||||
/* Wait until the cursor is unset from the cursor plane
|
|
||||||
before destroying it's BO. */
|
|
||||||
if (drm_atomic_commit(video_device, SDL_TRUE, SDL_FALSE)) {
|
|
||||||
SDL_SetError("Failed atomic commit in KMSDRM_DenitMouse.");
|
|
||||||
}
|
|
||||||
/* ..and finally destroy the cursor DRM BO! */
|
|
||||||
KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
|
|
||||||
dispdata->cursor_bo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2- Free the cursor plane, on which the cursor was being shown. */
|
|
||||||
if (dispdata->cursor_plane) {
|
|
||||||
free_plane(&dispdata->cursor_plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is called when a mouse motion event occurs */
|
/* This is called when a mouse motion event occurs */
|
||||||
static void
|
static void
|
||||||
KMSDRM_MoveCursor(SDL_Cursor * cursor)
|
KMSDRM_MoveCursor(SDL_Cursor * cursor)
|
||||||
|
|
|
@ -287,7 +287,8 @@ KMSDRM_GLES_SwapWindowDoubleBuffered(_THIS, SDL_Window * window)
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
/* In double-buffer mode, atomic_commit will always be synchronous/blocking (ie: */
|
/* In double-buffer mode, atomic_commit will always be synchronous/blocking (ie: */
|
||||||
/* won't return until the requested changes are really done). */ /* Also, there's no need to fence KMS or the GPU, because we won't be entering */
|
/* won't return until the requested changes are really done). */
|
||||||
|
/* Also, there's no need to fence KMS or the GPU, because we won't be entering */
|
||||||
/* game loop again (hence not building or executing a new cmdstring) until */
|
/* game loop again (hence not building or executing a new cmdstring) until */
|
||||||
/* pageflip is done, so we don't need to protect the KMS/GPU access to the buffer.*/
|
/* pageflip is done, so we don't need to protect the KMS/GPU access to the buffer.*/
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
|
|
||||||
#define KMSDRM_DRI_PATH "/dev/dri/"
|
#define KMSDRM_DRI_PATH "/dev/dri/"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int set_client_caps (int fd)
|
static int set_client_caps (int fd)
|
||||||
{
|
{
|
||||||
if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
|
if (KMSDRM_drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
|
||||||
|
@ -164,161 +166,6 @@ get_driindex(void)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
/**********************/
|
|
||||||
/* DUMB BUFFER Block. */
|
|
||||||
/**********************/
|
|
||||||
|
|
||||||
/* Create a dumb buffer, mmap the dumb buffer and fill it with pixels, */
|
|
||||||
/* then create a KMS framebuffer wrapping the dumb buffer. */
|
|
||||||
static dumb_buffer *KMSDRM_CreateDumbBuffer(_THIS)
|
|
||||||
{
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
|
|
||||||
struct drm_mode_create_dumb create;
|
|
||||||
struct drm_mode_map_dumb map;
|
|
||||||
struct drm_mode_destroy_dumb destroy;
|
|
||||||
|
|
||||||
dumb_buffer *ret = SDL_calloc(1, sizeof(*ret));
|
|
||||||
if (!ret) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The create ioctl uses the combination of depth and bpp to infer
|
|
||||||
* a format; 24/32 refers to DRM_FORMAT_XRGB8888 as defined in
|
|
||||||
* the drm_fourcc.h header. These arguments are the same as given
|
|
||||||
* to drmModeAddFB, which has since been superseded by
|
|
||||||
* drmModeAddFB2 as the latter takes an explicit format token.
|
|
||||||
*
|
|
||||||
* We only specify these arguments; the driver calculates the
|
|
||||||
* pitch (also known as stride or row length) and total buffer size
|
|
||||||
* for us, also returning us the GEM handle.
|
|
||||||
*/
|
|
||||||
create = (struct drm_mode_create_dumb) {
|
|
||||||
.width = dispdata->mode.hdisplay,
|
|
||||||
.height = dispdata->mode.vdisplay,
|
|
||||||
.bpp = 32,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create)) {
|
|
||||||
SDL_SetError("failed to create dumb buffer\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->gem_handles[0] = create.handle;
|
|
||||||
ret->format = DRM_FORMAT_XRGB8888;
|
|
||||||
ret->modifier = DRM_FORMAT_MOD_LINEAR;
|
|
||||||
ret->width = create.width;
|
|
||||||
ret->height = create.height;
|
|
||||||
ret->pitches[0] = create.pitch;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In order to map the buffer, we call an ioctl specific to the buffer
|
|
||||||
* type, which returns us a fake offset to use with the mmap syscall.
|
|
||||||
* mmap itself then works as you expect.
|
|
||||||
*
|
|
||||||
* Note this means it is not possible to map arbitrary offsets of
|
|
||||||
* buffers without specifically requesting it from the kernel.
|
|
||||||
*/
|
|
||||||
map = (struct drm_mode_map_dumb) {
|
|
||||||
.handle = ret->gem_handles[0],
|
|
||||||
};
|
|
||||||
|
|
||||||
if (KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map)) {
|
|
||||||
SDL_SetError("failed to get mmap offset for the dumb buffer.");
|
|
||||||
goto err_dumb;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret->dumb.mem = mmap(NULL, create.size, PROT_WRITE, MAP_SHARED,
|
|
||||||
viddata->drm_fd, map.offset);
|
|
||||||
|
|
||||||
if (ret->dumb.mem == MAP_FAILED) {
|
|
||||||
SDL_SetError("failed to get mmap offset for the dumb buffer.");
|
|
||||||
goto err_dumb;
|
|
||||||
}
|
|
||||||
ret->dumb.size = create.size;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
err_dumb:
|
|
||||||
destroy = (struct drm_mode_destroy_dumb) { .handle = create.handle };
|
|
||||||
KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
|
|
||||||
err:
|
|
||||||
SDL_free(ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
KMSDRM_DestroyDumbBuffer(_THIS, dumb_buffer **buffer)
|
|
||||||
{
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
|
||||||
|
|
||||||
struct drm_mode_destroy_dumb destroy = {
|
|
||||||
.handle = (*buffer)->gem_handles[0],
|
|
||||||
};
|
|
||||||
|
|
||||||
KMSDRM_drmModeRmFB(viddata->drm_fd, (*buffer)->fb_id);
|
|
||||||
|
|
||||||
munmap((*buffer)->dumb.mem, (*buffer)->dumb.size);
|
|
||||||
KMSDRM_drmIoctl(viddata->drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
|
|
||||||
free(*buffer);
|
|
||||||
*buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using the CPU mapping, fill the dumb buffer with black pixels. */
|
|
||||||
static void
|
|
||||||
KMSDRM_FillDumbBuffer(dumb_buffer *buffer)
|
|
||||||
{
|
|
||||||
unsigned int x, y;
|
|
||||||
for (y = 0; y < buffer->height; y++) {
|
|
||||||
uint32_t *pix = (uint32_t *) ((uint8_t *) buffer->dumb.mem + (y * buffer->pitches[0]));
|
|
||||||
for (x = 0; x < buffer->width; x++) {
|
|
||||||
*pix++ = (0x00000000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static dumb_buffer *KMSDRM_CreateBuffer(_THIS)
|
|
||||||
{
|
|
||||||
dumb_buffer *ret;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
|
||||||
|
|
||||||
ret = KMSDRM_CreateDumbBuffer(_this);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wrap our GEM buffer in a KMS framebuffer, so we can then attach it
|
|
||||||
* to a plane. Here's where we get out fb_id!
|
|
||||||
*/
|
|
||||||
err = KMSDRM_drmModeAddFB2(viddata->drm_fd, ret->width, ret->height,
|
|
||||||
ret->format, ret->gem_handles, ret->pitches,
|
|
||||||
ret->offsets, &ret->fb_id, 0);
|
|
||||||
|
|
||||||
if (err != 0 || ret->fb_id == 0) {
|
|
||||||
SDL_SetError("Failed AddFB2 on dumb buffer\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
err:
|
|
||||||
KMSDRM_DestroyDumbBuffer(_this, &ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************/
|
|
||||||
/* DUMB BUFFER Block ends. */
|
|
||||||
/***************************/
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*********************************/
|
/*********************************/
|
||||||
/* Atomic helper functions block */
|
/* Atomic helper functions block */
|
||||||
/*********************************/
|
/*********************************/
|
||||||
|
@ -1161,20 +1008,8 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
/* Figure out the default mode to be set. */
|
/* Figure out the default mode to be set. */
|
||||||
dispdata->mode = crtc->mode;
|
dispdata->mode = crtc->mode;
|
||||||
|
|
||||||
/* Find the connector's preferred mode, to be used in case the current mode
|
/* Save the original mode for restoration on quit. */
|
||||||
is not valid, or if restoring the current mode fails.
|
dispdata->original_mode = dispdata->mode;
|
||||||
We can always count on the preferred mode! */
|
|
||||||
for (i = 0; i < connector->count_modes; i++) {
|
|
||||||
if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
|
|
||||||
dispdata->preferred_mode = connector->modes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the current CRTC's mode isn't valid, select the preferred
|
|
||||||
mode of the connector. */
|
|
||||||
if (crtc->mode_valid == 0) {
|
|
||||||
dispdata->mode = dispdata->preferred_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) {
|
if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) {
|
||||||
ret = SDL_SetError("Couldn't get a valid connector videomode.");
|
ret = SDL_SetError("Couldn't get a valid connector videomode.");
|
||||||
|
@ -1360,15 +1195,17 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
|
||||||
#if 1
|
#if 1
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
/* Make the display plane point to the original TTY buffer. */
|
/* Make the display plane point to the original TTY buffer. */
|
||||||
|
/* We have to configure it's input and output scaling */
|
||||||
|
/* parameters accordingly. */
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
plane_info.plane = dispdata->display_plane;
|
plane_info.plane = dispdata->display_plane;
|
||||||
plane_info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
plane_info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
plane_info.fb_id = dispdata->crtc->crtc->buffer_id;
|
plane_info.fb_id = dispdata->crtc->crtc->buffer_id;
|
||||||
plane_info.src_w = dispdata->mode.hdisplay;
|
plane_info.src_w = dispdata->original_mode.hdisplay;
|
||||||
plane_info.src_h = dispdata->mode.vdisplay;
|
plane_info.src_h = dispdata->original_mode.vdisplay;
|
||||||
plane_info.crtc_w = dispdata->mode.hdisplay;
|
plane_info.crtc_w = dispdata->original_mode.hdisplay;
|
||||||
plane_info.crtc_h = dispdata->mode.vdisplay;
|
plane_info.crtc_h = dispdata->original_mode.vdisplay;
|
||||||
|
|
||||||
drm_atomic_set_plane_props(&plane_info);
|
drm_atomic_set_plane_props(&plane_info);
|
||||||
|
|
||||||
|
@ -1426,9 +1263,16 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) ||
|
/* If the current window already has surfaces, destroy them before creating other.
|
||||||
((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) {
|
This is mainly for ReconfigureWindow(), where we simply call CreateSurfaces()
|
||||||
|
for regenerating a window's surfaces. */
|
||||||
|
if (windata->gs) {
|
||||||
|
KMSDRM_DestroySurfaces(_this, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||||
|
|| ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN))
|
||||||
|
{
|
||||||
width = dispdata->mode.hdisplay;
|
width = dispdata->mode.hdisplay;
|
||||||
height = dispdata->mode.vdisplay;
|
height = dispdata->mode.vdisplay;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1436,11 +1280,14 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
||||||
height = window->h;
|
height = window->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, surface_fmt, surface_flags)) {
|
if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev,
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
|
surface_fmt, surface_flags)) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO,
|
||||||
|
"GBM surface format not supported. Trying anyway.");
|
||||||
}
|
}
|
||||||
|
|
||||||
windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, width, height, surface_fmt, surface_flags);
|
windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev,
|
||||||
|
width, height, surface_fmt, surface_flags);
|
||||||
|
|
||||||
if (!windata->gs) {
|
if (!windata->gs) {
|
||||||
return SDL_SetError("Could not create GBM surface");
|
return SDL_SetError("Could not create GBM surface");
|
||||||
|
@ -1562,8 +1409,10 @@ KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window) {
|
||||||
windata->output_x = 0;
|
windata->output_x = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Normal non-fullscreen windows are scaled using the CRTC,
|
/* Normal non-fullscreen windows are scaled using the PRIMARY PLANE, so here we store:
|
||||||
so get output (CRTC) size and position, for AR correction. */
|
input size (ie: the size of the window buffers),
|
||||||
|
output size (ie: th mode configured on the CRTC), an X position to compensate for AR correction.
|
||||||
|
These are used when we set the PRIMARY PLANE props in SwapWindow() */
|
||||||
ratio = (float)window->w / (float)window->h;
|
ratio = (float)window->w / (float)window->h;
|
||||||
windata->src_w = window->w;
|
windata->src_w = window->w;
|
||||||
windata->src_h = window->h;
|
windata->src_h = window->h;
|
||||||
|
@ -1637,6 +1486,13 @@ KMSDRM_VideoInit(_THIS)
|
||||||
SDL_EVDEV_Init();
|
SDL_EVDEV_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Since we create and show the default cursor on KMSDRM_InitMouse() and
|
||||||
|
we call KMSDRM_InitMouse() everytime we create a new window, we have
|
||||||
|
to be sure to create and show the default cursor only the first time.
|
||||||
|
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... */
|
||||||
|
dispdata->set_default_cursor_pending = SDL_TRUE;
|
||||||
|
|
||||||
viddata->video_init = SDL_TRUE;
|
viddata->video_init = SDL_TRUE;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -1821,7 +1677,7 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
||||||
so we do it here. */
|
so we do it here. */
|
||||||
KMSDRM_InitMouse(_this);
|
KMSDRM_InitMouse(_this);
|
||||||
|
|
||||||
/* Since we take cursor buffer way from the cursor plane and
|
/* Since we take cursor buffer away from the cursor plane and
|
||||||
destroy the cursor GBM BO when we destroy a window, we must
|
destroy the cursor GBM BO when we destroy a window, we must
|
||||||
also manually re-show the cursor on screen, if necessary,
|
also manually re-show the cursor on screen, if necessary,
|
||||||
when we create a window. */
|
when we create a window. */
|
||||||
|
|
|
@ -83,7 +83,7 @@ typedef struct connector {
|
||||||
typedef struct SDL_DisplayData
|
typedef struct SDL_DisplayData
|
||||||
{
|
{
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
drmModeModeInfo preferred_mode;
|
drmModeModeInfo original_mode;
|
||||||
|
|
||||||
plane *display_plane;
|
plane *display_plane;
|
||||||
plane *cursor_plane;
|
plane *cursor_plane;
|
||||||
|
@ -110,6 +110,8 @@ typedef struct SDL_DisplayData
|
||||||
struct gbm_bo *cursor_bo;
|
struct gbm_bo *cursor_bo;
|
||||||
uint64_t cursor_w, cursor_h;
|
uint64_t cursor_w, cursor_h;
|
||||||
|
|
||||||
|
SDL_bool set_default_cursor_pending;
|
||||||
|
|
||||||
} SDL_DisplayData;
|
} SDL_DisplayData;
|
||||||
|
|
||||||
/* Driverdata info that gives KMSDRM-side support and substance to the SDL_Window. */
|
/* Driverdata info that gives KMSDRM-side support and substance to the SDL_Window. */
|
||||||
|
|
|
@ -38,6 +38,21 @@ static void KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor);
|
||||||
static void KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y);
|
static void KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y);
|
||||||
static int KMSDRM_LEGACY_WarpMouseGlobal(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 *
|
static SDL_Cursor *
|
||||||
KMSDRM_LEGACY_CreateDefaultCursor(void)
|
KMSDRM_LEGACY_CreateDefaultCursor(void)
|
||||||
{
|
{
|
||||||
|
@ -68,43 +83,6 @@ void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
|
||||||
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evaluate if a given cursor size is supported or not.
|
|
||||||
Notably, current Intel gfx only support 64x64 and up. */
|
|
||||||
static SDL_bool
|
|
||||||
KMSDRM_LEGACY_IsCursorSizeSupported (int w, int h, uint32_t bo_format) {
|
|
||||||
|
|
||||||
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
|
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
uint32_t bo_handle;
|
|
||||||
struct gbm_bo *bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm_dev, w, h, bo_format,
|
|
||||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
|
||||||
|
|
||||||
if (!bo) {
|
|
||||||
SDL_SetError("Could not create GBM cursor BO width size %dx%d for size testing", w, h);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(bo).u32;
|
|
||||||
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id, bo_handle, w, h);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
KMSDRM_LEGACY_gbm_bo_destroy(bo);
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (bo) {
|
|
||||||
KMSDRM_LEGACY_gbm_bo_destroy(bo);
|
|
||||||
}
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This simply gets the cursor soft-buffer ready.
|
/* 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
|
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. */
|
in dispata) is destroyed and recreated when we recreate windows, etc. */
|
||||||
|
@ -212,7 +190,7 @@ KMSDRM_LEGACY_InitCursor()
|
||||||
KMSDRM_LEGACY_ShowCursor(mouse->cur_cursor);
|
KMSDRM_LEGACY_ShowCursor(mouse->cur_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show the specified cursor, or hide if cursor is NULL. */
|
/* Show the specified cursor, or hide if cursor is NULL or has no focus. */
|
||||||
static int
|
static int
|
||||||
KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor)
|
KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
|
@ -255,10 +233,6 @@ KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor)
|
||||||
/************************************************/
|
/************************************************/
|
||||||
/* If cursor != NULL, DO show cursor on display */
|
/* If cursor != NULL, DO show cursor on display */
|
||||||
/************************************************/
|
/************************************************/
|
||||||
if (!dispdata) {
|
|
||||||
return SDL_SetError("Could not get display driverdata.");
|
|
||||||
}
|
|
||||||
|
|
||||||
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
|
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
|
||||||
|
|
||||||
if (!curdata || !dispdata->cursor_bo) {
|
if (!curdata || !dispdata->cursor_bo) {
|
||||||
|
@ -318,8 +292,7 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have destroyed the cursor by now, in KMSDRM_DestroyCursor.
|
/* This is only for freeing the SDL_cursor.*/
|
||||||
This is only for freeing the SDL_cursor.*/
|
|
||||||
static void
|
static void
|
||||||
KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor)
|
KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
|
@ -450,8 +423,16 @@ KMSDRM_LEGACY_InitMouse(_THIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDL expects to set the default cursor on screen when we init the mouse. */
|
/* 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());
|
SDL_SetDefaultCursor(KMSDRM_LEGACY_CreateDefaultCursor());
|
||||||
|
dispdata->set_default_cursor_pending = SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -62,145 +62,6 @@
|
||||||
#define KMSDRM_LEGACY_DRI_CARDPATHFMT "/dev/dri/card%d"
|
#define KMSDRM_LEGACY_DRI_CARDPATHFMT "/dev/dri/card%d"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**************************************************************************************/
|
|
||||||
/* UNUSED function because any plane compatible with the CRTC we chose is good enough */
|
|
||||||
/* for us, whatever it's type is. Keep it here for documentation purposes. */
|
|
||||||
/* It cold be needed sometime in the future, too. */
|
|
||||||
/**************************************************************************************/
|
|
||||||
|
|
||||||
SDL_bool KMSDRM_IsPlanePrimary (_THIS, drmModePlane *plane) {
|
|
||||||
|
|
||||||
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
|
|
||||||
SDL_bool ret = SDL_FALSE;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
/* Find out if it's a primary plane. */
|
|
||||||
drmModeObjectProperties *plane_props =
|
|
||||||
KMSDRM_LEGACY_drmModeObjectGetProperties(viddata->drm_fd,
|
|
||||||
plane->plane_id, DRM_MODE_OBJECT_ANY);
|
|
||||||
|
|
||||||
for (j = 0; (j < plane_props->count_props); j++) {
|
|
||||||
|
|
||||||
drmModePropertyRes *prop = KMSDRM_LEGACY_drmModeGetProperty(viddata->drm_fd,
|
|
||||||
plane_props->props[j]);
|
|
||||||
|
|
||||||
if ((strcmp(prop->name, "type") == 0) &&
|
|
||||||
(plane_props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY))
|
|
||||||
{
|
|
||||||
ret = SDL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreeProperty(prop);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreeObjectProperties(plane_props);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/***********************************************/
|
|
||||||
/* Use these functions if you ever need info */
|
|
||||||
/* about the available planes on your machine. */
|
|
||||||
/***********************************************/
|
|
||||||
|
|
||||||
void print_plane_info(_THIS, drmModePlanePtr plane)
|
|
||||||
{
|
|
||||||
char *plane_type;
|
|
||||||
drmModeRes *resources;
|
|
||||||
uint32_t type = 0;
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
drmModeObjectPropertiesPtr props = KMSDRM_LEGACY_drmModeObjectGetProperties(viddata->drm_fd,
|
|
||||||
plane->plane_id, DRM_MODE_OBJECT_PLANE);
|
|
||||||
|
|
||||||
/* Search the plane props for the plane type. */
|
|
||||||
for (i = 0; i < props->count_props; i++) {
|
|
||||||
drmModePropertyPtr p = KMSDRM_LEGACY_drmModeGetProperty(viddata->drm_fd, props->props[i]);
|
|
||||||
if ((strcmp(p->name, "type") == 0)) {
|
|
||||||
type = props->prop_values[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreeProperty(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case DRM_PLANE_TYPE_OVERLAY:
|
|
||||||
plane_type = "overlay";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DRM_PLANE_TYPE_PRIMARY:
|
|
||||||
plane_type = "primary";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DRM_PLANE_TYPE_CURSOR:
|
|
||||||
plane_type = "cursor";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Remember that to present a plane on screen, it has to be
|
|
||||||
connected to a CRTC so the CRTC scans it,
|
|
||||||
scales it, etc... and presents it on screen. */
|
|
||||||
|
|
||||||
/* Now we look for the CRTCs supported by the plane. */
|
|
||||||
resources = KMSDRM_LEGACY_drmModeGetResources(viddata->drm_fd);
|
|
||||||
if (!resources)
|
|
||||||
return;
|
|
||||||
|
|
||||||
printf("--PLANE ID: %d\nPLANE TYPE: %s\nCRTC READING THIS PLANE: %d\nCRTCS SUPPORTED BY THIS PLANE: ", plane->plane_id, plane_type, plane->crtc_id);
|
|
||||||
for (i = 0; i < resources->count_crtcs; i++) {
|
|
||||||
if (plane->possible_crtcs & (1 << i)) {
|
|
||||||
uint32_t crtc_id = resources->crtcs[i];
|
|
||||||
printf ("%d", crtc_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_planes_info(_THIS)
|
|
||||||
{
|
|
||||||
drmModePlaneResPtr plane_resources;
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
|
|
||||||
plane_resources = KMSDRM_LEGACY_drmModeGetPlaneResources(viddata->drm_fd);
|
|
||||||
if (!plane_resources) {
|
|
||||||
printf("drmModeGetPlaneResources failed: %s\n", strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("--Number of planes found: %d-- \n", plane_resources->count_planes);
|
|
||||||
printf("--Usable CRTC that we have chosen: %d-- \n", dispdata->crtc->crtc_id);
|
|
||||||
|
|
||||||
/* Iterate on all the available planes. */
|
|
||||||
for (i = 0; (i < plane_resources->count_planes); i++) {
|
|
||||||
|
|
||||||
uint32_t plane_id = plane_resources->planes[i];
|
|
||||||
|
|
||||||
drmModePlanePtr plane = KMSDRM_LEGACY_drmModeGetPlane(viddata->drm_fd, plane_id);
|
|
||||||
if (!plane) {
|
|
||||||
printf("drmModeGetPlane(%u) failed: %s\n", plane_id, strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print plane info. */
|
|
||||||
print_plane_info(_this, plane);
|
|
||||||
KMSDRM_LEGACY_drmModeFreePlane(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreePlaneResources(plane_resources);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_modestting(int devindex)
|
check_modestting(int devindex)
|
||||||
{
|
{
|
||||||
|
@ -545,13 +406,10 @@ int KMSDRM_LEGACY_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
|
|
||||||
drmModeRes *resources = NULL;
|
drmModeRes *resources = NULL;
|
||||||
drmModePlaneRes *plane_resources = NULL;
|
|
||||||
drmModeEncoder *encoder = NULL;
|
drmModeEncoder *encoder = NULL;
|
||||||
drmModeConnector *connector = NULL;
|
drmModeConnector *connector = NULL;
|
||||||
drmModeCrtc *crtc = NULL;
|
drmModeCrtc *crtc = NULL;
|
||||||
|
|
||||||
uint32_t crtc_index = 0;
|
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned i,j;
|
unsigned i,j;
|
||||||
|
|
||||||
|
@ -560,8 +418,6 @@ int KMSDRM_LEGACY_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
|
|
||||||
dispdata->cursor_bo = NULL;
|
dispdata->cursor_bo = NULL;
|
||||||
|
|
||||||
dispdata->plane_id = 0;
|
|
||||||
|
|
||||||
/* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD) */
|
/* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD) */
|
||||||
SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), KMSDRM_LEGACY_DRI_CARDPATHFMT, viddata->devindex);
|
SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), KMSDRM_LEGACY_DRI_CARDPATHFMT, viddata->devindex);
|
||||||
|
|
||||||
|
@ -662,7 +518,6 @@ int KMSDRM_LEGACY_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
for (i = 0; i < resources->count_crtcs; i++) {
|
for (i = 0; i < resources->count_crtcs; i++) {
|
||||||
if (encoder->possible_crtcs & (1 << i)) {
|
if (encoder->possible_crtcs & (1 << i)) {
|
||||||
encoder->crtc_id = resources->crtcs[i];
|
encoder->crtc_id = resources->crtcs[i];
|
||||||
crtc_index = i;
|
|
||||||
crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
|
crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -680,57 +535,13 @@ int KMSDRM_LEGACY_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
|
||||||
/* Save the original mode for restoration on quit. */
|
/* Save the original mode for restoration on quit. */
|
||||||
dispdata->original_mode = dispdata->mode;
|
dispdata->original_mode = dispdata->mode;
|
||||||
|
|
||||||
/* Find the connector's preferred mode, to be used in case the current mode
|
|
||||||
is not valid, or if restoring the current mode fails. */
|
|
||||||
for (i = 0; i < connector->count_modes; i++) {
|
|
||||||
if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
|
|
||||||
dispdata->preferred_mode = connector->modes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the current CRTC's mode isn't valid, select the preferred
|
|
||||||
mode of the connector. */
|
|
||||||
if (crtc->mode_valid == 0) {
|
|
||||||
dispdata->mode = dispdata->preferred_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) {
|
if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) {
|
||||||
ret = SDL_SetError("Couldn't get a valid connector videomode.");
|
ret = SDL_SetError("Couldn't get a valid connector videomode.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************/
|
/* Store the connector and crtc for future use. These are all we keep
|
||||||
/* Look for a plane that can be connected to our CRTC. */
|
from this function, and these are just structs, inoffensive to VK. */
|
||||||
/*******************************************************/
|
|
||||||
plane_resources = KMSDRM_LEGACY_drmModeGetPlaneResources(viddata->drm_fd);
|
|
||||||
|
|
||||||
for (i = 0; (i < plane_resources->count_planes); i++) {
|
|
||||||
|
|
||||||
drmModePlane *plane = KMSDRM_LEGACY_drmModeGetPlane(viddata->drm_fd,
|
|
||||||
plane_resources->planes[i]);
|
|
||||||
|
|
||||||
/* 1 - Does this plane support our CRTC?
|
|
||||||
2 - Is this plane unused or used by our CRTC? Both possibilities are good.
|
|
||||||
We don't mind if it's primary or overlay. */
|
|
||||||
if ((plane->possible_crtcs & (1 << crtc_index)) &&
|
|
||||||
(plane->crtc_id == crtc->crtc_id || plane->crtc_id == 0 ))
|
|
||||||
{
|
|
||||||
dispdata->plane_id = plane->plane_id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreePlane(plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
KMSDRM_LEGACY_drmModeFreePlaneResources(plane_resources);
|
|
||||||
|
|
||||||
if (!dispdata->plane_id) {
|
|
||||||
ret = SDL_SetError("Could not locate a primary plane compatible with active CRTC.");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the connector and crtc for future use. These and the plane_id is
|
|
||||||
all we keep from this function, and these are just structs, inoffensive to VK. */
|
|
||||||
dispdata->connector = connector;
|
dispdata->connector = connector;
|
||||||
dispdata->crtc = crtc;
|
dispdata->crtc = crtc;
|
||||||
|
|
||||||
|
@ -900,15 +711,15 @@ KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* If the current window already has surfaces, destroy them before creating other.
|
/* If the current window already has surfaces, destroy them before creating other.
|
||||||
This is mainly for ReconfigureWindow, where we simply call CreateSurfaces()
|
This is mainly for ReconfigureWindow(), where we simply call CreateSurfaces()
|
||||||
for regenerating a window's surfaces. */
|
for regenerating a window's surfaces. */
|
||||||
if (windata->gs) {
|
if (windata->gs) {
|
||||||
KMSDRM_LEGACY_DestroySurfaces(_this, window);
|
KMSDRM_LEGACY_DestroySurfaces(_this, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) ||
|
if ( ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||||
((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) {
|
|| ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN))
|
||||||
|
{
|
||||||
width = dispdata->mode.hdisplay;
|
width = dispdata->mode.hdisplay;
|
||||||
height = dispdata->mode.vdisplay;
|
height = dispdata->mode.vdisplay;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1001,6 +812,13 @@ KMSDRM_LEGACY_VideoInit(_THIS)
|
||||||
SDL_EVDEV_Init();
|
SDL_EVDEV_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Since we create and show the default cursor on KMSDRM_InitMouse() and
|
||||||
|
we call KMSDRM_InitMouse() everytime we create a new window, we have
|
||||||
|
to be sure to create and show the default cursor only the first time.
|
||||||
|
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... */
|
||||||
|
dispdata->set_default_cursor_pending = SDL_TRUE;
|
||||||
|
|
||||||
viddata->video_init = SDL_TRUE;
|
viddata->video_init = SDL_TRUE;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
|
@ -62,12 +62,9 @@ typedef struct SDL_DisplayData
|
||||||
drmModeCrtc *crtc;
|
drmModeCrtc *crtc;
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
drmModeModeInfo original_mode;
|
drmModeModeInfo original_mode;
|
||||||
drmModeModeInfo preferred_mode;
|
|
||||||
|
|
||||||
drmModeCrtc *saved_crtc; /* CRTC to restore on quit */
|
drmModeCrtc *saved_crtc; /* CRTC to restore on quit */
|
||||||
|
|
||||||
uint32_t plane_id; /* ID of the primary plane used by the CRTC */
|
|
||||||
|
|
||||||
SDL_bool gbm_init;
|
SDL_bool gbm_init;
|
||||||
|
|
||||||
/* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
|
/* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct,
|
||||||
|
@ -79,6 +76,8 @@ typedef struct SDL_DisplayData
|
||||||
|
|
||||||
SDL_bool modeset_pending;
|
SDL_bool modeset_pending;
|
||||||
|
|
||||||
|
SDL_bool set_default_cursor_pending;
|
||||||
|
|
||||||
} SDL_DisplayData;
|
} SDL_DisplayData;
|
||||||
|
|
||||||
typedef struct SDL_WindowData
|
typedef struct SDL_WindowData
|
||||||
|
|
Loading…
Reference in New Issue