Very rough and basic implementation of frameskipping.

This commit is contained in:
Henrik Rydgard 2013-02-19 00:44:22 +01:00
parent 7c91802e3c
commit 1aa3a657c0
8 changed files with 69 additions and 22 deletions

View file

@ -68,6 +68,7 @@ void CConfig::Load(const char *iniFileName)
graphics->Get("LinearFiltering", &bLinearFiltering, false);
graphics->Get("SSAA", &SSAntiAliasing, 0);
graphics->Get("VBO", &bUseVBO, false);
graphics->Get("FrameSkip", &iFrameSkip, 0);
#ifdef USING_GLES2
graphics->Get("AnisotropyLevel", &iAnisotropyLevel, 0);
#else
@ -131,6 +132,7 @@ void CConfig::Save()
graphics->Set("LinearFiltering", bLinearFiltering);
graphics->Set("SSAA", SSAntiAliasing);
graphics->Set("VBO", bUseVBO);
graphics->Set("FrameSkip", iFrameSkip);
graphics->Set("AnisotropyLevel", iAnisotropyLevel);
graphics->Set("DisableG3DLog", bDisableG3DLog);
graphics->Set("VertexCache", bVertexCache);

View file

@ -59,6 +59,7 @@ public:
bool bLinearFiltering;
bool bUseVBO;
bool bStretchToDisplay;
int iFrameSkip; // 0 = off; 1 = auto; (future: 2 = skip every 2nd frame; 3 = skip every 3rd frame etc).
int iWindowZoom; // for Windows
bool SSAntiAliasing; //for Windows, too

View file

