From 86e95a607b5d375e4a80ad9eac7597924d8e1882 Mon Sep 17 00:00:00 2001 From: Brandon Schaefer Date: Wed, 2 Aug 2017 17:45:15 -0700 Subject: [PATCH] kmsdrm: Fix tearing in neverputt/ball https://gfycat.com/FatalFarawayHeron --- src/video/kmsdrm/SDL_kmsdrmopengles.c | 25 +++++++++++++++++-------- src/video/kmsdrm/SDL_kmsdrmvideo.c | 10 +++++++--- src/video/kmsdrm/SDL_kmsdrmvideo.h | 3 ++- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index fb0c248c6..8da196308 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -73,10 +73,12 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) { } /* Release previously displayed buffer (which is now the backbuffer) and lock a new one */ - if (wdata->locked_bo != NULL) { - KMSDRM_gbm_surface_release_buffer(wdata->gs, wdata->locked_bo); - /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)wdata->locked_bo); */ - wdata->locked_bo = NULL; + if (wdata->next_bo != NULL) { + KMSDRM_gbm_surface_release_buffer(wdata->gs, wdata->current_bo); + /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)wdata->next_bo); */ + + wdata->current_bo = wdata->next_bo; + wdata->next_bo = NULL; } if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { @@ -84,15 +86,22 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) { return 0; } - wdata->locked_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); - if (wdata->locked_bo == NULL) { + if (wdata->current_bo == NULL) { + wdata->current_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); + if (wdata->current_bo == NULL) { + return 0; + } + } + + wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); + if (wdata->next_bo == NULL) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer"); return 0; /* } else { - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)wdata->locked_bo); */ + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)wdata->next_bo); */ } - fb_info = KMSDRM_FBFromBO(_this, wdata->locked_bo); + fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo); if (_this->egl_data->egl_swapinterval == 0) { /* Swap buffers instantly, possible tearing */ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)", diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index bb16837ee..637fe8c3a 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -542,9 +542,13 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window * window) if(data) { /* Wait for any pending page flips and unlock buffer */ KMSDRM_WaitPageFlip(_this, data, -1); - if (data->locked_bo != NULL) { - KMSDRM_gbm_surface_release_buffer(data->gs, data->locked_bo); - data->locked_bo = NULL; + if (data->next_bo != NULL) { + KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo); + data->next_bo = NULL; + } + if (data->current_bo != NULL) { + KMSDRM_gbm_surface_release_buffer(data->gs, data->current_bo); + data->current_bo = NULL; } #if SDL_VIDEO_OPENGL_EGL SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index bc44e1ab3..39eb8abab 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -58,7 +58,8 @@ typedef struct SDL_DisplayData typedef struct SDL_WindowData { struct gbm_surface *gs; - struct gbm_bo *locked_bo; + struct gbm_bo *current_bo; + struct gbm_bo *next_bo; SDL_bool waiting_for_flip; #if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface;