From 185d3d902dda27b573257bcc588a82abaed9e6a7 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 5 Apr 2006 05:36:04 +0000 Subject: [PATCH] It's RageDisplay::EndFrame()'s job to give up CPU between frames. Currently, we're doing this partially in EndFrame (in FrameLimitBeforeVsync and/or the actual vblank wait), and partially in RunGameLoop. These serve the same purpose, so merge them. (The renderer itself should have more control over this, but this is an improvement.) --- stepmania/src/GameLoop.cpp | 11 ---------- stepmania/src/RageDisplay.cpp | 40 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/stepmania/src/GameLoop.cpp b/stepmania/src/GameLoop.cpp index 49b1433ac6..b9b3b599b2 100644 --- a/stepmania/src/GameLoop.cpp +++ b/stepmania/src/GameLoop.cpp @@ -179,17 +179,6 @@ void GameLoop::RunGameLoop() * Render */ SCREENMAN->Draw(); - - /* If we don't have focus, give up lots of CPU. */ - // XXX: do this in DISPLAY EndFrame? - if( !HOOKS->AppHasFocus() ) - usleep( 10000 );// give some time to other processes and threads -#if defined(_WINDOWS) - /* In Windows, we want to give up some CPU for other threads. Most OS's do - * this more intelligently. */ - else - usleep( 1000 ); // give some time to other processes and threads -#endif } if( ChangeAppPri() ) diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp index f08f86b112..28c96d9fb3 100644 --- a/stepmania/src/RageDisplay.cpp +++ b/stepmania/src/RageDisplay.cpp @@ -11,6 +11,7 @@ #include "RageSurface.h" #include "Preference.h" #include "LocalizedString.h" +#include "arch/ArchHooks/ArchHooks.h" // // Statistics stuff @@ -774,24 +775,33 @@ void RageDisplay::FrameLimitBeforeVsync( int iFPS ) { ASSERT( iFPS != 0 ); - if( g_LastFrameEndedAt.IsZero() ) - return; + int iDelayMicroseconds = 0; + if( g_fFrameLimitPercent.Get() > 0.0f && !g_LastFrameEndedAt.IsZero() ) + { + float fFrameTime = g_LastFrameEndedAt.GetDeltaTime(); + float fExpectedTime = 1.0f / iFPS; - if( g_fFrameLimitPercent.Get() == 0.0f ) - return; + /* This is typically used to turn some of the delay that would normally + * be waiting for vsync and turn it into a usleep, to make sure we give + * up the CPU. If we overshoot the sleep, then we'll miss the vsync, + * so allow tweaking the amount of time we expect a frame to take. + * Frame limiting is disabled by setting this to 0. */ + fExpectedTime *= g_fFrameLimitPercent.Get(); + float fExtraTime = fExpectedTime - fFrameTime; - float fFrameTime = g_LastFrameEndedAt.GetDeltaTime(); - float fExpectedTime = 1.0f / iFPS; + iDelayMicroseconds = int(fExtraTime * 1000000); + } - /* This is typically used to turn some of the delay that would normally - * be waiting for vsync and turn it into a usleep, to make sure we give - * up the CPU. If we overshoot the sleep, then we'll miss the vsync, - * so allow tweaking the amount of time we expect a frame to take. - * Frame limiting is disabled by setting this to 0. */ - fExpectedTime *= g_fFrameLimitPercent.Get(); - float fExtraTime = fExpectedTime - fFrameTime; - if( fExtraTime > 0 ) - usleep( int(fExtraTime * 1000000) ); + if( !HOOKS->AppHasFocus() ) + iDelayMicroseconds = max( iDelayMicroseconds, 10000 ); // give some time to other processes and threads + +#if defined(_WINDOWS) + /* In Windows, always explicitly give up a minimum amount of CPU for other threads. */ + iDelayMicroseconds = max( iDelayMicroseconds, 1000 ); +#endif + + if( iDelayMicroseconds > 0 ) + usleep( iDelayMicroseconds ); } void RageDisplay::FrameLimitAfterVsync()