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