From 3ac9e2aa4e8352ca410f07b18d80a23686cfbaf6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 5 Oct 2018 17:06:05 -0700 Subject: [PATCH] Fixed bug 4296 - kmsdrm video driver leaks 1 bo in KMSDRM_GLES_SetupCrtc() Icenowy Zheng One front buffer is locked in GLES_SetupCrtc() and overrides the next_bo just locked in KMSDRM_GLES_SwapWindow, then the next_bo gets lost and is not released even when quitting the video. It may leads to problems with GLES drivers that doesn't clean up GBM correctly if there's any bo left (e.g. the Mali Utgard r6p2 blob). In the case of Mali Utgard r6p2 blob, the DRM device file is still hold by the blob, and if you try to SDL_Quit to let another program to run (this is done by EmulationStation), the new program will fail to open DRM device. --- src/video/kmsdrm/SDL_kmsdrmopengles.c | 6 +++--- src/video/kmsdrm/SDL_kmsdrmvideo.c | 4 ++++ src/video/kmsdrm/SDL_kmsdrmvideo.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index 7e8fae725..fc6304d5f 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -54,13 +54,13 @@ KMSDRM_GLES_SetupCrtc(_THIS, SDL_Window * window) { return SDL_FALSE; } - wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); - if (wdata->next_bo == NULL) { + wdata->crtc_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); + if (wdata->crtc_bo == NULL) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer on CRTC setup"); return SDL_FALSE; } - fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo); + fb_info = KMSDRM_FBFromBO(_this, wdata->crtc_bo); if (fb_info == NULL) { return SDL_FALSE; } diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 7855eeddb..973a72602 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -566,6 +566,10 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window * window) if(data) { /* Wait for any pending page flips and unlock buffer */ KMSDRM_WaitPageFlip(_this, data, -1); + if (data->crtc_bo != NULL) { + KMSDRM_gbm_surface_release_buffer(data->gs, data->crtc_bo); + data->crtc_bo = NULL; + } if (data->next_bo != NULL) { KMSDRM_gbm_surface_release_buffer(data->gs, data->next_bo); data->next_bo = NULL; diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index 5f00f0ebc..34f0b105a 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -62,6 +62,7 @@ typedef struct SDL_WindowData struct gbm_surface *gs; struct gbm_bo *current_bo; struct gbm_bo *next_bo; + struct gbm_bo *crtc_bo; SDL_bool waiting_for_flip; SDL_bool crtc_ready; SDL_bool double_buffer;