From aed370c7cea3c353097d2b4d187b33a5b5d8dbb0 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 31 Jul 2021 20:07:05 -0400 Subject: [PATCH] [client] main: implement just-in-time render mode When requested, JIT render mode will be used if the display server supports it. Otherwise, a warning is generated instead. This essentially uses the signalNextFrame logic for imgui, but for everything. We automatically enable this mode when overlay is on. Currently, this exposes some damage tracking bugs in the EGL renderer. --- client/src/config.c | 12 ++++++++++-- client/src/main.c | 40 +++++++++++++++++++++++++++------------- client/src/main.h | 5 +++-- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/client/src/config.c b/client/src/config.c index a0a526ec..acb78ac4 100644 --- a/client/src/config.c +++ b/client/src/config.c @@ -277,6 +277,13 @@ static struct Option options[] = .type = OPTION_TYPE_INT, .value.x_int = 14 }, + { + .module = "win", + .name = "jitRender", + .description = "Enable just-in-time rendering", + .type = OPTION_TYPE_BOOL, + .value.x_bool = false, + }, // input options { @@ -562,8 +569,9 @@ bool config_load(int argc, char * argv[]) g_params.autoScreensaver = option_get_bool ("win", "autoScreensaver"); g_params.showAlerts = option_get_bool ("win", "alerts" ); g_params.quickSplash = option_get_bool ("win", "quickSplash" ); - g_params.uiFont = option_get_string("win" , "uiFont" ); - g_params.uiSize = option_get_int ("win" , "uiSize" ); + g_params.uiFont = option_get_string("win" , "uiFont" ); + g_params.uiSize = option_get_int ("win" , "uiSize" ); + g_params.jitRender = option_get_bool ("win" , "jitRender" ); if (g_params.noScreensaver && g_params.autoScreensaver) { diff --git a/client/src/main.c b/client/src/main.c index 6b67ac92..785e8078 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -167,8 +167,8 @@ static int renderThread(void * unused) while(g_state.state != APP_STATE_SHUTDOWN) { - if (g_state.overlayMustWait) - lgWaitEvent(g_state.overlayRenderEvent, TIMEOUT_INFINITE); + if (g_state.jitRender) + lgWaitEvent(g_state.jitEvent, TIMEOUT_INFINITE); else if (g_params.fpsMin != 0) { float ups = atomic_load_explicit(&g_state.ups, memory_order_relaxed); @@ -182,13 +182,11 @@ static int renderThread(void * unused) } } - if (g_state.overlayInput && g_state.ds->signalNextFrame) - { - g_state.ds->signalNextFrame(g_state.overlayRenderEvent); - g_state.overlayMustWait = true; - } - else - g_state.overlayMustWait = false; + if (!g_params.jitRender && g_state.ds->signalNextFrame) + g_state.jitRender = g_state.overlayInput; + + if (g_state.jitRender) + g_state.ds->signalNextFrame(g_state.jitEvent); int resize = atomic_load(&g_state.lgrResize); if (resize) @@ -828,6 +826,14 @@ static int lg_run(void) assert(g_state.ds); ASSERT_LG_DS_VALID(g_state.ds); + if (g_params.jitRender) + { + if (g_state.ds->signalNextFrame) + g_state.jitRender = true; + else + DEBUG_WARN("JIT render not supported on display server backend, disabled"); + } + // init the subsystem if (!g_state.ds->earlyInit()) { @@ -979,12 +985,18 @@ static int lg_run(void) return -1; } - if (!(g_state.overlayRenderEvent = lgCreateEvent(true, 0))) + if (!(g_state.jitEvent = lgCreateEvent(true, 0))) { DEBUG_ERROR("failed to create the overlay render event"); return -1; } + if (g_state.jitRender) + { + DEBUG_INFO("Using JIT render mode"); + lgSignalEvent(g_state.jitEvent); + } + lgInit(); // start the renderThread so we don't just display junk @@ -1136,6 +1148,8 @@ restart: goto restart; } + lgSignalEvent(g_state.jitEvent); + return 0; } @@ -1164,10 +1178,10 @@ static void lg_shutdown(void) g_state.frameEvent = NULL; } - if (g_state.overlayRenderEvent) + if (g_state.jitEvent) { - lgFreeEvent(g_state.overlayRenderEvent); - g_state.overlayRenderEvent = NULL; + lgFreeEvent(g_state.jitEvent); + g_state.jitEvent = NULL; } if (e_startup) diff --git a/client/src/main.h b/client/src/main.h index 8d5a4966..6ece72b8 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -55,8 +55,6 @@ struct AppState ImFont * fontLarge; bool overlayInput; ImGuiMouseCursor cursorLast; - LGEvent * overlayRenderEvent; - bool overlayMustWait; char * imGuiIni; bool alertShow; @@ -66,6 +64,8 @@ struct AppState struct LG_DisplayServerOps * ds; bool dsInitialized; + bool jitRender; + LGEvent * jitEvent; bool stopVideo; bool ignoreInput; @@ -171,6 +171,7 @@ struct AppParams uint64_t helpMenuDelayUs; const char * uiFont; int uiSize; + bool jitRender; unsigned int cursorPollInterval; unsigned int framePollInterval;