libretro / libretro/RetroArch

Framerate too fast with threaded video + vsync on + audio sync off

Open
#11,302 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
14.1k
Forks
2.2k
Avg merge
7h 35m
Merged PRs (30d)
51

Description

Description

I've been trying to get the threaded video driver running on 3ds, and noticed something weird that doesn't seem to be 3ds-specific.

Specifically, with audio sync off and threaded video on / vsync on, the framerate will sometimes drift up to 65-70fps, where I would expect it to be locked to vsync rate at maximum.

This seems to happen because of the scond_wait_timeout call in video_thread_wrapper.c:751(ish). If the wait times out, we will bail early and drop the frame. In this case, I see this happening when we just missed the last vsync and have to wait for the next one, which is longer than the time between the last call and this one.

If we drop a frame and the core is running fast enough, another frame can come in before the vsync we were waiting on and get handled correctly. Because we dropped the first frame, this means two frames will run under the same vsync, which will handle more than 60fps from the core's perspective.

This was some timing data I collected from a run, logging times at every vsync and at the end of each video_thread_frame call:

image

As you can see, video_thread_frame can get called twice per vsync (due to timeout) which gives a framerate > 60.

Increasing the timeout and removing it altogether both solve the problem, although neither seems correct to me.

Expected behavior

fps to be locked to 60fps (or lower)

Actual behavior

fps counter goes above 60fps, and the audio driver drops samples

Steps to reproduce the bug

This is in a dev build on 3ds, but I can't see why it couldn't happen in others. I don't have those others set up to check yet. It probably also depends on how different drivers listen to vsync.

In the dev build:

  • Turn threaded video on
  • Turn audio sync off
  • Turn video sync on
  • Open a pcsx_rearmed game in an area that runs > 100ish fps when not limited (towns in RPGs are good for this)
  • Watch the framerate go to ~65fps and the audio drop samples
Bisect Results

N/A

Version/Commit

You can find this information under Information/System Information

  • RetroArch: N/A
Environment information
  • OS: Linux
  • Compiler: devkitpro

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in video_thread_wrapper.c around the scond_wait_timeout call near line 751, then trace how video_thread_frame handles a timeout and the next vsync. Reproduce with threaded video and video sync enabled, audio sync disabled, and a fast pcsx_rearmed game. Done means the frame rate remains at or below the vsync rate without audio samples being dropped.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.