<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Aptos;
        panose-1:2 11 0 4 2 2 2 2 2 4;}
@font-face
        {font-family:"Iosevka Fixed SS16";
        panose-1:2 0 5 9 3 0 0 0 0 4;}
@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:10.0pt;
        font-family:"Aptos",sans-serif;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Iosevka Fixed SS16";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#467886" vlink="#96607D" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">This might be slightly off-topic, but I noticed that instead of computing 'now' time for AnimationTimer.handle(long) just before calling the actual handler, we do compute it
 once before sending to possibly multiple handlers.  Each subsequent invocation produces progressively larger discrepancy (AbstractPrimaryTimer:264).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Does not explain the issue John raised though.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">openjfx-dev <openjfx-dev-retn@openjdk.org> on behalf of Michael Strauß <michaelstrau2@gmail.com><br>
<b>Date: </b>Thursday, August 29, 2024 at 11:45<br>
<b>To: </b><br>
<b>Cc: </b>openjfx-dev@openjdk.org <openjfx-dev@openjdk.org><br>
<b>Subject: </b>Re: Bug: Times passed to AnimationTimer should not fluctuate<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">Yes, that makes sense. In any case, we shouldn't be using a system<br>
timer, but simply record the timestamp at v-sync, and then pass this<br>
precise timestamp to all AnimationTimers. It shouldn't matter when<br>
AnimationTimers are invoked between frames, as long as the timestamp<br>
corresponds to the v-sync signal. (Well, unless the timer callback<br>
measures its own time, which it shouldn't do.)<br>
<br>
<br>
On Thu, Aug 29, 2024 at 8:20</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM John Hendrikx <john.hendrikx@gmail.com> wrote:<br>
><br>
> I think they're a bit separate.  Even with VSync, the time it takes to kick the FX thread in action is still going to be between 0-30ms.  If it then passes `System.nanoTime()` to the AnimationRunnables, you're basically saying that they should render a frame
 at the precise time of VSync-Time + random time it took to schedule the FX thread... suffice to say that the extra accuracy of the more accurate VSync timer (just like my far more accurate timer) is made completely redundant by the jitter introduced by the
 scheduler.<br>
><br>
> This brings me back to my original point: we should not be passing `System.nanoTime()` to AnimationRunnables.  Passing `System.nanoTime()` is basically asking to create a frame with a time index that will NEVER be rendered, so why are we asking Animations
 to use this value for calculating animation locations/offsets/sizes ?<br>
><br>
> This problem is also present on Mac and Linux, just less noticeable because their schedulers generally react within 0-2 ms (vs 0-30 ms on Windows).  2 ms is "close enough" to the most commonly used frame rates (60 fps, at 16.667 ms per frame), but on Windows
 it can practically be a two frame difference.<br>
><br>
> Even in the absence of V-sync, when JavaFX arbitrarily picks 60 Hz as its refresh frequency, the times passed to AnimationTimer should be multiples of 16.667 ms, not 16.667 ms + however long it took to wake up the FX thread.  In other words this code in AbstactPrimaryTimer:<br>
><br>
> private long nextPulseTime = nanos();<br>
><br>
> private long lastPulseDuration = Integer.MIN_VALUE;<br>
><br>
> @Override<br>
><br>
> public void run() {<br>
><br>
> if (paused) {<br>
><br>
> return;<br>
><br>
> }<br>
><br>
> final long now = nanos();<br>
><br>
> recordStart((nextPulseTime - now) / 1000000);<br>
><br>
> timePulseImpl(now);<br>
><br>
> recordEnd();<br>
><br>
> updateNextPulseTime(now);<br>
><br>
> // reschedule animation runnable if needed<br>
><br>
> updateAnimationRunnable();<br>
><br>
> }<br>
><br>
> ...would be far better if it passed "nextPulseTime" to `timePulseImpl` (which eventually calls the AnimationRunnables) instead of "now".<br>
><br>
> Note: this is assuming the adaptive pulse flag is disabled.  If it is enabled, nextPulseTime won't be a nice multiple of the frame rate -- so when this is enabled we may want to round it up/down before passing it to the AnimationRunnables.<br>
><br>
> Note 2: you can **already** achieve far smoother animation even on Windows by rounding the value you get passed in to a multiple of 1/frameRate. This only works when you have access to the this time. It won't solve Timeline calculations -- they will still
 calculate positions and values for frames that will never exist, subject to FX thread scheduling jitter...<br>
><br>
> --John<o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>