Closed Bug 1778575 Opened 2 years ago Closed 2 years ago

If requestAnimationFrame misses the 16.6ms budget, we fall back to 40 fps

Categories

(Core :: Layout, defect)

defect

Tracking

()

RESOLVED FIXED
108 Branch
Tracking Status
relnote-firefox --- 108+
firefox-esr91 --- wontfix
firefox-esr102 --- wontfix
firefox102 --- wontfix
firefox103 --- wontfix
firefox104 --- wontfix
firefox105 --- wontfix
firefox106 --- wontfix
firefox107 --- wontfix
firefox108 --- fixed

People

(Reporter: mstange, Assigned: smaug)

References

(Regression)

Details

(Keywords: perf-alert, regression)

Attachments

(4 files)

Profile: https://share.firefox.dev/3O4YLvH

Testcase: https://jrmuizel.github.io/dl-perf/sommerset-js-work.html?spin=18

If a requestAnimationFrame handler takes long enough that we can't manage to run it every vsync, we end up getting into a tick/tick/skip pattern. For example, when vsync ticks at 60fps, this means that we go down to 40fps if the tick takes longer than 16.6ms.

You might argue that, if we're consistently missing 60fps, we should fall down to 30fps to at least get even frame pacing. Or we should go as fast as we can. So either 30fps or 57fps might be an acceptable solution. But the 40fps behavior that we have now is the worst of both worlds.

It looks like we're the only browser with this kind of behavior. Both Chrome and Safari seem to be willing to call requestAnimationFrame callbacks at any time during a frame, and keep the CPU completely busy without any gaps. So they've picked the "57fps" behavior.

Olli, how do you feel about "unlocking" the start time of the refresh tick, in the case where we can't keep up with the vsync rate? I think this will undo from the work from (the amazingly named) bug 1371668.

Flags: needinfo?(bugs)
Keywords: regression
Regressed by: 1371668

Set release status flags based on info from the regressing bug 1371668

Sounds reasonable, but better to test that the change doesn't regress high frequency handling (unlikely) nor bug 1755006 (perhaps a bit likelier, but shouldn't, since mSkippedPaints is handled at the nsRefreshDriver level, not RefreshDriverTimer).

Flags: needinfo?(bugs)

I wonder if we could add a test for this once this is fixed. Regressing scheduling behavior is easy, since there aren't too many tests... because writing tests can be tricky.

Severity: -- → S3

Set release status flags based on info from the regressing bug 1371668

Markus, do you plan to fix this?

Flags: needinfo?(mstange.moz)

I'll be busy with profiler work for the rest of the year, probably, so I won't have time for this in the near future.

Flags: needinfo?(mstange.moz)

Need to ensure bug 1755006 doesn't regress when fixing this.

And the priority of DidComposite has changed since bug 1371668 landed - it is now using control priority (and JS shouldn't run in such tasks).

Attached file slowraf.html

Do we actually have an issue, or in which case exactly?
Since DidComposite has the highest possible priority, if rAF takes lots of time and there is a pending DidComposite, DidComposite will be processes ASAP after rAF and then a pending vsync can be handled again.

Ok, this one shows the difference

Assignee: nobody → smaug
Attachment #9298388 - Attachment description: WIP: Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty → WIP: Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions
Attachment #9298388 - Attachment description: WIP: Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions → Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions
Attachment #9298388 - Attachment description: Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions → Bug 1778575, try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions, r=mstange,bas

This improves the setup so that whenever there are only idle/deferred tasks, we can run low priority tasks immediately.
Manual testing shows that this way we get couple of more ticks every now and then.

Without this patch we'd rely on normal priority tasks, but since there might be multiple of those pending, ShouldGiveNonVsyncTasksMoreTime() would
return true.

So, low priority tasks are effectively "run when the queue is otherwise empty (but idle-type of tasks are still special)".

Depends on D159260

Pushed by opettay@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/6721a4116d17
try to run a pending vsync asap if the main thread is otherwise empty, or if we skipped paints because of pending transactions, r=bas
https://hg.mozilla.org/integration/autoland/rev/74c85cc921c1
add support for low priority tasks and use such to trigger pending RefreshDriverTimer, r=bas
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 108 Branch

Since nightly and release are affected, beta will likely be affected too.
For more information, please visit auto_nag documentation.

== Change summary for alert #35702 (as of Thu, 20 Oct 2022 01:57:34 GMT) ==

Improvements:

Ratio Test Platform Options Absolute values (old vs new)
7% motionmark-htmlsuite linux1804-64-shippable-qr fission webrender 57.03 -> 60.88
7% motionmark-animometer linux1804-64-shippable-qr fission webrender 48.38 -> 51.55

For up to date results, see: https://treeherder.mozilla.org/perfherder/alerts?id=35702

See Also: → 1825391
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: