<!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>