mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2025-01-17 14:47:19 +01:00
kmsdrm: wait for possible pending atomic commits before destroying surfaces, and before restoring video on quit. Move messages to the SDL_Log* functions.
This commit is contained in:
parent
96c99693a2
commit
3b9f1073c6
@ -121,13 +121,11 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
|||||||
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. */
|
||||||
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) {
|
||||||
printf("Failed to lock frontbuffer\n");
|
return SDL_SetError("Failed to lock frontbuffer");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
printf("Failed to get a new framebuffer BO\n");
|
return SDL_SetError("Failed to get a new framebuffer BO");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't issue another atomic ioctl until previous one has completed: it will cause errors. */
|
/* Don't issue another atomic ioctl until previous one has completed: it will cause errors. */
|
||||||
@ -139,13 +137,13 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
|
|||||||
} while (status != EGL_CONDITION_SATISFIED_KHR);
|
} while (status != EGL_CONDITION_SATISFIED_KHR);
|
||||||
|
|
||||||
_this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->kms_fence);
|
_this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->kms_fence);
|
||||||
|
dispdata->kms_fence = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issue atomic commit, where we request the pageflip. */
|
/* Issue atomic commit, where we request the pageflip. */
|
||||||
ret = drm_atomic_commit(_this, fb->fb_id, flags);
|
ret = drm_atomic_commit(_this, fb->fb_id, flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("failed to do atomic commit\n");
|
return SDL_SetError("failed to issue atomic commit");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
@ -206,20 +204,17 @@ KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
|
|||||||
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. */
|
||||||
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) {
|
||||||
printf("Failed to lock frontbuffer\n");
|
return SDL_SetError("Failed to lock frontbuffer");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
fb = KMSDRM_FBFromBO(_this, windata->next_bo);
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
printf("Failed to get a new framebuffer BO\n");
|
return SDL_SetError("Failed to get a new framebuffer BO");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Issue atomic commit, where we request the pageflip. */
|
/* Issue atomic commit, where we request the pageflip. */
|
||||||
ret = drm_atomic_commit(_this, fb->fb_id, flags);
|
ret = drm_atomic_commit(_this, fb->fb_id, flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("failed to do atomic commit\n");
|
return SDL_SetError("failed to do atomic commit");
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
@ -462,12 +462,30 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wait_pending_atomic(_THIS)
|
||||||
|
{
|
||||||
|
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
|
||||||
|
|
||||||
|
/* Will return immediately if we have already destroyed the fence, because we NULL-ify it just after.
|
||||||
|
Also, will return immediately in double-buffer mode, because kms_fence will alsawys be NULL. */
|
||||||
|
if (dispdata->kms_fence) {
|
||||||
|
EGLint status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
status = _this->egl_data->eglClientWaitSyncKHR(_this->egl_data->egl_display,
|
||||||
|
dispdata->kms_fence, 0, EGL_FOREVER_KHR);
|
||||||
|
} while (status != EGL_CONDITION_SATISFIED_KHR);
|
||||||
|
|
||||||
|
_this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->kms_fence);
|
||||||
|
dispdata->kms_fence = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************/
|
/***************************************/
|
||||||
/* End of Atomic helper functions block*/
|
/* End of Atomic helper functions block*/
|
||||||
/***************************************/
|
/***************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
KMSDRM_Available(void)
|
KMSDRM_Available(void)
|
||||||
{
|
{
|
||||||
@ -657,6 +675,9 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window * window)
|
|||||||
{
|
{
|
||||||
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
|
||||||
|
|
||||||
|
/* Wait for pending atomic commit (like pageflips requested in SwapWindow) to complete. */
|
||||||
|
wait_pending_atomic(_this);
|
||||||
|
|
||||||
if (windata->bo) {
|
if (windata->bo) {
|
||||||
KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
|
KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
|
||||||
windata->bo = NULL;
|
windata->bo = NULL;
|
||||||
@ -1073,21 +1094,13 @@ KMSDRM_VideoQuit(_THIS)
|
|||||||
/* Atomic block for video mode and crt->buffer restoration */
|
/* Atomic block for video mode and crt->buffer restoration */
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
|
||||||
/* It could happen that we will get here after an async atomic commit (as it's in triple buffer
|
/* We could get here after an async atomic commit (as it's in triple buffer SwapWindow())
|
||||||
SwapWindow()) and we don't want to issue another atomic commit before previous one is completed. */
|
and we don't want to issue another atomic commit before previous one is completed. */
|
||||||
if (dispdata->kms_fence) {
|
wait_pending_atomic(_this);
|
||||||
EGLint status;
|
|
||||||
|
|
||||||
do {
|
|
||||||
status = _this->egl_data->eglClientWaitSyncKHR(_this->egl_data->egl_display,
|
|
||||||
dispdata->kms_fence, 0, EGL_FOREVER_KHR);
|
|
||||||
} while (status != EGL_CONDITION_SATISFIED_KHR);
|
|
||||||
|
|
||||||
_this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->kms_fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Issue sync/blocking atomic commit that restores original video mode and points crtc to original buffer. */
|
/* Issue sync/blocking atomic commit that restores original video mode and points crtc to original buffer. */
|
||||||
ret = drm_atomic_commit(_this, dispdata->crtc->buffer_id, flags);
|
ret = drm_atomic_commit(_this, dispdata->crtc->buffer_id, flags);
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
/* Atomic block ends */
|
/* Atomic block ends */
|
||||||
/*********************/
|
/*********************/
|
||||||
|
Loading…
Reference in New Issue
Block a user