New feature!

There's a new option in the GS window configuration that allows a "managed Vsync".
This new option will dynamically toggle Vsync based on the current frame rate.
If the game runs at full speed, it turns Vsync on. If it drops below full speed, Vsync is turned off.

This effectively allows Vsync to be enabled in most games while avoiding the huge performance penalty
it usually causes whenever the FPS drop below full speed.

Note that the feature currently only works nicely with GSdx DX10/11 HW rendering.
The other renderers and plugins will either ignore the Vsync switches or they'll show an
annoying black frame on each switch.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4386 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2011-03-03 18:32:29 +00:00
parent fffd1328f2
commit b824ec5610
5 changed files with 79 additions and 3 deletions

View File

@ -279,6 +279,7 @@ struct Pcsx2Config
bool FrameLimitEnable;
bool FrameSkipEnable;
bool VsyncEnable;
bool ManagedVsync;
// The region mode controls the default Maximum/Minimum FPS settings and also
// regulates the vsync rates (which in turn control the IOP's SPU2 tick sync and ensure
@ -305,6 +306,7 @@ struct Pcsx2Config
OpEqu( FrameSkipEnable ) &&
OpEqu( FrameLimitEnable ) &&
OpEqu( VsyncEnable ) &&
OpEqu( ManagedVsync ) &&
OpEqu( LimitScalar ) &&
OpEqu( FramerateNTSC ) &&

View File

@ -202,6 +202,7 @@ Pcsx2Config::GSOptions::GSOptions()
FrameLimitEnable = true;
FrameSkipEnable = false;
VsyncEnable = false;
ManagedVsync = false;
SynchronousMTGS = false;
DisableOutput = false;
@ -227,6 +228,7 @@ void Pcsx2Config::GSOptions::LoadSave( IniInterface& ini )
IniEntry( FrameLimitEnable );
IniEntry( FrameSkipEnable );
IniEntry( VsyncEnable );
IniEntry( ManagedVsync );
IniEntry( LimitScalar );
IniEntry( FramerateNTSC );

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "MainFrame.h"
#include "GSFrame.h"
#include "GS.h"
#include "AppSaveStates.h"
#include "AppGameDatabase.h"
#include "AppAccelerators.h"
@ -435,7 +436,63 @@ void Pcsx2App::LogicalVsync()
// Update / Calculate framerate!
FpsManager.DoFrame();
if (EmuConfig.GS.ManagedVsync)
{
if ( g_LimiterMode == Limit_Nominal && EmuConfig.GS.VsyncEnable && g_Conf->EmuOptions.GS.FrameLimitEnable )
{
static bool last_enabled = 0;
static int too_slow = 0;
static int fast_enough = 0;
float fps = (float)FpsManager.GetFramerate();
if( gsRegionMode == Region_NTSC )
{
if (fps < 59.0f ) {
too_slow++;
fast_enough = 0;
if (too_slow > 4 && last_enabled == true)
{
last_enabled = false;
GSsetVsync( 0 );
}
}
else {
fast_enough++;
too_slow = 0;
if (fast_enough > 12 && last_enabled == false)
{
last_enabled = true;
GSsetVsync( 1 );
}
}
}
else
{
if (fps < 49.2f ) {
too_slow++;
fast_enough = 0;
if (too_slow > 3 && last_enabled == true)
{
last_enabled = false;
GSsetVsync( 0 );
}
}
else {
fast_enough++;
too_slow = 0;
if (fast_enough > 15 && last_enabled == false)
{
last_enabled = true;
GSsetVsync( 1 );
}
}
}
}
else
GSsetVsync( 0 );
}
// Only call PADupdate here if we're using GSopen2. Legacy GSopen plugins have the
// GS window belonging to the MTGS thread.
if( (PADupdate != NULL) && (GSopen2 != NULL) && (wxGetApp().GetGsFramePtr() != NULL) )

View File

