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