|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "perfwizard.h"
#include "tier0/platform.h"
#include "con_nprint.h"
#include "server.h"
#include "client.h"
#include "filesystem.h"
#include "filesystem_engine.h"
#include "KeyValues.h"
#include "vstdlib/ICommandLine.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//--------------------------------------------------------------------------------------------------------------
ClientFPSTracker g_ClientFPSTracker;
//--------------------------------------------------------------------------------------------------------------
ClientFPSTracker::ClientFPSTracker() { Reset(); }
//--------------------------------------------------------------------------------------------------------------
void ClientFPSTracker::Reset( void ) { m_validTime = 0.0f; // not valid yet
m_minNonServerFPS = -1.0f; m_maxNonServerFPS = -1.0f;
m_nonServerFPSAverage = -1.0f;
m_minAvgNonServerFPS = -1.0f; m_maxAvgNonServerFPS = -1.0f; }
//--------------------------------------------------------------------------------------------------------------
bool ClientFPSTracker::IsValid( void ) const { return m_maxAvgNonServerFPS > 0.0f; }
//--------------------------------------------------------------------------------------------------------------
void ClientFPSTracker::NPrint( int line ) const { #ifndef DEDICATED
Con_NPrintf ( line++, "Min non-server FPS: %.0f", m_minNonServerFPS ); Con_NPrintf ( line++, "Max non-server FPS: %.0f", m_maxNonServerFPS );
line++; Con_NPrintf ( line++, "Avg non-server FPS: %.0f", m_nonServerFPSAverage ); Con_NPrintf ( line++, "Min avg non-server FPS: %.0f", m_minAvgNonServerFPS ); Con_NPrintf ( line++, "Max avg non-server FPS: %.0f", m_maxAvgNonServerFPS ); #endif // !DEDICATED
}
//--------------------------------------------------------------------------------------------------------------
void ClientFPSTracker::WriteData( void ) const { if ( IsValid() && !CommandLine()->FindParm( "-makereslists" ) ) { KeyValues *data = new KeyValues( "perfdata" ); data->SetFloat( "minClientFPS", m_minNonServerFPS ); data->SetFloat( "maxClientFPS", m_maxNonServerFPS ); data->SetFloat( "minAveragedClientFPS", m_minAvgNonServerFPS ); data->SetFloat( "maxAveragedClientFPS", m_maxAvgNonServerFPS ); data->SaveToFile( g_pFileSystem, "cfg/perfdata.vdf", "MOD" ); data->deleteThis(); } else { //g_pFileSystem->RemoveFile( "cfg/perfdata.vdf", "MOD" );
} }
//--------------------------------------------------------------------------------------------------------------
void ClientFPSTracker::MarkFrame( float fps, float input, float client, float server, float render, float sound, float cl_dll, float exec ) { if ( sv.IsDedicated() ) // client-side only, so skip if we're a dedicated server
return;
if ( !cl.IsActive() ) // we only care about the time that a client is in the game
{ m_validTime = 0.0f; return; }
if ( m_validTime == 0.0f ) { m_validTime = Plat_FloatTime() + 10.0f; // allow some settling down
return; } else { if ( m_validTime > Plat_FloatTime() ) { return; // don't track fps in the settling-down phase after loading
} }
// Construct a client FPS by using every time component but the server. This helps on listenservers,
// since the performance wizard won't be able to do anything about server perf anyway.
double nonServerFrameTime = (input + client + render + sound + cl_dll + exec) / 1000.0f; double nonServerFps;
if ( nonServerFrameTime < 0.0001 ) { nonServerFps = 999.0; } else { nonServerFps = 1.0 / nonServerFrameTime; }
// Track min/max instantaneous FPS
if ( m_minNonServerFPS < 0.0f ) { m_minNonServerFPS = m_maxNonServerFPS = nonServerFps; } else { if ( nonServerFps < m_minNonServerFPS ) m_minNonServerFPS = nonServerFps; if ( nonServerFps > m_maxNonServerFPS ) m_maxNonServerFPS = nonServerFps; }
// Construct an average FPS (this isn't really an average, since it weights the current frame AverageFraction, the previous frame by AverageFraction*AverageFraction, etc)
const float AverageFraction = 0.99f; if ( m_nonServerFPSAverage < 0.0f ) { m_nonServerFPSAverage = nonServerFps; }
m_nonServerFPSAverage = m_nonServerFPSAverage * AverageFraction + ( 1.0f - AverageFraction ) * nonServerFps;
// Track min/max averaged FPS. These are the useful values for making performance recommendations.
if ( m_minAvgNonServerFPS < 0.0f ) { m_minAvgNonServerFPS = m_maxAvgNonServerFPS = m_nonServerFPSAverage; } else { if ( m_nonServerFPSAverage < m_minAvgNonServerFPS ) m_minAvgNonServerFPS = m_nonServerFPSAverage; if ( m_nonServerFPSAverage > m_maxAvgNonServerFPS ) m_maxAvgNonServerFPS = m_nonServerFPSAverage; }
// Debug printing for test purposes.
//NPrint( 10 );
}
//--------------------------------------------------------------------------------------------------------------
|