mirror of https://github.com/encounter/SDL.git
kmsdrm: move videomode restoration on VideoQuit() to using the atomic interface instead of the legacy drmModeSetCrtc() function. Refactoring of get_plane_id().
This commit is contained in:
parent
fc722b2d21
commit
09692b6170
|
@ -80,15 +80,16 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||||
KMSDRM_FBInfo *fb;
|
KMSDRM_FBInfo *fb;
|
||||||
int ret;
|
int ret;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
|
/* Do we need to set video mode this time? If yes, pass the right flag and issue a blocking atomic ioctl. */
|
||||||
|
if (dispdata->modeset_pending) {
|
||||||
/* Do we need to set video mode this time? */
|
|
||||||
if (windata->crtc_setup_pending) {
|
|
||||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
windata->crtc_setup_pending = SDL_FALSE;
|
dispdata->modeset_pending = SDL_FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* Block for telling KMS to wait for GPU rendering of the current frame */
|
/* Block for telling KMS to wait for GPU rendering of the current frame */
|
||||||
|
@ -184,12 +185,15 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||||
KMSDRM_FBInfo *fb;
|
KMSDRM_FBInfo *fb;
|
||||||
int ret;
|
int ret;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
/* Do we need to set video mode this time? */
|
/* Do we need to set video mode this time? If yes, pass the right flag and issue a blocking atomic ioctl. */
|
||||||
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
|
if (dispdata->modeset_pending) {
|
||||||
if (windata->crtc_setup_pending) {
|
|
||||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
windata->crtc_setup_pending = SDL_FALSE;
|
dispdata->modeset_pending = SDL_FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the fence that will be inserted in the cmdstream exactly at the end
|
/* Create the fence that will be inserted in the cmdstream exactly at the end
|
||||||
|
|
|
@ -333,18 +333,27 @@ void get_planes_info(_THIS)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get a plane that is PRIMARY (there's no guarantee that we have overlays in all hardware!)
|
/* Get a plane that is PRIMARY (there's no guarantee that we have overlays in all hardware,
|
||||||
and can use the CRTC we have chosen. That's all. */
|
so we can really only count on having one primary plane) and can use the CRTC we have chosen. */
|
||||||
uint32_t get_plane_id(_THIS)
|
uint32_t get_plane_id(_THIS, drmModeRes *resources)
|
||||||
{
|
{
|
||||||
drmModePlaneResPtr plane_resources;
|
drmModePlaneResPtr plane_resources;
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
uint32_t crtc_index = 0;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
int found_primary = 0;
|
int found_primary = 0;
|
||||||
|
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
|
||||||
|
/* Get the crtc_index for the current CRTC. Needed to find out if a plane supports the CRTC. */
|
||||||
|
for (i = 0; i < resources->count_crtcs; i++) {
|
||||||
|
if (resources->crtcs[i] == dispdata->crtc_id) {
|
||||||
|
crtc_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plane_resources = KMSDRM_drmModeGetPlaneResources(viddata->drm_fd);
|
plane_resources = KMSDRM_drmModeGetPlaneResources(viddata->drm_fd);
|
||||||
if (!plane_resources) {
|
if (!plane_resources) {
|
||||||
printf("drmModeGetPlaneResources failed: %s\n", strerror(errno));
|
printf("drmModeGetPlaneResources failed: %s\n", strerror(errno));
|
||||||
|
@ -363,9 +372,10 @@ uint32_t get_plane_id(_THIS)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if the current CRTC is available for this plane. */
|
/* See if the current CRTC is available for this plane. */
|
||||||
if (plane->possible_crtcs & (1 << dispdata->crtc_index)) {
|
if (plane->possible_crtcs & (1 << crtc_index)) {
|
||||||
|
|
||||||
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd, plane_id, DRM_MODE_OBJECT_PLANE);
|
drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(viddata->drm_fd,
|
||||||
|
plane_id, DRM_MODE_OBJECT_PLANE);
|
||||||
ret = plane_id;
|
ret = plane_id;
|
||||||
|
|
||||||
/* Search the plane props, to see if it's a primary plane. */
|
/* Search the plane props, to see if it's a primary plane. */
|
||||||
|
@ -717,7 +727,7 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
|
||||||
|
|
||||||
/* We take note here about the need to do a modeset in the atomic_commit(),
|
/* We take note here about the need to do a modeset in the atomic_commit(),
|
||||||
called in KMSDRM_GLES_SwapWindow(). */
|
called in KMSDRM_GLES_SwapWindow(). */
|
||||||
windata->crtc_setup_pending = SDL_TRUE;
|
dispdata->modeset_pending = SDL_TRUE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -870,20 +880,12 @@ KMSDRM_VideoInit(_THIS)
|
||||||
/* Atomic block */
|
/* Atomic block */
|
||||||
/****************/
|
/****************/
|
||||||
|
|
||||||
/* Find crtc_index. It's used to find out if a plane supports a CRTC. */
|
|
||||||
/* TODO: include this in the get_plane_id() function somehow. */
|
|
||||||
for (int i = 0; i < resources->count_crtcs; i++) {
|
|
||||||
if (resources->crtcs[i] == dispdata->crtc_id) {
|
|
||||||
dispdata->crtc_index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the fences and their fds: */
|
/* Initialize the fences and their fds: */
|
||||||
dispdata->kms_fence = NULL;
|
dispdata->kms_fence = NULL;
|
||||||
dispdata->gpu_fence = NULL;
|
dispdata->gpu_fence = NULL;
|
||||||
dispdata->kms_out_fence_fd = -1,
|
dispdata->kms_out_fence_fd = -1,
|
||||||
dispdata->kms_in_fence_fd = -1,
|
dispdata->kms_in_fence_fd = -1,
|
||||||
|
dispdata->modeset_pending = SDL_FALSE;
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
/* Atomic block ends */
|
/* Atomic block ends */
|
||||||
|
@ -949,7 +951,7 @@ KMSDRM_VideoInit(_THIS)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispdata->plane_id = get_plane_id(_this);
|
dispdata->plane_id = get_plane_id(_this, resources);
|
||||||
if (!dispdata->plane_id) {
|
if (!dispdata->plane_id) {
|
||||||
ret = SDL_SetError("could not find a suitable plane.");
|
ret = SDL_SetError("could not find a suitable plane.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -1011,6 +1013,11 @@ KMSDRM_VideoInit(_THIS)
|
||||||
SDL_EVDEV_Init();
|
SDL_EVDEV_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (encoder)
|
||||||
|
KMSDRM_drmModeFreeEncoder(encoder);
|
||||||
|
if (resources)
|
||||||
|
KMSDRM_drmModeFreeResources(resources);
|
||||||
|
|
||||||
KMSDRM_InitMouse(_this);
|
KMSDRM_InitMouse(_this);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1044,12 +1051,21 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fn to restore original video mode and crtc buffer on quit, using the atomic interface. */
|
||||||
|
/*int
|
||||||
|
restore_video (_THIS)
|
||||||
|
{
|
||||||
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
|
||||||
|
ret = drm_atomic_commit(_this, fb->fb_id, flags);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
void
|
void
|
||||||
KMSDRM_VideoQuit(_THIS)
|
KMSDRM_VideoQuit(_THIS)
|
||||||
{
|
{
|
||||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||||
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
|
||||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
|
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoQuit()");
|
||||||
|
|
||||||
if (_this->gl_config.driver_loaded) {
|
if (_this->gl_config.driver_loaded) {
|
||||||
|
@ -1062,16 +1078,14 @@ KMSDRM_VideoQuit(_THIS)
|
||||||
viddata->max_windows = 0;
|
viddata->max_windows = 0;
|
||||||
viddata->num_windows = 0;
|
viddata->num_windows = 0;
|
||||||
|
|
||||||
/* Restore saved CRTC settings */
|
/* Restore original videomode. */
|
||||||
if (viddata->drm_fd >= 0 && dispdata && dispdata->connector && dispdata->crtc) {
|
if (viddata->drm_fd >= 0 && dispdata && dispdata->connector && dispdata->crtc) {
|
||||||
drmModeConnector *conn = dispdata->connector;
|
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
drmModeCrtc *crtc = dispdata->crtc;
|
|
||||||
|
|
||||||
int ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, crtc->crtc_id, crtc->buffer_id,
|
int ret = drm_atomic_commit(_this, dispdata->crtc->buffer_id, flags);
|
||||||
crtc->x, crtc->y, &conn->connector_id, 1, &crtc->mode);
|
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
|
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original videomode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/****************/
|
/****************/
|
||||||
|
@ -1191,11 +1205,9 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init windata fields. */
|
/* Init fields. */
|
||||||
windata->crtc_setup_pending = SDL_FALSE;
|
|
||||||
windata->egl_surface_dirty = SDL_FALSE;
|
windata->egl_surface_dirty = SDL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
/* First remember that certain functions in SDL_Video.c will call *_SetDisplayMode when the
|
/* First remember that certain functions in SDL_Video.c will call *_SetDisplayMode when the
|
||||||
SDL_WINDOW_FULLSCREEN is set and SDL_WINDOW_FULLSCREEN_DESKTOP is not set.
|
SDL_WINDOW_FULLSCREEN is set and SDL_WINDOW_FULLSCREEN_DESKTOP is not set.
|
||||||
So I am determining here that the behavior when creating an SDL_Window() in KMSDRM, is:
|
So I am determining here that the behavior when creating an SDL_Window() in KMSDRM, is:
|
||||||
|
|
|
@ -75,14 +75,13 @@ typedef struct SDL_DisplayData
|
||||||
drmModeObjectProperties *connector_props;
|
drmModeObjectProperties *connector_props;
|
||||||
drmModePropertyRes **connector_props_info;
|
drmModePropertyRes **connector_props_info;
|
||||||
|
|
||||||
int crtc_index;
|
|
||||||
|
|
||||||
int kms_in_fence_fd;
|
int kms_in_fence_fd;
|
||||||
int kms_out_fence_fd;
|
int kms_out_fence_fd;
|
||||||
|
|
||||||
EGLSyncKHR kms_fence; /* Signaled when kms completes changes requested in atomic iotcl (pageflip, etc). */
|
EGLSyncKHR kms_fence; /* Signaled when kms completes changes requested in atomic iotcl (pageflip, etc). */
|
||||||
EGLSyncKHR gpu_fence; /* Signaled when GPU rendering is done. */
|
EGLSyncKHR gpu_fence; /* Signaled when GPU rendering is done. */
|
||||||
|
|
||||||
|
SDL_bool modeset_pending;
|
||||||
} SDL_DisplayData;
|
} SDL_DisplayData;
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +92,6 @@ typedef struct SDL_WindowData
|
||||||
struct gbm_bo *bo;
|
struct gbm_bo *bo;
|
||||||
struct gbm_bo *next_bo;
|
struct gbm_bo *next_bo;
|
||||||
struct gbm_bo *crtc_bo;
|
struct gbm_bo *crtc_bo;
|
||||||
SDL_bool crtc_setup_pending;
|
|
||||||
#if SDL_VIDEO_OPENGL_EGL
|
#if SDL_VIDEO_OPENGL_EGL
|
||||||
SDL_bool egl_surface_dirty;
|
SDL_bool egl_surface_dirty;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
|
Loading…
Reference in New Issue