<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div class="moz-cite-prefix">Hi Kevin,<br>
<br>
On 23/9/25 01:02, Kevin Rushforth wrote:<br>
</div>
<blockquote type="cite"
cite="mid:5386517c-5ae6-4028-be42-8185a1e2977d@oracle.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Hi Michael,<br>
<br>
Welcome to the openjfx-dev list. We've not ever been able to
reproduce this on any of our systems. It seems likely that it is
specific to certain graphics drivers. We do all our testing on
Ubuntu Linux and Oracle Linux (which is based on RHEL), so it's
also possible we are testing with different drivers even for the
same card.<br>
<br>
</blockquote>
<br>
Thanks, and I've subscribed to the dev list. It just seemed to be
full of patch discussion so I wasn't sure where to post.<br>
<br>
Indeed I saw on the bug nobody could recreate it. Weird. I tried
Oracle Linux 10 on my laptop but I couldn't get it to load the
modesetting driver and boot (incl the official amd driver). With
ubuntu 25 vanilla i'm getting the same unthrottled framerate as on
my other systems. I was hoping this wasn't the case so I could see
why you weren't seeing this, so I'll try the other desktops in-case
it's related to the compositor but it's going to take a while as i'm
using a usb stick and ubuntu installation seems very disk heavy in
ways every other linux isn't.<br>
<br>
I've attached a standalone example - it runs about 2000fps on one
system when it's down to 1 window. It's intentionally updating each
pulse ignoring the 'frac' value so the pulse timing can be
visualised.<br>
<br>
I don't know if it's useful but this is sample output from
quantum.debug:<br>
<br>
QT.postPulse#(95891966861546): DROP : TAPN<br>
QT.endPulse: 95891966882376<br>
QT.vsyncHint: postPulse: 95891967385262<br>
QT.postPulse@(95891967391984): TAPN<br>
QT.endPulse: 95891967429776<br>
QT.vsyncHint: postPulse: 95891968031510<br>
QT.postPulse@(95891968039475): TAPN<br>
QT.endPulse: 95891968072438<br>
QT.vsyncHint: postPulse: 95891968663842<br>
QT.postPulse@(95891968671827): TAPN<br>
QT.endPulse: 95891968696373<br>
<br>
This last basic sequence repeats a dozen or so times times until a
DROP : TAPN again<br>
<br>
Note that each postPulse() is about 650uS apart.<br>
<br>
<br>
<blockquote type="cite"
cite="mid:5386517c-5ae6-4028-be42-8185a1e2977d@oracle.com">If you
have a reliable patch for the bug, you can submit a PR although we
will need to find a way to test it. See the CONTRIBUTING [1]
guidelines for what you will need to do in order to contribute.<br>
<br>
</blockquote>
<br>
I spent a frustrating hour or so trying to log into an oracle
account I forgot I had, then creating a new one which I also can't
log into ("<span class="oj-idaas-signin-message-content"
role="alert" id="idcs-app-shell-message-content">A federated user
can't perform local authentication.") </span>so I can't sign the
OCA for now (if it ever gets to that point).<br>
<br>
I looked more at the latest code (without the vsync patch).<br>
<br>
Commenting out makeCurrent(null) in ES2SwapChain.present() throttles
the pulse but only if there is a single window (i.e. because the
context never changes). Perhaps this is a driver difference, and
causes glxswapbuffers not to throttle even with double buffering on
the rendering context. makeContext is quite expensive (a few ms),
so i'm surprised it is called every render pass (apart from the
obvious of being easier to implement with a single render thread).
Adding a glFinish() immediately after swapbuffers almost works but
it halves the framerate when too many windows (>2) are active
because it's performed per-window and not per-pulse.<br>
<br>
Secondly, tracing PaintCollector.done() calls toolkit.vsyncHint()
which calls postPulse() whose logic will always fire a new pulse
when an animation is active (i.e. the Transition in the example).
Is this really the expected behaviour here? vsyncHint() seems to be
to perform a vsync not to fire another pulse. Just commenting out
vsyncHint() fixes the poor throttling but then it runs quite jittery
due to timing via gdk_thread_timeout.<br>
<br>
I added some time measurement to ES2SWwapChain.present() with a
single window and it confirms that this is where the throttling or
not occurs - with makeCurrent(null) removed 2 frames are presented
very quickly then swapBuffers() blocks to match the display (and
also means rendering is 2 frames ahead). With it added in it just
runs asynchronously and returns very quickly. I was hoping to
confirm against a 'working' platform but alas so far.<br>
<br>
TBH the throttling is important but I was also curious about
addressing the jitteriness due to using gdk_thread_timeout, it seems
vsyncHint() is meant for that but there doesn't seem to be any
linkage between that and the pulse timing esp since the 'hint' isn't
vsync-synced, so it just ends up firing another pulse immediately or
pausing the timer if no animation is active.<br>
<br>
I'm still thinking of fixes, perhaps a more accurate pulse timer is
enough (and basically ignore vsyncHint) but it will have to be
platform specific. I will have to study the other backends a bit
more first as well.<br>
<br>
Are there plans for a vulkan backend? That might solve/move the
problem. I've seen in mentioned in the past but I can't find
anything on the web about anything concrete.<br>
<br>
Regards, <br>
Michael<br>
<br>
</body>
</html>