@ -267,6 +267,7 @@ namespace Panels
pxCheckBox* m_check_CloseGS;
pxCheckBox* m_check_SizeLock;
pxCheckBox* m_check_VsyncEnable;
pxCheckBox* m_check_ManagedVsync;
pxCheckBox* m_check_Fullscreen;
pxCheckBox* m_check_ExclusiveFS;
pxCheckBox* m_check_HideMouse;

View File

@ -45,14 +45,23 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent )
m_check_HideMouse = new pxCheckBox( this, _("Always hide mouse cursor") );
m_check_CloseGS = new pxCheckBox( this, _("Hide window on suspend") );
m_check_Fullscreen = new pxCheckBox( this, _("Default to fullscreen mode on open") );
m_check_VsyncEnable = new pxCheckBox( this, _("Wait for vsync on refresh") );
m_check_DclickFullscreen = new pxCheckBox( this, _("Double-click Toggles Full-Screen mode") );
m_check_VsyncEnable = new pxCheckBox( this, _("Wait for Vsync on refresh") );
m_check_ManagedVsync = new pxCheckBox( this, _("Dynamically toggle Vsync depending on frame rate (read tooltip!)") );
m_check_DclickFullscreen = new pxCheckBox( this, _("Double-click toggles fullscreen mode") );
m_check_ExclusiveFS = new pxCheckBox( this, _("Use exclusive fullscreen mode (if available)") );
m_check_VsyncEnable->SetToolTip( pxEt( "!ContextTip:Window:Vsync",
L"Vsync eliminates screen tearing but typically has a big performance hit. "
L"It usually only applies to fullscreen mode, and may not work with all GS plugins."
) );
m_check_ManagedVsync->SetToolTip( pxEt( "!ContextTip:Window:ManagedVsync",
L"Enables Vsync when the framerate is exactly at full speed. "
L"Should it fall below that, Vsync gets disabled to avoid further performance penalties. "
L"Note: This currently only works well with GSdx as GS plugin and with it configured to use DX10/11 hardware rendering. "
L"Any other plugin or rendering mode will either ignore it or produce a black frame that blinks whenever the mode switches. "
L"It also requires Vsync to be enabled."
) );
m_check_HideMouse->SetToolTip( pxEt( "!ContextTip:Window:HideMouse",
L"Check this to force the mouse cursor invisible inside the GS window; useful if using "
@ -100,9 +109,11 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent )
*this += m_check_Fullscreen;
*this += m_check_DclickFullscreen;;
*this += m_check_ExclusiveFS;
*this += new wxStaticLine( this ) | StdExpand();
*this += m_check_VsyncEnable;
*this += m_check_ManagedVsync;
wxBoxSizer* centerSizer = new wxBoxSizer( wxVERTICAL );
*centerSizer += GetSizer() | pxCenter;
@ -130,6 +141,7 @@ void Panels::GSWindowSettingsPanel::ApplyConfigToGui( AppConfig& configToApply,
m_combo_AspectRatio ->SetSelection( (int)conf.AspectRatio );
m_check_VsyncEnable ->SetValue( configToApply.EmuOptions.GS.VsyncEnable );
m_check_ManagedVsync->SetValue( configToApply.EmuOptions.GS.ManagedVsync );
m_check_DclickFullscreen ->SetValue ( conf.IsToggleFullscreenOnDoubleClick );
@ -138,6 +150,7 @@ void Panels::GSWindowSettingsPanel::ApplyConfigToGui( AppConfig& configToApply,
}
m_check_VsyncEnable->Enable(!configToApply.EnablePresets);
m_check_ManagedVsync->Enable(!configToApply.EnablePresets);
}
void Panels::GSWindowSettingsPanel::Apply()
@ -153,6 +166,7 @@ void Panels::GSWindowSettingsPanel::Apply()
appconf.AspectRatio = (AspectRatioType)m_combo_AspectRatio->GetSelection();
gsconf.VsyncEnable = m_check_VsyncEnable->GetValue();
gsconf.ManagedVsync = m_check_ManagedVsync->GetValue();
appconf.IsToggleFullscreenOnDoubleClick = m_check_DclickFullscreen->GetValue();