@ -89,7 +89,8 @@ static int isVblank;
static int numSkippedFrames;
static bool hasSetMode;
// Don't include this in the state, time increases regardless of state.
static double lastFrameTime;
static double curFrameTime;
static double nextFrameTime;
std::vector<WaitVBlankInfo> vblankWaitingThreads;
@ -129,7 +130,8 @@ void __DisplayInit() {
vCount = 0;
hCount = 0;
hCountTotal = 0;
lastFrameTime = 0;
curFrameTime = 0.0;
nextFrameTime = 0.0;
InitGfxState();
}
@ -191,7 +193,7 @@ float calculateFPS()
static int lastFpsFrame = 0;
static double lastFpsTime = 0.0;
static double fps = 0.0;
time_update();
double now = time_now_d();
@ -274,25 +276,56 @@ void DoFrameTiming(bool &throttle, bool &skipFrame, bool &skipFlip) {
#endif
skipFlip = false;
skipFrame = false;
if (PSP_CoreParameter().headLess)
throttle = false;
if (throttle) {
// Best place to throttle the frame rate on non vsynced platforms is probably here. Let's try it.
time_update();
if (lastFrameTime == 0.0)
lastFrameTime = time_now_d();
// First, check if we are already behind.
// Wait until it's time.
while (time_now_d() < lastFrameTime + 1.0 / 60.0) {
Common::SleepCurrentThread(1);
time_update();
// Check if the frameskipping code should be enabled. If neither throttling or frameskipping is on,
// we have nothing to do here.
bool doFrameSkip = g_Config.iFrameSkip == 1;
if (!throttle && !doFrameSkip)
return;
time_update();
curFrameTime = time_now_d();
if (nextFrameTime == 0.0)
nextFrameTime = time_now_d() + 1.0 / 60.0;
if (curFrameTime > nextFrameTime && doFrameSkip) {
// Argh, we are falling behind! Let's skip a frame and see if we catch up.
skipFrame = true;
skipFlip = true;
INFO_LOG(HLE,"FRAMESKIP %i", numSkippedFrames);
}
if (curFrameTime < nextFrameTime && throttle)
{
// If time gap is huge just jump (somebody unthrottled)
if (nextFrameTime - curFrameTime > 1.0 / 30.0) {
nextFrameTime = curFrameTime + 1.0 / 60.0;
} else {
// Wait until we've catched up.
while (time_now_d() < nextFrameTime) {
Common::SleepCurrentThread(1);
time_update();
}
}
// Advance lastFrameTime by a constant amount each frame,
// but don't let it get too far behind.
lastFrameTime = std::max(lastFrameTime + 1.0 / 60.0, time_now_d() - 1.5 / 60.0);
curFrameTime = time_now_d();
}
// Advance lastFrameTime by a constant amount each frame,
// but don't let it get too far behind as things can get very jumpy.
const double maxFallBehindFrames = 5.5;
if (throttle || doFrameSkip) {
nextFrameTime = std::max(nextFrameTime + 1.0 / 60.0, time_now_d() - maxFallBehindFrames / 60.0);
} else {
nextFrameTime = nextFrameTime + 1.0 / 60.0;
}
// Max 6 skipped frames in a row - 10 fps is really the bare minimum for playability.
if (numSkippedFrames >= 4) {
skipFrame = false;
skipFlip = false;
}
}

View file

@ -209,10 +209,12 @@
<None Include="..\android\atlasscript.txt">
<Filter>Android</Filter>
</None>
<None Include="..\CMakeLists.txt" />
<None Include="..\android\jni\Application.mk">
<Filter>Android</Filter>
</None>
<None Include="..\CMakeLists.txt">
<Filter>Windows</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ppsspp.rc">

View file

@ -73,8 +73,7 @@ namespace MainWindow
void Init(HINSTANCE hInstance)
{
#ifdef THEMES
WTL::CTheme::IsThemingSupported();
#ifdef THEMES WTL::CTheme::IsThemingSupported();
#endif
//Register classes
WNDCLASSEX wcex;
@ -447,6 +446,11 @@ namespace MainWindow
gpu->Resized(); // easy way to force a clear...
break;
case ID_OPTIONS_FRAMESKIP:
g_Config.iFrameSkip = !g_Config.iFrameSkip;
UpdateMenus();
break;
case ID_FILE_EXIT:
DestroyWindow(hWnd);
break;
@ -712,6 +716,7 @@ namespace MainWindow
CHECKITEM(ID_OPTIONS_DISABLEG3DLOG, g_Config.bDisableG3DLog);
CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache);
CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.bShowFPSCounter);
CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != 0);
UINT enable = !Core_IsStepping() ? MF_GRAYED : MF_ENABLED;
EnableMenuItem(menu,ID_EMULATION_RUN, g_State.bEmuThreadStarted ? enable : MF_GRAYED);

Binary file not shown.

View file

@ -260,6 +260,7 @@
#define ID_OPTIONS_VERTEXCACHE 40136
#define ID_OPTIONS_SHOWFPS 40137
#define ID_OPTIONS_STRETCHDISPLAY 40138
#define ID_OPTIONS_FRAMESKIP 40139
#define IDC_STATIC -1
// Next default values for new objects
@ -267,7 +268,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 233
#define _APS_NEXT_COMMAND_VALUE 40139
#define _APS_NEXT_COMMAND_VALUE 40140
#define _APS_NEXT_CONTROL_VALUE 1163
#define _APS_NEXT_SYMED_VALUE 101
#endif

View file

@ -251,6 +251,9 @@ void InGameMenuScreen::render() {
UICheckBox(GEN_ID, x, y += 50, "Stretch to display", ALIGN_TOPLEFT, &g_Config.bStretchToDisplay);
UICheckBox(GEN_ID, x, y += 50, "Hardware Transform", ALIGN_TOPLEFT, &g_Config.bHardwareTransform);
bool fs = g_Config.iFrameSkip == 1;
UICheckBox(GEN_ID, x, y += 50, "Frameskip", ALIGN_TOPLEFT, &fs);
g_Config.iFrameSkip = fs ? 1 : 0;
// TODO: Add UI for more than one slot.
VLinear vlinear1(x, y + 80, 20);