From ec7137e693f8663db7afb4d92e86f69599e5127c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 9 Jun 2024 14:26:26 -0500 Subject: [PATCH] Flush window events in MMAL and DRM renderers --- app/streaming/video/ffmpeg-renderers/drm.cpp | 17 +++++++++++++++++ app/streaming/video/ffmpeg-renderers/mmal.cpp | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 15d575d4..f3f202b8 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -317,6 +317,23 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params) // CRTC modes below. SDL_Renderer* renderer = SDL_CreateRenderer(params->window, -1, SDL_RENDERER_SOFTWARE); if (renderer != nullptr) { + // SDL_CreateRenderer() can end up having to recreate our window (SDL_RecreateWindow()) + // to ensure it's compatible with the renderer's OpenGL context. If that happens, we + // can get spurious SDL_WINDOWEVENT events that will cause us to (again) recreate our + // renderer. This can lead to an infinite to renderer recreation, so discard all + // SDL_WINDOWEVENT events after SDL_CreateRenderer(). + Session* session = Session::get(); + if (session != nullptr) { + // If we get here during a session, we need to synchronize with the event loop + // to ensure we don't drop any important events. + session->flushWindowEvents(); + } + else { + // If we get here prior to the start of a session, just pump and flush ourselves. + SDL_PumpEvents(); + SDL_FlushEvent(SDL_WINDOWEVENT); + } + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); diff --git a/app/streaming/video/ffmpeg-renderers/mmal.cpp b/app/streaming/video/ffmpeg-renderers/mmal.cpp index 98cf663d..bd733fbe 100644 --- a/app/streaming/video/ffmpeg-renderers/mmal.cpp +++ b/app/streaming/video/ffmpeg-renderers/mmal.cpp @@ -230,6 +230,23 @@ void MmalRenderer::setupBackground(PDECODER_PARAMETERS params) return; } + // SDL_CreateRenderer() can end up having to recreate our window (SDL_RecreateWindow()) + // to ensure it's compatible with the renderer's OpenGL context. If that happens, we + // can get spurious SDL_WINDOWEVENT events that will cause us to (again) recreate our + // renderer. This can lead to an infinite to renderer recreation, so discard all + // SDL_WINDOWEVENT events after SDL_CreateRenderer(). + Session* session = Session::get(); + if (session != nullptr) { + // If we get here during a session, we need to synchronize with the event loop + // to ensure we don't drop any important events. + session->flushWindowEvents(); + } + else { + // If we get here prior to the start of a session, just pump and flush ourselves. + SDL_PumpEvents(); + SDL_FlushEvent(SDL_WINDOWEVENT); + } + SDL_SetRenderDrawColor(m_BackgroundRenderer, 0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderClear(m_BackgroundRenderer); SDL_RenderPresent(m_BackgroundRenderer);