Bug 238999 - [GTK][WPE] Timestamps delivered to requestAnimationFrame callbacks do not reflect the display refresh that triggered them
Summary: [GTK][WPE] Timestamps delivered to requestAnimationFrame callbacks do not ref...
Status: ASSIGNED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Compositing (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Lord
URL:
Keywords:
Depends on: 233312
Blocks:
  Show dependency treegraph
 
Reported: 2022-04-08 07:18 PDT by Chris Lord
Modified: 2023-04-05 05:02 PDT (History)
5 users (show)

See Also:


Attachments
Frame times under a 20ms load with Chrome (96.35 KB, image/png)
2022-04-08 07:33 PDT, Chris Lord
no flags Details
Frame times under a 20ms load with Firefox (105.14 KB, image/png)
2022-04-08 07:34 PDT, Chris Lord
no flags Details
Frame times under a 20ms load with WebKit/WPE, pre-patch (54.10 KB, image/png)
2022-04-08 07:38 PDT, Chris Lord
no flags Details
Frame times under a 20ms load with WebKit/WPE, post-patch (109.98 KB, image/png)
2022-04-08 07:41 PDT, Chris Lord
no flags Details
Frame times under a 20ms load with Chrome (141.11 KB, image/png)
2022-04-18 05:20 PDT, Chris Lord
no flags Details
Frame times under a 20ms load with Firefox (145.72 KB, image/png)
2022-04-18 05:20 PDT, Chris Lord
no flags Details
Frame time testing page (10.64 KB, text/html)
2022-04-19 02:52 PDT, Chris Lord
no flags Details
Patch (13.21 KB, patch)
2022-05-31 08:54 PDT, Chris Lord
no flags Details | Formatted Diff | Diff
Patch v2 (13.39 KB, patch)
2023-04-05 05:02 PDT, Adrian Perez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lord 2022-04-08 07:18:30 PDT
I don't know if this is reflected in other backends, but timestamps delivered to rAF callbacks are taken from Performance::now and don't necessarily reflect the display refresh that triggered them. This is noticeable when under load as the timestamps are no longer in line with when the display actually refreshes. This behaviour contradicts both Firefox and Chrome, whose timestamps reflect the cadence at which screen refreshes happen. Practically, this means if you have a 20ms frame time, the distance between rAF timestamps will be ~20ms, even though the actual display will be alternating between 16.7ms and 33.3ms (on a 60Hz refresh).

The spec is pretty loose on what these timestamps need to be, but this difference can have an adverse effect on the fluidity of animations based on rAF timestamps and can also have an effect on synthetic benchmarks.

More information and pictures to follow; I have a patch that fixes this for GTK/WPE (though really only WPE in practice due to an unimplemented feature in the GTK backend)
Comment 1 Chris Lord 2022-04-08 07:33:06 PDT
Created attachment 457063 [details]
Frame times under a 20ms load with Chrome

This data captured with a custom tool shows Chrome's behaviour when continuously drawing frames with a ~20ms load. The red line represents the time between consecutive rAF callbacks and the blue line represents the time elapsed between calling rAF and receiving a callback.

Note how the red line is ping-ponging between 16.67ms and 33.33ms (more or less), representing the cadence of displayed frames on this 60Hz display.
Comment 2 Chris Lord 2022-04-08 07:34:35 PDT
Created attachment 457064 [details]
Frame times under a 20ms load with Firefox

The same thing with Firefox shows the same behaviour, though Firefox has lower latency (other testing hints that Chrome uses a triple buffering setup, which explains the higher latency and smoother frame cadence).
Comment 3 Chris Lord 2022-04-08 07:38:17 PDT
Created attachment 457065 [details]
Frame times under a 20ms load with WebKit/WPE, pre-patch

This shows the behaviour of WebKit/WPE - frame timestamps are delivered at regular 20ms intervals, which doesn't represent the cadence of frame display (note, this is with the patch from bug 233312 applied).

This difference in behaviour can cause inconsistency in animations, and can also cause differences in synthetic benchmarks that don't take into account that rAF timestamps are not a good way to measure performance.
Comment 4 Chris Lord 2022-04-08 07:41:56 PDT
Created attachment 457067 [details]
Frame times under a 20ms load with WebKit/WPE, post-patch

This shows frame times after the patch (which I've yet to attach as it depends on bug 233312) - putting WebKit/WPE's behaviour in line with Firefox and Chrome.
Comment 5 Simon Fraser (smfr) 2022-04-11 11:31:25 PDT
Following the spec, I would expect the timestamp to be taken from Step 9, "Let now be the current high resolution time. [HRT]":
https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
Comment 6 Chris Lord 2022-04-18 05:17:41 PDT
(In reply to Simon Fraser (smfr) from comment #5)
> Following the spec, I would expect the timestamp to be taken from Step 9,
> "Let now be the current high resolution time. [HRT]":
> https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-
> model

I agree, but this doesn't match the behaviour of either of the other major browsers and has undesirable consequences (animations looking less consistent if they're based on rAF timestamps and possibly skewed benchmark results).

I think the spec is loose enough for the idea of the 'current' time to be the time of the event that triggered the event loop iteration, perhaps. There is other language in the spec that talks about the user agent being in the best position to determine animation-related parameters, which I think could also apply to this situation (at least, other browsers seem to have interpreted it in this way?)

I've altered my tool to also show the delay between performance.now() called at the start of a callback and the timestamp given to the same callback. These ought to be basically the same under the obvious reading of the spec, but are not and instead match my interpretation in the initial comment.
Comment 7 Chris Lord 2022-04-18 05:20:00 PDT
Created attachment 457804 [details]
Frame times under a 20ms load with Chrome
Comment 8 Chris Lord 2022-04-18 05:20:26 PDT
Created attachment 457805 [details]
Frame times under a 20ms load with Firefox
Comment 9 Simon Fraser (smfr) 2022-04-18 10:03:45 PDT
Could you attach your test page?
Comment 10 Chris Lord 2022-04-19 02:52:37 PDT
Created attachment 457872 [details]
Frame time testing page
Comment 11 Chris Lord 2022-05-31 08:54:38 PDT
Created attachment 459890 [details]
Patch

Attaching this patch for the record - this applies after the patch in bug 233312 and makes sure that the timestamp in rAF callbacks is always aligned to the screen refresh, similar to how it is in Firefox and Chrome.
Comment 12 Adrian Perez 2023-04-05 05:02:43 PDT
Created attachment 465772 [details]
Patch v2

This is Chris' patch updated to build on “main”; I am trying to look
now into this issue and one of the first things I wanted to do was
testing the suggested approach.