hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.11k stars 2.16k forks source link

Better display framerate support on Android #14074

Closed hrydgard closed 9 months ago

hrydgard commented 3 years ago

High-end Android 11 devices such as the Galaxy S21 family support 120hz displays. PPSSPP works fine with this, but the framerate sometimes feels slightly uneven - PSP games never run at more than 60Hz, and I suspect we sometimes get cadences like 1,2,1,3,2,2,2,2,1,3,2,2,2,2 frames (and similar).

Android 11 (SDK 30) adds a new API, Surface.setFrameRate that lets the app set a preferred framerate, and the system will try to accomodate.

We should have an option to switch down to 60Hz, for a more even framerate but probably slightly worse latency than you can get with 120Hz.

Unfortunately, using this API means that we have to target SDK 30, which starts enforcing Scoped Storage Hell. So we're essentially blocked on that. We will have to do that after August anyway though...

There's also some interesting stuff here: https://developer.android.com/games/sdk/frame-pacing

PPSSPP is certainly guilty of "buffer stuffing", and using the choreographer API we might be able to effectively reduce display latency a little.

hrydgard commented 3 years ago

Apparently there's also an older API that could be useful, which according to https://android-developers.googleblog.com/2020/04/high-refresh-rate-rendering-on-android.html is deprecated by setFrameRate:

On Older Android versions (before Android 11) where the setFrameRate API doesn’t exist, applications can still influence the refresh rate by directly setting WindowManager.LayoutParams.preferredDisplayModeId to one of the available modes from Display.getSupportedModes"

hrydgard commented 3 years ago

Note to self: Now that the scoped storage PR is merged and we target SDK 30, this is unblocked.

unknownbrackets commented 3 years ago

I wonder if it'd work out to simply call setFrameRate(59.94, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE). Feels like we'd want to avoid sending detected frame rates if possible, since those are already delayed heuristics.

-[Unknown]

ghost commented 1 year ago

This is kinda related to this https://github.com/hrydgard/ppsspp/issues/15081?

unknownbrackets commented 1 year ago

In a way, but it'd be kinda terrible to simply do that. If the device is 90Hz and you just "sync to host framerate" blindly, then that means in other words you're stuck at 150% speed. You'd then have to enable alternate speed at 75% to get "normal" speed but it probably would have uneven frames still.

Force sync to host frame rate is basically the strategy PAL SNES games used when they were written for NTSC regions and lazily release for PAL. In that case, the games just ran 16% slower on 50Hz displays.

-[Unknown]

hrydgard commented 9 months ago

I've tried this in #18529 now and it does not do anything meaningful for us on 120hz devices. However it prevents 90hz devices from going down to 45 when they want to save power, as reported in #18480 . Closing.