From 7a9b29f358f575c7132dc55d546ce12bb9061188 Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 13 Oct 2026 13:30:20 -0500 Subject: [PATCH] fix(effects): stop retrying scroll-fade shader init after it fails If the scroll-edge fade shader failed to compile or link, the init path left its ready flag clear and tried again on the very next frame. On a driver that rejects the shader that meant a fresh compile attempt every frame, for the life of the program. - A failed init is now latched and treated as final until destroy(), so the compile is attempted once, the failure is logged once, and the fades stay disabled without further retries. Destroying the shader clears the latch so a later re-init can try again. Co-Authored-By: Claude Opus 4.8 --- src/ui/effects/scroll_fade_shader.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ui/effects/scroll_fade_shader.h b/src/ui/effects/scroll_fade_shader.h index fdc8ea3..f6c162c 100644 --- a/src/ui/effects/scroll_fade_shader.h +++ b/src/ui/effects/scroll_fade_shader.h @@ -49,6 +49,7 @@ struct ScrollFadeShader { // ---- Internal state ---- bool ready = false; + bool failed = false; // a failed init is final until destroy(): no per-frame recompiles on a rejecting driver #ifdef DRAGONX_HAS_GLAD GLuint program_ = 0; @@ -72,11 +73,16 @@ struct ScrollFadeShader { bool init() { if (ready) return true; + if (failed) return false; #ifdef DRAGONX_HAS_GLAD ready = initGL(); #elif defined(DRAGONX_USE_DX11) ready = initDX11(); #endif + if (!ready) { + failed = true; + LOGF("ScrollFadeShader: init failed, scroll-edge fades disabled\n"); // once; release builds record it + } return ready; } @@ -87,6 +93,7 @@ struct ScrollFadeShader { destroyDX11(); #endif ready = false; + failed = false; } // ----------------------------------------------------------------