From a9d7c8e49579938bcb292fe08191ff822b30f2d4 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 25 Jun 2024 21:57:02 -0500 Subject: [PATCH] Move forced KMSDRM modesetting operation into Session init code Performing this each time DrmRenderer is initialized leads to long delays when choosing a decoder on embedded platforms, particularly those like TH1520/JH7110 which lack accelerated GL drivers. --- app/streaming/session.cpp | 25 +++++++++++++ app/streaming/video/ffmpeg-renderers/drm.cpp | 37 -------------------- 2 files changed, 25 insertions(+), 37 deletions(-) diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 305e6a3e..3cc04bdd 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -1802,6 +1802,31 @@ void Session::execInternal() FillRect(info.info.win.hdc, &clientRect, blackBrush); DeleteObject(blackBrush); } +#else + if (strcmp(SDL_GetCurrentVideoDriver(), "KMSDRM") == 0) { + // Create a dummy renderer to force SDL to complete the modesetting + // operation that the KMSDRM backend keeps pending until the next + // time we swap buffers. + SDL_Renderer* renderer = SDL_CreateRenderer(m_Window, -1, SDL_RENDERER_SOFTWARE); + if (renderer != nullptr) { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + SDL_DestroyRenderer(renderer); + + // 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(). + flushWindowEvents(); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_CreateRenderer() for KMSDRM modesetting failed: %s", + SDL_GetError()); + } + } #endif } diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index cf63728a..a3281db5 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -47,7 +47,6 @@ extern "C" { #include #include "streaming/streamutils.h" -#include "streaming/session.h" #include @@ -328,42 +327,6 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params) return DIRECT_RENDERING_INIT_FAILED; } - if (!params->testOnly) { - // Create a dummy renderer to force SDL to complete the modesetting - // operation that the KMSDRM backend keeps pending until the next - // time we swap buffers. We have to do this before we enumerate - // 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); - SDL_DestroyRenderer(renderer); - } - else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_CreateRenderer() failed: %s", - SDL_GetError()); - } - } - drmModeRes* resources = drmModeGetResources(m_DrmFd); if (resources == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,