mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-24 19:00:54 +00:00
Watch for consistently high flips, not spurts.
This commit is contained in:
parent
e3d0e4bdfa
commit
57d057d661
@ -115,6 +115,8 @@ static int actualFlips = 0; // taking frameskip into account
|
||||
static int lastActualFlips = 0;
|
||||
static float actualFps = 0;
|
||||
static u64 lastFlipCycles = 0;
|
||||
// For the "max 60 fps" setting.
|
||||
static int lastFlipsTooFrequent = 0;
|
||||
|
||||
void hleEnterVblank(u64 userdata, int cyclesLate);
|
||||
void hleLeaveVblank(u64 userdata, int cyclesLate);
|
||||
@ -135,6 +137,7 @@ void __DisplayInit() {
|
||||
framebuf.pspFramebufFormat = GE_FORMAT_8888;
|
||||
framebuf.pspFramebufLinesize = 480; // ??
|
||||
lastFlipCycles = 0;
|
||||
lastFlipsTooFrequent = 0;
|
||||
|
||||
enterVblankEvent = CoreTiming::RegisterEvent("EnterVBlank", &hleEnterVblank);
|
||||
leaveVblankEvent = CoreTiming::RegisterEvent("LeaveVBlank", &hleLeaveVblank);
|
||||
@ -520,16 +523,27 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync)
|
||||
}
|
||||
|
||||
s64 delayCycles = 0;
|
||||
if (topaddr != framebuf.topaddr) {
|
||||
if (g_Config.iForceMaxEmulatedFPS) {
|
||||
u64 now = CoreTiming::GetTicks();
|
||||
u64 expected = msToCycles(1000) / g_Config.iForceMaxEmulatedFPS;
|
||||
u64 actual = now - lastFlipCycles;
|
||||
if (actual < expected) {
|
||||
if (topaddr != framebuf.topaddr && g_Config.iForceMaxEmulatedFPS > 0) {
|
||||
// Sometimes we get a small number, there's probably no need to delay the thread for this.
|
||||
// sceDisplaySetFramebuf() isn't supposed to delay threads at all. This is a hack.
|
||||
const int FLIP_DELAY_CYCLES_MIN = 10;
|
||||
// Some games (like Final Fantasy 4) only call this too much in spurts.
|
||||
// The goal is to fix games where this would result in a consistent overhead.
|
||||
const int FLIP_DELAY_MIN_FLIPS = 30;
|
||||
|
||||
u64 now = CoreTiming::GetTicks();
|
||||
u64 expected = msToCycles(1000) / g_Config.iForceMaxEmulatedFPS;
|
||||
u64 actual = now - lastFlipCycles;
|
||||
if (actual < expected - FLIP_DELAY_CYCLES_MIN) {
|
||||
if (lastFlipsTooFrequent >= FLIP_DELAY_MIN_FLIPS) {
|
||||
delayCycles = expected - actual;
|
||||
} else {
|
||||
++lastFlipsTooFrequent;
|
||||
}
|
||||
lastFlipCycles = CoreTiming::GetTicks();
|
||||
} else {
|
||||
--lastFlipsTooFrequent;
|
||||
}
|
||||
lastFlipCycles = CoreTiming::GetTicks();
|
||||
}
|
||||
|
||||
if (sync == PSP_DISPLAY_SETBUF_IMMEDIATE) {
|
||||
@ -549,6 +563,7 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync)
|
||||
if (delayCycles > 0) {
|
||||
// Okay, the game is going at too high a frame rate. God of War and Fat Princess both do this.
|
||||
// Simply eating the cycles works and is fast, but breaks other games (like Jeanne d'Arc.)
|
||||
// So, instead, we delay this HLE thread only (a small deviation from correct behavior.)
|
||||
return hleDelayResult(0, "set framebuf", cyclesToUs(delayCycles));
|
||||
} else {
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user