Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
5.0 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "perfwizard.h"
  9. #include "tier0/platform.h"
  10. #include "con_nprint.h"
  11. #include "server.h"
  12. #include "client.h"
  13. #include "filesystem.h"
  14. #include "filesystem_engine.h"
  15. #include "KeyValues.h"
  16. #include "vstdlib/ICommandLine.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. //--------------------------------------------------------------------------------------------------------------
  20. ClientFPSTracker g_ClientFPSTracker;
  21. //--------------------------------------------------------------------------------------------------------------
  22. ClientFPSTracker::ClientFPSTracker()
  23. {
  24. Reset();
  25. }
  26. //--------------------------------------------------------------------------------------------------------------
  27. void ClientFPSTracker::Reset( void )
  28. {
  29. m_validTime = 0.0f; // not valid yet
  30. m_minNonServerFPS = -1.0f;
  31. m_maxNonServerFPS = -1.0f;
  32. m_nonServerFPSAverage = -1.0f;
  33. m_minAvgNonServerFPS = -1.0f;
  34. m_maxAvgNonServerFPS = -1.0f;
  35. }
  36. //--------------------------------------------------------------------------------------------------------------
  37. bool ClientFPSTracker::IsValid( void ) const
  38. {
  39. return m_maxAvgNonServerFPS > 0.0f;
  40. }
  41. //--------------------------------------------------------------------------------------------------------------
  42. void ClientFPSTracker::NPrint( int line ) const
  43. {
  44. #ifndef DEDICATED
  45. Con_NPrintf ( line++, "Min non-server FPS: %.0f", m_minNonServerFPS );
  46. Con_NPrintf ( line++, "Max non-server FPS: %.0f", m_maxNonServerFPS );
  47. line++;
  48. Con_NPrintf ( line++, "Avg non-server FPS: %.0f", m_nonServerFPSAverage );
  49. Con_NPrintf ( line++, "Min avg non-server FPS: %.0f", m_minAvgNonServerFPS );
  50. Con_NPrintf ( line++, "Max avg non-server FPS: %.0f", m_maxAvgNonServerFPS );
  51. #endif // !DEDICATED
  52. }
  53. //--------------------------------------------------------------------------------------------------------------
  54. void ClientFPSTracker::WriteData( void ) const
  55. {
  56. if ( IsValid() && !CommandLine()->FindParm( "-makereslists" ) )
  57. {
  58. KeyValues *data = new KeyValues( "perfdata" );
  59. data->SetFloat( "minClientFPS", m_minNonServerFPS );
  60. data->SetFloat( "maxClientFPS", m_maxNonServerFPS );
  61. data->SetFloat( "minAveragedClientFPS", m_minAvgNonServerFPS );
  62. data->SetFloat( "maxAveragedClientFPS", m_maxAvgNonServerFPS );
  63. data->SaveToFile( g_pFileSystem, "cfg/perfdata.vdf", "MOD" );
  64. data->deleteThis();
  65. }
  66. else
  67. {
  68. //g_pFileSystem->RemoveFile( "cfg/perfdata.vdf", "MOD" );
  69. }
  70. }
  71. //--------------------------------------------------------------------------------------------------------------
  72. void ClientFPSTracker::MarkFrame( float fps, float input, float client, float server, float render, float sound, float cl_dll, float exec )
  73. {
  74. if ( sv.IsDedicated() ) // client-side only, so skip if we're a dedicated server
  75. return;
  76. if ( !cl.IsActive() ) // we only care about the time that a client is in the game
  77. {
  78. m_validTime = 0.0f;
  79. return;
  80. }
  81. if ( m_validTime == 0.0f )
  82. {
  83. m_validTime = Plat_FloatTime() + 10.0f; // allow some settling down
  84. return;
  85. }
  86. else
  87. {
  88. if ( m_validTime > Plat_FloatTime() )
  89. {
  90. return; // don't track fps in the settling-down phase after loading
  91. }
  92. }
  93. // Construct a client FPS by using every time component but the server. This helps on listenservers,
  94. // since the performance wizard won't be able to do anything about server perf anyway.
  95. double nonServerFrameTime = (input + client + render + sound + cl_dll + exec) / 1000.0f;
  96. double nonServerFps;
  97. if ( nonServerFrameTime < 0.0001 )
  98. {
  99. nonServerFps = 999.0;
  100. }
  101. else
  102. {
  103. nonServerFps = 1.0 / nonServerFrameTime;
  104. }
  105. // Track min/max instantaneous FPS
  106. if ( m_minNonServerFPS < 0.0f )
  107. {
  108. m_minNonServerFPS = m_maxNonServerFPS = nonServerFps;
  109. }
  110. else
  111. {
  112. if ( nonServerFps < m_minNonServerFPS ) m_minNonServerFPS = nonServerFps;
  113. if ( nonServerFps > m_maxNonServerFPS ) m_maxNonServerFPS = nonServerFps;
  114. }
  115. // Construct an average FPS (this isn't really an average, since it weights the current frame AverageFraction, the previous frame by AverageFraction*AverageFraction, etc)
  116. const float AverageFraction = 0.99f;
  117. if ( m_nonServerFPSAverage < 0.0f )
  118. {
  119. m_nonServerFPSAverage = nonServerFps;
  120. }
  121. m_nonServerFPSAverage = m_nonServerFPSAverage * AverageFraction + ( 1.0f - AverageFraction ) * nonServerFps;
  122. // Track min/max averaged FPS. These are the useful values for making performance recommendations.
  123. if ( m_minAvgNonServerFPS < 0.0f )
  124. {
  125. m_minAvgNonServerFPS = m_maxAvgNonServerFPS = m_nonServerFPSAverage;
  126. }
  127. else
  128. {
  129. if ( m_nonServerFPSAverage < m_minAvgNonServerFPS ) m_minAvgNonServerFPS = m_nonServerFPSAverage;
  130. if ( m_nonServerFPSAverage > m_maxAvgNonServerFPS ) m_maxAvgNonServerFPS = m_nonServerFPSAverage;
  131. }
  132. // Debug printing for test purposes.
  133. //NPrint( 10 );
  134. }
  135. //--------------------------------------------------------------------------------------------------------------