mirror of https://github.com/encounter/SDL.git
kmsdrm: Add error control to plane prop setting function. Do most plane prop setting with a single function.
This commit is contained in:
parent
e06e9c35c8
commit
0d593d7ead
|
@ -43,58 +43,6 @@ static int KMSDRM_WarpMouseGlobal(int x, int y);
|
||||||
/* Atomic helper functions block. */
|
/* Atomic helper functions block. */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
int
|
|
||||||
drm_atomic_setcursor(KMSDRM_CursorData *curdata, int x, int y)
|
|
||||||
{
|
|
||||||
KMSDRM_FBInfo *fb;
|
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
|
||||||
|
|
||||||
/* Do we have a set of changes already in the making? If not, allocate a new one. */
|
|
||||||
if (!dispdata->atomic_req)
|
|
||||||
dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc();
|
|
||||||
|
|
||||||
if (curdata)
|
|
||||||
{
|
|
||||||
if (!dispdata->cursor_plane) {
|
|
||||||
setup_plane(curdata->video, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR);
|
|
||||||
/* "curdata->video" is the _THIS pointer, which points to an SDL_Display, as passed from kmsdrmmouse.c */
|
|
||||||
}
|
|
||||||
|
|
||||||
fb = KMSDRM_FBFromBO(curdata->video, curdata->bo);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", fb->fb_id);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", dispdata->crtc->crtc->crtc_id);
|
|
||||||
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", curdata->w << 16);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", curdata->h << 16);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_X", x);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_Y", y);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", curdata->w);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", curdata->h);
|
|
||||||
}
|
|
||||||
else if (dispdata->cursor_plane) /* Don't go further if plane has already been freed. */
|
|
||||||
{
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "FB_ID", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_ID", 0);
|
|
||||||
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_X", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_Y", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_W", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "SRC_H", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_W", 0);
|
|
||||||
add_plane_property(dispdata->atomic_req, dispdata->cursor_plane, "CRTC_H", 0);
|
|
||||||
|
|
||||||
free_plane(&dispdata->cursor_plane);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* GPU <-> DISPLAY synchronization is done ON the display_plane,
|
|
||||||
so no need to set any fence props here, we do that only on the main
|
|
||||||
display plane. */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
drm_atomic_movecursor(KMSDRM_CursorData *curdata, int x, int y)
|
drm_atomic_movecursor(KMSDRM_CursorData *curdata, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -140,7 +88,6 @@ void alpha_premultiply_ARGB8888 (uint32_t *pixel) {
|
||||||
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SDL_Cursor *
|
static SDL_Cursor *
|
||||||
KMSDRM_CreateDefaultCursor(void)
|
KMSDRM_CreateDefaultCursor(void)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +116,7 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||||
SDL_assert(surface->pitch == surface->w * 4);
|
SDL_assert(surface->pitch == surface->w * 4);
|
||||||
|
|
||||||
if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
|
if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
|
||||||
printf("Unsupported pixel format for cursor\n");
|
SDL_SetError("Unsupported pixel format for cursor");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +238,8 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
KMSDRM_CursorData *curdata;
|
KMSDRM_CursorData *curdata;
|
||||||
SDL_VideoDisplay *display = NULL;
|
SDL_VideoDisplay *display = NULL;
|
||||||
SDL_DisplayData *dispdata = NULL;
|
SDL_DisplayData *dispdata = NULL;
|
||||||
|
KMSDRM_FBInfo *fb;
|
||||||
|
KMSDRM_PlaneInfo info = {0};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mouse = SDL_GetMouse();
|
mouse = SDL_GetMouse();
|
||||||
|
@ -305,18 +254,21 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide cursor */
|
/**********************************/
|
||||||
|
/* if cursor == NULL, HIDE cursor */
|
||||||
|
/**********************************/
|
||||||
if (!cursor) {
|
if (!cursor) {
|
||||||
/* Hide CURRENT cursor, a cursor that is already on screen
|
/* Hide CURRENT cursor, a cursor that is already on screen
|
||||||
and SDL stores in mouse->cur_cursor. */
|
and SDL stores in mouse->cur_cursor. */
|
||||||
if (mouse->cur_cursor && mouse->cur_cursor->driverdata) {
|
if (mouse->cur_cursor && mouse->cur_cursor->driverdata) {
|
||||||
curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
|
if (dispdata && dispdata->cursor_plane) {
|
||||||
if (curdata->video) {
|
info.plane = dispdata->cursor_plane; /* The rest of the members are zeroed. */
|
||||||
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
ret = drm_atomic_setcursor(0, 0, 0);
|
/* Free the plane on which the cursor was being shown. */
|
||||||
|
free_plane(&dispdata->cursor_plane);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SDL_SetError("Could not hide current cursor with drm_atomic_setcursor).");
|
SDL_SetError("Could not hide current cursor.");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,8 +280,10 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
return SDL_SetError("Couldn't find cursor to hide.");
|
return SDL_SetError("Couldn't find cursor to hide.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************/
|
||||||
|
/* If cursor != NULL, DO show cursor on display */
|
||||||
|
/************************************************/
|
||||||
|
|
||||||
/* If cursor != NULL, show new cursor on display */
|
|
||||||
if (!display) {
|
if (!display) {
|
||||||
return SDL_SetError("Could not get display for mouse.");
|
return SDL_SetError("Could not get display for mouse.");
|
||||||
}
|
}
|
||||||
|
@ -338,15 +292,33 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
||||||
|
|
||||||
if (!curdata || !curdata->bo) {
|
if (!curdata || !curdata->bo) {
|
||||||
return SDL_SetError("Cursor not initialized properly.");
|
return SDL_SetError("Cursor not initialized properly.");
|
||||||
}
|
}
|
||||||
|
|
||||||
curdata->crtc_id = dispdata->crtc->crtc->crtc_id;
|
curdata->crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
|
curdata->plane = dispdata->cursor_plane;
|
||||||
curdata->video = video_device;
|
curdata->video = video_device;
|
||||||
|
|
||||||
/* DO show cursor */
|
/* Init cursor plane, if we haven't yet. */
|
||||||
ret = drm_atomic_setcursor(curdata, mouse->x - curdata->hot_x, mouse->y - curdata->hot_y);
|
if (!dispdata->cursor_plane) {
|
||||||
|
setup_plane(curdata->video, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
fb = KMSDRM_FBFromBO(curdata->video, curdata->bo);
|
||||||
|
|
||||||
|
info.plane = dispdata->cursor_plane;
|
||||||
|
info.crtc_id = curdata->crtc_id;
|
||||||
|
info.fb_id = fb->fb_id;
|
||||||
|
info.src_w = curdata->w;
|
||||||
|
info.src_h = curdata->h;
|
||||||
|
info.crtc_x = mouse->x - curdata->hot_x;
|
||||||
|
info.crtc_y = mouse->y - curdata->hot_y;
|
||||||
|
info.crtc_w = curdata->w;
|
||||||
|
info.crtc_h = curdata->h;
|
||||||
|
|
||||||
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SDL_SetError("KMSDRM_SetCursor failed.");
|
SDL_SetError("KMSDRM_SetCursor failed.");
|
||||||
|
@ -356,12 +328,12 @@ KMSDRM_ShowCursor(SDL_Cursor * cursor)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unset the cursor from the cusror plane, and ONLY WHEN THAT'S DONE,
|
/* Unset the cursor from the cursor plane, and ONLY WHEN THAT'S DONE,
|
||||||
DONE FOR REAL, and not only requested, destroy it by destroying the curso BO.
|
DONE FOR REAL, and not only requested, destroy it by destroying the curso BO.
|
||||||
Destroying the cursor BO is an special an delicate situation,
|
Destroying the cursor BO is an special an delicate situation,
|
||||||
because drm_atomic_setcursor() returns immediately, and we DON'T
|
because drm_atomic_set_plane_props() returns immediately, and we DON'T
|
||||||
want to get to gbm_bo_destroy() before the prop changes requested
|
want to get to gbm_bo_destroy() before the prop changes requested
|
||||||
in drm_atomic_setcursor() have effectively been done. So we
|
in drm_atomic_set_plane_props() have effectively been done. So we
|
||||||
issue a BLOCKING atomic_commit here to avoid that situation.
|
issue a BLOCKING atomic_commit here to avoid that situation.
|
||||||
REMEMBER you yan issue an atomic_commit whenever you want, and
|
REMEMBER you yan issue an atomic_commit whenever you want, and
|
||||||
the changes requested until that moment (for any planes, crtcs, etc.)
|
the changes requested until that moment (for any planes, crtcs, etc.)
|
||||||
|
@ -371,12 +343,14 @@ KMSDRM_FreeCursor(SDL_Cursor * cursor)
|
||||||
{
|
{
|
||||||
KMSDRM_CursorData *curdata = NULL;
|
KMSDRM_CursorData *curdata = NULL;
|
||||||
SDL_VideoDevice *video = NULL;
|
SDL_VideoDevice *video = NULL;
|
||||||
|
KMSDRM_PlaneInfo info = {0};
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
curdata = (KMSDRM_CursorData *) cursor->driverdata;
|
||||||
video = curdata->video;
|
video = curdata->video;
|
||||||
if (video && curdata->bo) {
|
if (video && curdata->bo && curdata->plane) {
|
||||||
drm_atomic_setcursor(0, 0, 0);
|
info.plane = curdata->plane; /* The other members are zeroed. */
|
||||||
|
drm_atomic_set_plane_props(&info);
|
||||||
/* Wait until the cursor is unset from the cursor plane before destroying it's BO. */
|
/* Wait until the cursor is unset from the cursor plane before destroying it's BO. */
|
||||||
drm_atomic_commit(video, SDL_TRUE);
|
drm_atomic_commit(video, SDL_TRUE);
|
||||||
KMSDRM_gbm_bo_destroy(curdata->bo);
|
KMSDRM_gbm_bo_destroy(curdata->bo);
|
||||||
|
@ -427,6 +401,7 @@ KMSDRM_WarpMouseGlobal(int x, int y)
|
||||||
} else {
|
} else {
|
||||||
return SDL_SetError("No mouse or current cursor.");
|
return SDL_SetError("No mouse or current cursor.");
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
typedef struct _KMSDRM_CursorData
|
typedef struct _KMSDRM_CursorData
|
||||||
{
|
{
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
|
struct plane *plane;
|
||||||
uint32_t crtc_id;
|
uint32_t crtc_id;
|
||||||
int hot_x, hot_y;
|
int hot_x, hot_y;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
|
@ -79,6 +79,7 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||||
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
|
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||||
KMSDRM_FBInfo *fb;
|
KMSDRM_FBInfo *fb;
|
||||||
|
KMSDRM_PlaneInfo info = {0};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
@ -108,25 +109,37 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||||
/***************/
|
/***************/
|
||||||
|
|
||||||
/* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer (so it can not
|
/* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer (so it can not
|
||||||
be chosen by EGL as back buffer to draw on), and get a handle to it to request the pageflip on it. */
|
be chosen by EGL as back buffer to draw on), and get a handle to it to request the pageflip on it.
|
||||||
|
REMEMBER that gbm_surface_lock_front_buffer() ALWAYS has to be called after eglSwapBuffers(). */
|
||||||
windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
|
windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
|
||||||
if (!windata->next_bo) {
|
if (!windata->next_bo) {
|
||||||
return SDL_SetError("Failed to lock frontbuffer on GBM surface destruction");
|
return SDL_SetError("Failed to lock frontbuffer");
|
||||||
}
|
}
|
||||||
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
return SDL_SetError("Failed to get a new framebuffer on GBM surface destruction");
|
return SDL_SetError("Failed to get a new framebuffer from BO");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the pageflip to te request list. */
|
/* Add the pageflip to the request list. */
|
||||||
drm_atomic_setbuffer(_this, dispdata->display_plane, fb->fb_id, dispdata->crtc->crtc->crtc_id);
|
info.plane = dispdata->display_plane;
|
||||||
|
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
|
info.fb_id = fb->fb_id;
|
||||||
|
info.src_w = dispdata->mode.hdisplay;
|
||||||
|
info.src_h = dispdata->mode.vdisplay;
|
||||||
|
info.crtc_w = dispdata->mode.hdisplay;
|
||||||
|
info.crtc_h = dispdata->mode.vdisplay;
|
||||||
|
|
||||||
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
|
if (ret) {
|
||||||
|
return SDL_SetError("Failed to request prop changes for setting plane buffer and CRTC");
|
||||||
|
}
|
||||||
|
|
||||||
/* Issue the one and only atomic commit where all changes will be requested!.
|
/* Issue the one and only atomic commit where all changes will be requested!.
|
||||||
We need e a non-blocking atomic commit for triple buffering, because we
|
We need e a non-blocking atomic commit for triple buffering, because we
|
||||||
must not block on this atomic commit so we can re-enter program loop once more. */
|
must not block on this atomic commit so we can re-enter program loop once more. */
|
||||||
ret = drm_atomic_commit(_this, SDL_FALSE);
|
ret = drm_atomic_commit(_this, SDL_FALSE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return SDL_SetError("failed to issue atomic commit on GBM surface destruction");
|
return SDL_SetError("Failed to issue atomic commit on pageflip");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the last front buffer so EGL can chose it as back buffer and render on it again. */
|
/* Release the last front buffer so EGL can chose it as back buffer and render on it again. */
|
||||||
|
@ -165,6 +178,7 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
|
||||||
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
|
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||||
KMSDRM_FBInfo *fb;
|
KMSDRM_FBInfo *fb;
|
||||||
|
KMSDRM_PlaneInfo info = {0};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* In double-buffer mode, atomic commit will always be synchronous/blocking (ie: won't return until
|
/* In double-buffer mode, atomic commit will always be synchronous/blocking (ie: won't return until
|
||||||
|
@ -187,15 +201,26 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
|
||||||
return SDL_SetError("Failed to get a new framebuffer BO");
|
return SDL_SetError("Failed to get a new framebuffer BO");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the pageflip to te request list. */
|
/* Add the pageflip to the request list. */
|
||||||
drm_atomic_setbuffer(_this, dispdata->display_plane, fb->fb_id, dispdata->crtc->crtc->crtc_id);
|
info.plane = dispdata->display_plane;
|
||||||
|
info.crtc_id = dispdata->crtc->crtc->crtc_id;
|
||||||
|
info.fb_id = fb->fb_id;
|
||||||
|
info.src_w = dispdata->mode.hdisplay;
|
||||||
|
info.src_h = dispdata->mode.vdisplay;
|
||||||
|
info.crtc_w = dispdata->mode.hdisplay;
|
||||||
|
info.crtc_h = dispdata->mode.vdisplay;
|
||||||
|
|
||||||
|
ret = drm_atomic_set_plane_props(&info);
|
||||||
|
if (ret) {
|
||||||
|
return SDL_SetError("Failed to request prop changes for setting plane buffer and CRTC");
|
||||||
|
}
|
||||||
|
|
||||||
/* Issue the one and only atomic commit where all changes will be requested!.
|
/* Issue the one and only atomic commit where all changes will be requested!.
|
||||||
Blocking for double buffering: won't return until completed. */
|
Blocking for double buffering: won't return until completed. */
|
||||||
ret = drm_atomic_commit(_this, SDL_TRUE);
|
ret = drm_atomic_commit(_this, SDL_TRUE);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return SDL_SetError("failed to issue atomic commit");
|
return SDL_SetError("Failed to issue atomic commit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release last front buffer so EGL can chose it as back buffer and render on it again. */
|
/* Release last front buffer so EGL can chose it as back buffer and render on it again. */
|
||||||
|
|
|
@ -102,15 +102,14 @@ static int get_dricount(void)
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
DIR *folder;
|
DIR *folder;
|
||||||
|
|
||||||
if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
|
if (!(stat(KMSDRM_DRI_PATH, &sb) == 0 && S_ISDIR(sb.st_mode))) {
|
||||||
&& S_ISDIR(sb.st_mode))) {
|
SDL_SetError("The path %s cannot be opened or is not available",
|
||||||
printf("The path %s cannot be opened or is not available\n",
|
|
||||||
KMSDRM_DRI_PATH);
|
KMSDRM_DRI_PATH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
|
if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
|
||||||
printf("The path %s cannot be opened\n",
|
SDL_SetError("The path %s cannot be opened",
|
||||||
KMSDRM_DRI_PATH);
|
KMSDRM_DRI_PATH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +164,7 @@ static int add_connector_property(drmModeAtomicReq *req, struct connector *conne
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop_id < 0) {
|
if (prop_id < 0) {
|
||||||
printf("no connector property: %s\n", name);
|
SDL_SetError("no connector property: %s", name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +186,7 @@ static int add_crtc_property(drmModeAtomicReq *req, struct crtc *crtc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop_id < 0) {
|
if (prop_id < 0) {
|
||||||
printf("no crtc property: %s\n", name);
|
SDL_SetError("no crtc property: %s", name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +207,7 @@ int add_plane_property(drmModeAtomicReq *req, struct plane *plane,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prop_id < 0) {
|
if (prop_id < 0) {
|
||||||
printf("no plane property: %s\n", name);
|
SDL_SetError("no plane property: %s", name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,8 +465,8 @@ free_plane(struct plane **plane)
|
||||||
/* first, move the plane away from those buffers and ONLY THEN destroy the */
|
/* first, move the plane away from those buffers and ONLY THEN destroy the */
|
||||||
/* buffers and/or the GBM surface containig them. */
|
/* buffers and/or the GBM surface containig them. */
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
void
|
int
|
||||||
drm_atomic_setbuffer(_THIS, struct plane *plane, uint32_t fb_id, uint32_t crtc_id)
|
drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info)
|
||||||
{
|
{
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
|
||||||
|
@ -475,22 +474,40 @@ drm_atomic_setbuffer(_THIS, struct plane *plane, uint32_t fb_id, uint32_t crtc_i
|
||||||
if (!dispdata->atomic_req)
|
if (!dispdata->atomic_req)
|
||||||
dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc();
|
dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc();
|
||||||
|
|
||||||
add_plane_property(dispdata->atomic_req, plane, "FB_ID", fb_id);
|
if (add_plane_property(dispdata->atomic_req, info->plane, "FB_ID", info->fb_id) < 0)
|
||||||
add_plane_property(dispdata->atomic_req, plane, "CRTC_ID", crtc_id);
|
return SDL_SetError("Failed to set plane FB_ID prop");
|
||||||
add_plane_property(dispdata->atomic_req, plane, "SRC_W", dispdata->mode.hdisplay << 16);
|
if (add_plane_property(dispdata->atomic_req, info->plane, "CRTC_ID", info->crtc_id) < 0)
|
||||||
add_plane_property(dispdata->atomic_req, plane, "SRC_H", dispdata->mode.vdisplay << 16);
|
return SDL_SetError("Failed to set plane CRTC_ID prop");
|
||||||
add_plane_property(dispdata->atomic_req, plane, "SRC_X", 0);
|
if (add_plane_property(dispdata->atomic_req, info->plane, "SRC_W", info->src_w << 16) < 0)
|
||||||
add_plane_property(dispdata->atomic_req, plane, "SRC_Y", 0);
|
return SDL_SetError("Failed to set plane SRC_W prop");
|
||||||
add_plane_property(dispdata->atomic_req, plane, "CRTC_W", dispdata->mode.hdisplay);
|
if (add_plane_property(dispdata->atomic_req, info->plane, "SRC_H", info->src_h << 16) < 0)
|
||||||
add_plane_property(dispdata->atomic_req, plane, "CRTC_H", dispdata->mode.vdisplay);
|
return SDL_SetError("Failed to set plane SRC_H prop");
|
||||||
add_plane_property(dispdata->atomic_req, plane, "CRTC_X", 0);
|
if (add_plane_property(dispdata->atomic_req, info->plane, "SRC_X", info->src_x) < 0)
|
||||||
add_plane_property(dispdata->atomic_req, plane, "CRTC_Y", 0);
|
return SDL_SetError("Failed to set plane SRC_X prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "SRC_Y", info->src_y) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane SRC_Y prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "CRTC_W", info->crtc_w) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane CRTC_W prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "CRTC_H", info->crtc_h) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane CRTC_H prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "CRTC_X", info->crtc_x) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane CRTC_X prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "CRTC_Y", info->crtc_y) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane CRTC_Y prop");
|
||||||
|
|
||||||
if (dispdata->kms_in_fence_fd != -1) {
|
/* Only set the IN_FENCE aqnd OUT_FENCE props if we're operationg on the display plane,
|
||||||
add_crtc_property(dispdata->atomic_req, dispdata->crtc, "OUT_FENCE_PTR",
|
since that's the only plane for which we manage who and when should access the buffers
|
||||||
VOID2U64(&dispdata->kms_out_fence_fd));
|
it uses. */
|
||||||
add_plane_property(dispdata->atomic_req, plane, "IN_FENCE_FD", dispdata->kms_in_fence_fd);
|
if ((info->plane == dispdata->display_plane) && (dispdata->kms_in_fence_fd != -1))
|
||||||
|
{
|
||||||
|
if (add_crtc_property(dispdata->atomic_req, dispdata->crtc, "OUT_FENCE_PTR",
|
||||||
|
VOID2U64(&dispdata->kms_out_fence_fd)) < 0)
|
||||||
|
return SDL_SetError("Failed to set CRTC OUT_FENCE_PTR prop");
|
||||||
|
if (add_plane_property(dispdata->atomic_req, info->plane, "IN_FENCE_FD", dispdata->kms_in_fence_fd) < 0)
|
||||||
|
return SDL_SetError("Failed to set plane IN_FENCE_FD prop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int drm_atomic_commit(_THIS, SDL_bool blocking)
|
int drm_atomic_commit(_THIS, SDL_bool blocking)
|
||||||
|
@ -507,8 +524,9 @@ int drm_atomic_commit(_THIS, SDL_bool blocking)
|
||||||
|
|
||||||
ret = KMSDRM_drmModeAtomicCommit(viddata->drm_fd, dispdata->atomic_req, dispdata->atomic_flags, NULL);
|
ret = KMSDRM_drmModeAtomicCommit(viddata->drm_fd, dispdata->atomic_req, dispdata->atomic_flags, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
//SDL_SetError("Atomic commit failed, returned %d.", ret);
|
SDL_SetError("Atomic commit failed, returned %d.", ret);
|
||||||
printf("ATOMIC COMMIT FAILED: %d.\n", ret);
|
/* Uncomment this for fast-debugging */
|
||||||
|
//printf("ATOMIC COMMIT FAILED: %d.\n", ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,7 +771,10 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window * window)
|
||||||
the display plane from the GBM surface buffer it's reading by setting
|
the display plane from the GBM surface buffer it's reading by setting
|
||||||
it's CRTC_ID and FB_ID props to 0.
|
it's CRTC_ID and FB_ID props to 0.
|
||||||
*/
|
*/
|
||||||
drm_atomic_setbuffer(_this, dispdata->display_plane, 0, 0);
|
KMSDRM_PlaneInfo info = {0};
|
||||||
|
info.plane = dispdata->display_plane;
|
||||||
|
|
||||||
|
drm_atomic_set_plane_props(&info);
|
||||||
drm_atomic_commit(_this, SDL_TRUE);
|
drm_atomic_commit(_this, SDL_TRUE);
|
||||||
|
|
||||||
if (windata->bo) {
|
if (windata->bo) {
|
||||||
|
|
|
@ -119,12 +119,29 @@ typedef struct KMSDRM_FBInfo
|
||||||
uint32_t fb_id; /* DRM framebuffer ID */
|
uint32_t fb_id; /* DRM framebuffer ID */
|
||||||
} KMSDRM_FBInfo;
|
} KMSDRM_FBInfo;
|
||||||
|
|
||||||
|
/* Info passed to set_plane_props calls. */
|
||||||
|
typedef struct KMSDRM_PlaneInfo
|
||||||
|
{
|
||||||
|
struct plane *plane;
|
||||||
|
uint32_t fb_id;
|
||||||
|
uint32_t crtc_id;
|
||||||
|
int src_x;
|
||||||
|
int src_y;
|
||||||
|
int src_w;
|
||||||
|
int src_h;
|
||||||
|
int crtc_x;
|
||||||
|
int crtc_y;
|
||||||
|
int crtc_w;
|
||||||
|
int crtc_h;
|
||||||
|
} KMSDRM_PlaneInfo;
|
||||||
|
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window);
|
int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window);
|
||||||
KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
|
KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo);
|
||||||
|
|
||||||
/* Atomic functions that are used from SDL_kmsdrmopengles.c and SDL_kmsdrmmouse.c */
|
/* Atomic functions that are used from SDL_kmsdrmopengles.c and SDL_kmsdrmmouse.c */
|
||||||
void drm_atomic_setbuffer(_THIS, struct plane *plane, uint32_t fb_id, uint32_t crtc_id);
|
int drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info);
|
||||||
|
|
||||||
void drm_atomic_waitpending(_THIS);
|
void drm_atomic_waitpending(_THIS);
|
||||||
int drm_atomic_commit(_THIS, SDL_bool blocking);
|
int drm_atomic_commit(_THIS, SDL_bool blocking);
|
||||||
int add_plane_property(drmModeAtomicReq *req, struct plane *plane,
|
int add_plane_property(drmModeAtomicReq *req, struct plane *plane,
|
||||||
|
|
Loading…
Reference in New Issue