JDK-8210547[linux] frame pacing etc.
Thiago Milczarek Sayão
thiago.sayao at gmail.com
Thu Oct 2 18:04:18 UTC 2025
I confess I did not understand much about the problem.
Is it about variable refresh rates?
If I think a message _VARIABLE_REFRESH is received on the Notify event.
Or
https://docs.gtk.org/gdk3/class.FrameClock.html
I also did an EGL version in place of GLX:
https://github.com/openjdk/jfx/pull/1381
-- Thiago
Em qui., 2 de out. de 2025 às 06:59, Michael Zucchi <notzed at gmail.com>
escreveu:
>
> All,
>
> Unfortunately I'm still unable to login to oracle.com to sign any OCA,
> so the attached patch is just FYI. It seemed to create my account ok but
> afterward confirming my email it redirected me to a page without being
> logged in, and then any attempt to login fails. Firefox 140.x ESR using
> a default profile of I reserve for finicky sites. Any suggestions?
>
> Regardless, I spent a few days poking around including installing
> ubuntu 24 lts, and building javafx on windows 10 (in a vm) to see what
> was supposed to be happening.
>
> Unlike D3D's SwapChain.Present(flags=0), glXSwapBuffers() is a not a
> synchronous call[1]. It only inserts a synchronisation point into the
> command queue which will block any calls that try to render to the back
> buffer before it is swapped from the front - which means it
> 'effectively' blocks if there's a backlog, but only at some unknown
> point in the future (depending on how many buffers the driver sets up).
>
> As per [1] and the specification calling glFinish() immediately after
> glXSwapBuffers() will synchronise to the display and make it behave
> similarly to D3D's SwapChain.Present(0), but with GLX this only works
> for a single window. Each additional window adds another whole frame so
> they all run at 1/N the target rate.
>
> I tried a number of approaches, some of them follow. I was focusing on
> making it work on both a single and multiple window application, and
> with consistent pulse rates.
>
> "vsync" timers
> --------------
>
> One solution is to change the GtkGlass backend to export a non-zero
> staticScreen_getVideoRefreshPeriod() which will cause Quantum to
> assume the clock is accurate to vsync. And then implement something
> that is either accurate or close-enough.
>
> I've tried a few different variations:
>
> 0. Use gdk_timeout but use a dynamic timeout each frame based on the
> reported frame-rate, and using logic to maintain long-term
> accuracy.
>
> Pros: No new mechanisms or races or build changes.
> Fairly accurate over the lont term.
> Can adapt if the monitor refresh rate changes at runtime.
> Avoids vsyncHint() logic.
> Cons: Jittery due to only millisecond precision and g_mainloop.
> gdk_monitor_get_refresh_rate() must be correct (and exist)
>
> 1. As with the Mac backend, Gtk GlassTimer starts a thread that runs
> it's own vblank timing. Use a hidden double-buffered Window and
> call glXSwapBuffer() then glFinish() on a local context before the
> callback.
>
> This works very well for X11 but breaks on XWayland due to [2] where
> it runs at 'jittery 60Hz' regardless of the actual frame-rate because
> wayland and by extension Xwayland doesn't think hidden windows should
> know about vsync.
>
> Pros: For X11 Correct and accurate, should be well supported.
> Avoids vsyncHint() logic.
> Cons: Requires linking to libGL in gtk3glass.
> Complicates errors/fallback a bit.
> gdk_monitor_get_refresh_rate() must be correct (and exist)
> XWayland is broken.
> It is unclear whether the timer callback needs to run on the
> g_mainloop, it doesn't seem to matter.
>
> 2. As with the Mac backend, Gtk GlassTimer starts a thread that runs
> it's own timing. This time using clock_gettime() and usleep() and
> some logic to avoid drift, handle suspend, and keep consistent
> frame timing.
>
> This works quite well as long as GdkMonitor returns an accurate frame
> rate.
>
> Pros: Simple, not perfect timing but fairly accurate in practice.
> Avoids syncHint() logic.
> Could just be implemented in Java if
> GlassApplication.staticScreen_getVideoRefreshPeriod() is
> accurate, although a frame-rate might be more useful.
> Cons: Complicates errors/fallback a bit (if in native)
> gdk_monitor_get_refresh_rate() must be correct (and exist)
> It is unclear whether the timer callback needs to run on the
> g_mainloop, it doesn't seem to matter.
>
> glFinish at a different spot
> ----------------------------
>
> After trying all of the above and reading some more internet forums and
> articles I tried another approach: run a glFinish() once, after all
> GlassScene's have been rendered.
>
> Pros: Seems to work reliably and accurately.
> Pretty simple patch that doesn't touch much.
> Cons: Better Gtk GlassTimer would be nice.
>
> Comments
> --------
>
> A better timer interface and for the animation.pulse value would be
> nice, perhaps internally fps in decimal fixed-point like GdkMonitor
> uses. A better Gtk GlassTimer using that, plus GLX syncing after
> PaintCollector.renderAll().
>
> Just for interest's sake I've attached a WIP patch of the last
> suggestion. I thought they might provide more insight but I've attached
> some frame-time plots from the various alternatives anyway. Note that
> Wayland is on a machine with a frame-rate of 143.88, and the others 59.95.
>
> Regards,
> !Z
>
>
> [1]
>
> https://community.khronos.org/t/understanding-the-opengl-main-loop-swapbuffers/75593/12
> [2] https://gitlab.freedesktop.org/xorg/xserver/-/issues/631
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20251002/894beb66/attachment-0001.htm>
More information about the openjfx-dev
mailing list