Skip to content

Navigation Menu

Sign in
Sign up

Dreamcast renders ~20fps in heavy scenes on both iPhone and Apple TV #6

Open

Description

Dreamcast renders roughly 20 frames a second in heavy scenes on both iPhone and Apple TV, while running at correct speed with correct audio. Help welcome, this one is well measured but not understood.

Background: a related bug that is already fixed

The native player used to advance the emulator once per display refresh rather than at the rate the core asks for. An iPhone caps its draw loop at 60, close enough to the 59.94 these consoles want that nobody noticed. An Apple TV's display link runs higher, so every core there ran too fast. For Dreamcast that meant the core produced 65,000 to 85,000 audio frames a second against 44,100 of realtime, and roughly 60% of it was discarded, which is heard as music playing sped up.

That is fixed in d49008d: retro_run is now paced against the core's declared timing.fps, and the frontend finally handles RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, which cores use to correct their own timing mid-session (Flycast divides its SPG-derived rate by the vsync swap interval).

Audio on Dreamcast is correct after that fix. Measured: 44,110 frames a second against 44,100 of realtime, exactly 735 frames per call at 60 calls a second, nothing discarded.

The remaining problem

In heavy scenes, Flycast hands over about 2,207 audio frames per retro_run, which is three frames' worth, and renders once. So the emulator holds correct speed by skipping two frames out of three, and the picture updates about 20 times a second.

This happens on both an Apple TV 4K (3rd gen) and an iPhone Air, which is what makes it interesting: it is not simply the Apple TV being the slower box.

What has been ruled out

  • Not the audio buffer. Audio is realtime with zero drops, and pausing the core plays the queued audio out sounding perfectly normal.
  • Not threaded rendering. Forcing reicast_threaded_rendering=disabled changed nothing.
  • Not the frame rate detection option. detect_vsync_swap_interval defaults off and is never enabled by this frontend.
  • Not the usual performance settings. A frontend that never answers GET_VARIABLE inherits the C++ constructor defaults in Flycast's shell/libretro/option.cpp, not the defaults its options table advertises, so enable_dsp is already off, delay_frame_swapping is already off, threaded rendering is already on and the internal resolution is already native. There is nothing to turn down.
  • Not build optimisation. Measured with Cabinet's own code compiled optimised.

What was tried and deliberately not kept

Holding the core back whenever more than 100ms of audio was already queued. It fixed Dreamcast audio completely and dropped the picture to about 20 frames a second on both devices, so it trades one problem for another and is not committed. Anyone trying that approach should note the hazard: if the audio engine is not running, the queue never drains and the core stops advancing entirely, freezing the game.

Where to look

Cabinet compiles Flycast interpreter-only (-DTARGET_NO_REC), since apps on Apple's platforms cannot generate code at runtime, so some ceiling is expected. What is not explained is why the same behaviour appears on hardware several generations apart, or whether three emulated frames per call is Flycast's own frame limiter reacting to something this frontend does.

The relevant code is RommApp/RommApp/Native/NativePlayerRenderer.swift (the draw loop and pacing) and RommApp/RommApp/Native/Libretro/LibretroFrontend.mm (the environment callback and av_info handling). The instrumentation used to measure all of the above is in commit d49008d if it is useful to bring back: it logs frames delivered per wall second, drops, starves, core calls and frames per call.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      AltStyle によって変換されたページ (->オリジナル) /