mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-12 05:50:29 +02:00
Rework the present mode settings, refactor.
This commit is contained in:
1 parent
4c0b011b0e
commit
042cf87248
65 files changed
+284
-175
No files matched your search
+53
-57
@@ -22,6 +22,7 @@
|
||||
#include "ppsspp_config.h"
|
||||
#include "Common/Profiler/Profiler.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
|
||||
#include "Core/RetroAchievements.h"
|
||||
@@ -56,22 +57,6 @@ void WaitUntil(double now, double timestamp, const char *reason) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Draw::PresentMode GetBestImmediateMode(Draw::PresentMode supportedModes) {
|
||||
if (supportedModes & Draw::PresentMode::MAILBOX) {
|
||||
return Draw::PresentMode::MAILBOX;
|
||||
} else {
|
||||
return Draw::PresentMode::IMMEDIATE;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameTiming::Reset(Draw::DrawContext *draw) {
|
||||
if (g_Config.bVSync || !(draw->GetDeviceCaps().presentModesSupported & (Draw::PresentMode::MAILBOX | Draw::PresentMode::IMMEDIATE))) {
|
||||
presentMode = Draw::PresentMode::FIFO;
|
||||
} else {
|
||||
presentMode = GetBestImmediateMode(draw->GetDeviceCaps().presentModesSupported);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameTiming::DeferWaitUntil(double until, double *curTimePtr) {
|
||||
_dbg_assert_(until > 0.0);
|
||||
waitUntil_ = until;
|
||||
@@ -89,54 +74,65 @@ void FrameTiming::PostSubmit() {
|
||||
}
|
||||
}
|
||||
|
||||
Draw::PresentMode ComputePresentMode(Draw::DrawContext *draw) {
|
||||
_assert_(draw);
|
||||
void FrameTiming::ComputePresentMode(Draw::DrawContext *draw, bool fastForward) {
|
||||
_dbg_assert_(draw);
|
||||
if (!draw) {
|
||||
fastForwardSkipFlip_ = true;
|
||||
presentMode_ = Draw::PresentMode::FIFO;
|
||||
return;
|
||||
}
|
||||
|
||||
Draw::PresentMode mode = Draw::PresentMode::FIFO;
|
||||
_dbg_assert_(draw->GetDeviceCaps().presentModesSupported != (Draw::PresentMode)0);
|
||||
|
||||
if (draw->GetDeviceCaps().presentModesSupported & (Draw::PresentMode::IMMEDIATE | Draw::PresentMode::MAILBOX)) {
|
||||
// Switch to immediate if desired and possible.
|
||||
bool wantInstant = false;
|
||||
if (!g_Config.bVSync) {
|
||||
wantInstant = true;
|
||||
if (draw->GetDeviceCaps().presentModesSupported == Draw::PresentMode::FIFO) {
|
||||
// Only FIFO mode is supported (like on iOS and some GLES backends).
|
||||
fastForwardSkipFlip_ = true;
|
||||
presentMode_ = Draw::PresentMode::FIFO;
|
||||
return;
|
||||
}
|
||||
|
||||
// More than one present mode is supported. Use careful logic.
|
||||
|
||||
// The user has requested vsync off.
|
||||
if (!g_Config.bVSync) {
|
||||
if (draw->GetDeviceCaps().presentModesSupported & Draw::PresentMode::IMMEDIATE) {
|
||||
// Use immediate mode, whether fast-forwarding or not.
|
||||
presentMode_ = Draw::PresentMode::IMMEDIATE;
|
||||
fastForwardSkipFlip_ = false;
|
||||
return;
|
||||
}
|
||||
// Inconsistent state - vsync is off but immediate mode is not supported.
|
||||
// We will simply force on VSync.
|
||||
g_Config.bVSync = true;
|
||||
}
|
||||
|
||||
if (PSP_CoreParameter().fastForward && NetworkAllowSpeedControl()) {
|
||||
wantInstant = true;
|
||||
// At this point, vsync is always on. What decides now is whether MAILBOX or IMMEDIATE is available,
|
||||
// and also if we need an unsynced mode.
|
||||
|
||||
// OK, vsync is requested (or immediate is not available). If mailbox is supported, it works the same as IMMEDIATE above.
|
||||
|
||||
if (g_Config.bLowLatencyPresent) {
|
||||
// Use mailbox if available. It works fine for both fast-forward and normal.
|
||||
if (draw->GetDeviceCaps().presentModesSupported & Draw::PresentMode::MAILBOX) {
|
||||
presentMode_ = Draw::PresentMode::MAILBOX;
|
||||
fastForwardSkipFlip_ = false;
|
||||
return;
|
||||
}
|
||||
// We could force off lowLatencyPresent here, but it's no good when changing between backends.
|
||||
// So let's leave it on in the background, maybe the user just went from Vulkan to OpenGL.
|
||||
}
|
||||
|
||||
FPSLimit limit = PSP_CoreParameter().fpsLimit;
|
||||
if (!NetworkAllowSpeedControl()) {
|
||||
limit = FPSLimit::NORMAL;
|
||||
}
|
||||
|
||||
if (limit != FPSLimit::NORMAL) {
|
||||
int limit;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
limit = g_Config.iFpsLimit1;
|
||||
else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
limit = g_Config.iFpsLimit2;
|
||||
else
|
||||
limit = PSP_CoreParameter().analogFpsLimit;
|
||||
|
||||
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
|
||||
// TODO: Should take the user's display refresh rate into account...
|
||||
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
|
||||
wantInstant = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wantInstant && g_Config.bVSync && !draw->GetDeviceCaps().presentInstantModeChange) {
|
||||
// If in vsync mode (which will be FIFO), and the backend can't switch immediately,
|
||||
// stick to FIFO.
|
||||
wantInstant = false;
|
||||
}
|
||||
|
||||
// The outer if checks that instant modes are available.
|
||||
if (wantInstant) {
|
||||
mode = GetBestImmediateMode(draw->GetDeviceCaps().presentModesSupported);
|
||||
// At this point, low-latency mode is not available, and vsync is on. We see if we can use INSTANT
|
||||
// mode for fast-forwarding, or if we need to resort to frameskipping.
|
||||
if (draw->GetDeviceCaps().presentInstantModeChange) {
|
||||
if (fastForward) {
|
||||
presentMode_ = Draw::PresentMode::IMMEDIATE;
|
||||
fastForwardSkipFlip_ = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return mode;
|
||||
// Finally, fallback to FIFO mode, with skip-flip in fast-forward.
|
||||
presentMode_ = Draw::PresentMode::FIFO;
|
||||
fastForwardSkipFlip_ = true;
|
||||
}
|
||||
Reference in new issue
Block a user