diff --git a/client/include/interface/renderer.h b/client/include/interface/renderer.h index 818d7c66..2226ca6f 100644 --- a/client/include/interface/renderer.h +++ b/client/include/interface/renderer.h @@ -33,6 +33,7 @@ (x)->deinitialize && \ (x)->onRestart && \ (x)->onResize && \ + (x)->onFontUpdate && \ (x)->onMouseShape && \ (x)->onMouseEvent && \ (x)->renderStartup && \ @@ -185,6 +186,10 @@ typedef struct LG_RendererOps const double scale, const LG_RendererRect destRect, LG_RendererRotate rotate); + /* called when the Dear ImGui font atlas texture must be uploaded + * Context: renderThread */ + bool (*onFontUpdate)(LG_Renderer * renderer); + /* called when the mouse shape has changed * Context: cursorThread */ bool (*onMouseShape)(LG_Renderer * renderer, const LG_RendererCursor cursor, diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index 474d7aa5..bfe2ef92 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -584,16 +584,18 @@ static void egl_onResize(LG_Renderer * renderer, const int width, const int heig !egl_hdrComposeResize(this->hdrCompose, this->width, this->height)) DEBUG_FATAL("Failed to resize the linear HDR composition framebuffer"); - // this is needed to refresh the font atlas texture - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplOpenGL3_Init("#version 300 es"); - ImGui_ImplOpenGL3_NewFrame(); - egl_stateInvalidate(); - egl_damageResize(this->damage, this->translateX, this->translateY, this->scaleX, this->scaleY); egl_desktopResize(this->desktop, this->width, this->height); } +static bool egl_onFontUpdate(LG_Renderer * renderer) +{ + ImGui_ImplOpenGL3_DestroyFontsTexture(); + const bool result = ImGui_ImplOpenGL3_CreateFontsTexture(); + egl_stateInvalidate(); + return result; +} + static bool egl_onMouseShape(LG_Renderer * renderer, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data) @@ -1650,6 +1652,7 @@ struct LG_RendererOps LGR_EGL = .getInterop = egl_getInterop, .onRestart = egl_onRestart, .onResize = egl_onResize, + .onFontUpdate = egl_onFontUpdate, .onMouseShape = egl_onMouseShape, .onMouseColorTransform = egl_onMouseColorTransform, .onMouseWhiteLevel = egl_onMouseWhiteLevel, diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 58cbbc01..201a80b5 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -314,11 +314,12 @@ void opengl_onResize(LG_Renderer * renderer, const int width, const int height, glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, this->window.x, this->window.y, 0, -1, 1); +} - // this is needed to refresh the font atlas texture - ImGui_ImplOpenGL2_Shutdown(); - ImGui_ImplOpenGL2_Init(); - ImGui_ImplOpenGL2_NewFrame(); +static bool opengl_onFontUpdate(LG_Renderer * renderer) +{ + ImGui_ImplOpenGL2_DestroyFontsTexture(); + return ImGui_ImplOpenGL2_CreateFontsTexture(); } bool opengl_onMouseShape(LG_Renderer * renderer, const LG_RendererCursor cursor, @@ -744,6 +745,7 @@ const LG_RendererOps LGR_OpenGL = .deinitialize = opengl_deinitialize, .onRestart = opengl_onRestart, .onResize = opengl_onResize, + .onFontUpdate = opengl_onFontUpdate, .onMouseShape = opengl_onMouseShape, .onMouseEvent = opengl_onMouseEvent, .onFrameFormat = opengl_onFrameFormat, diff --git a/client/src/app.c b/client/src/app.c index ed6c79ce..584162a6 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -1157,7 +1157,7 @@ void app_registerImGuiText(const char * text) if (!util_uiFontAddText(text)) return; - atomic_fetch_add(&g_state.lgrResize, 1); + atomic_store(&g_state.fontDirty, true); app_invalidateOverlay(false); } diff --git a/client/src/main.c b/client/src/main.c index a374cf7f..e512df40 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -268,11 +268,23 @@ static int renderThread(void * unused) .y = g_state.windowScale, }; g_state.io->FontGlobalScale = 1.0f / g_state.windowScale; + } + const bool fontDirty = atomic_exchange(&g_state.fontDirty, false); + if (unlikely(fontDirty || g_state.fontScale != g_state.windowScale)) + { if (!util_buildUIFontAtlas(g_state.io->Fonts, g_params.uiSize * g_state.windowScale, &g_state.fontLarge)) DEBUG_FATAL("Failed to build font atlas: %s (%s)", g_params.uiFont, g_state.fontName); + if (g_state.lgr && !RENDERER(onFontUpdate)) + DEBUG_FATAL("Failed to upload the ImGui font atlas"); + + g_state.fontScale = g_state.windowScale; + } + + if (unlikely(resize)) + { if (g_state.lgr) RENDERER(onResize, g_state.windowW, g_state.windowH, g_state.windowScale, g_state.dstRect, g_params.winRotate); diff --git a/client/src/main.h b/client/src/main.h index a9a4d05f..df2e698b 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -106,6 +106,7 @@ struct AppState int windowW, windowH; int windowCX, windowCY; double windowScale; + double fontScale; LG_RendererRotate rotate; bool focused; struct Border border; @@ -120,6 +121,7 @@ struct AppState LG_Renderer * lgr; atomic_int lgrResize; + atomic_bool fontDirty; LG_Lock lgrLock; bool useDMA;