Hi Thorsten,
> While researching this, I came across Michael Zucchi's PR #1981 > (https://github.com/openjdk/jfx/pull/1981), which addresses an uncontrolled > framerate issue. (...) Applying the patch to my 17u fork seems to resolve the > crash on the affected machine. Good to hear! BadAlloc does point at there being not enough memory in the system. I would have to expect that adding glFinish() is helping the GL server clean up some unused resources. > The original motivation for context.makeCurrent(null) at the end of present() > appears to be defensive (...) I'm not the author of the ES2 backend, but it does look like that to me as well. `makeCurent(null)` could've also been a synchronization effort - glXMakeCurrent specification does define that any buffered GL commands are flushed before swapping contexts. Though, as far as I know OpenGL it should work fine without it. For safety I would also try checking if any parts of JavaFX call any draw commands while dummy GL context is attached, that will ensure it’s not really needed. > Does anyone know a reason if/why the current behavior is actually needed and > if my patch would be reasonable and safe? On a first glance this doesn't look like a bad change, but during review we'd have to extensively test it to make sure. While ES2 is the (only) default on Linux, it is still a fallback on macOS and can also be enabled on Windows. -Lukasz -----Original Message----- From: Thorsten Fischer <[email protected]> Sent: Friday, 17 April 2026 13:26 To: [email protected] Subject: [External] : [Linux] glXMakeCurrent BadAlloc crash with Nvidia driver Hi all, I would like to share an issue a client of mine ran into with JavaFX 17u on Linux/X11 and discuss a change that seems to resolve it. On a Linux notebook with an Nvidia GPU (proprietary driver), a JavaFX application, essentially just running a continuous animation in a single window, would eventually crash with a SIGSEGV originating deep inside the driver. Prior to the crash, glXMakeCurrent returned a BadAlloc error. Timing was non-deterministic - sometimes after ~5 minutes, sometimes after roughly a day. A second machine with very similar hardware (different graphics card revision), the same driver version, but a slightly different OS configuration did not exhibit the crash. When the crash occurred, it was always after ES2Context.makeCurrent() was called with the real drawable (i.e. called from ES2SwapChain.createGraphics()). I have not been able to pinpoint the exact root cause. What I can say empirically is that the crash correlates with the pattern that JavaFX's current code produces on every frame: for each rendered window, glXMakeCurrent is called twice - once in createGraphics() to bind the real drawable, and once in present() via context.makeCurrent(null) to bind the dummy drawable. So the GL context alternates between a real on-screen window and an off-screen pixmap at the frame rate. Reducing this alternation (see below) makes the crash disappear on the affected machine in long-running tests, at least for more than 2 days, which was not the case before. I'd like to discuss whether the alternation itself is actually needed. While researching this, I came across Michael Zucchi's PR #1981 (https://github.com/openjdk/jfx/pull/1981), which addresses an uncontrolled framerate issue. That patch removes / replaces the context.makeCurrent(null) call from ES2SwapChain.present() and calls glFinish after the last presentable. Applying the patch to my 17u fork seems to resolve the crash on the affected machine. So, that was a strong hint that the alternation pattern is involved. However, I also observed new visual artifacts. I commented on them in the PR. So just removing the call is not sufficient. Instead of calling makeCurrent(null) (which issues glXMakeCurrent to the dummy drawable), I only invalidate the Java-side currentDrawable tracking in ES2Context. The next createGraphics() call for any window then sees currentDrawable == null and reliably performs glContext.makeCurrent(drawable) and glContext.bindFBO(0) before rendering. The code is here to see: https://github.com/openjdk/jfx/compare/master...tsx84:jfx:GLX_MakeCurrent_Bug The original motivation for context.makeCurrent(null) at the end of present() appears to be defensive: after swapping buffers, unbind the GL context from the visible drawable so that stray GL operations do not accidentally target a live window. If this is the only reason, is the dummy round-trip still necessary? The next render cycle always starts with an explicit makeCurrent(drawable) anyway. Invalidating the Java-side tracking seems to be enough to ensure that the next makeCurrent is not skipped by the identity-based cache in ES2Context. Does anyone know a reason if/why the current behavior is actually needed and if my patch would be reasonable and safe? Thanks, Thorsten
