Team Fortress 2 Source Code as on 22/4/2020
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.

372 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "client_pch.h"
  7. #include "vgui_texturebudgetpanel.h"
  8. #include "vgui_controls/Label.h"
  9. #include "VGuiMatSurface/IMatSystemSurface.h"
  10. #include "vgui_baseui_interface.h"
  11. #include "ivideomode.h"
  12. // memdbgon must be the last include file in a .cpp file!!!
  13. #include "tier0/memdbgon.h"
  14. #ifdef VPROF_ENABLED
  15. // Globals.
  16. static CTextureBudgetPanel *g_pTextureBudgetPanel = NULL;
  17. static void TextureCVarChangedCallBack( IConVar *pConVar, const char *pOldString, float flOldValue );
  18. ConVar texture_budget_panel_global( "texture_budget_panel_global", "0", 0, "Show global times in the texture budget panel." );
  19. ConVar showbudget_texture( "showbudget_texture", "0", FCVAR_CHEAT, "Enable the texture budget panel." );
  20. ConVar showbudget_texture_global_sum( "showbudget_texture_global_sum", "0.0f" );
  21. // Commands to turn on the texture budget panel, with per-FRAME settings.
  22. void showbudget_texture_on_f()
  23. {
  24. texture_budget_panel_global.SetValue( 0 );
  25. showbudget_texture.SetValue( 1 );
  26. }
  27. void showbudget_texture_off_f()
  28. {
  29. showbudget_texture.SetValue( 0 );
  30. }
  31. ConCommand showbudget_texture_on( "+showbudget_texture", showbudget_texture_on_f, "", FCVAR_CHEAT );
  32. ConCommand showbudget_texture_off( "-showbudget_texture", showbudget_texture_off_f, "", FCVAR_CHEAT );
  33. // Commands to turn on the texture budget panel, with GLOBAL settings.
  34. void showbudget_texture_global_on_f()
  35. {
  36. texture_budget_panel_global.SetValue( 1 );
  37. showbudget_texture.SetValue( 1 );
  38. }
  39. void showbudget_texture_global_off_f()
  40. {
  41. showbudget_texture.SetValue( 0 );
  42. }
  43. ConCommand showbudget_texture_global_on( "+showbudget_texture_global", showbudget_texture_global_on_f, "", FCVAR_CHEAT );
  44. ConCommand showbudget_texture_global_off( "-showbudget_texture_global", showbudget_texture_global_off_f, "", FCVAR_CHEAT );
  45. ConVar texture_budget_panel_x( "texture_budget_panel_x", "0", FCVAR_ARCHIVE, "number of pixels from the left side of the game screen to draw the budget panel", TextureCVarChangedCallBack );
  46. ConVar texture_budget_panel_y( "texture_budget_panel_y", "450", FCVAR_ARCHIVE, "number of pixels from the top side of the game screen to draw the budget panel", TextureCVarChangedCallBack );
  47. ConVar texture_budget_panel_width( "texture_budget_panel_width", "512", FCVAR_ARCHIVE, "width in pixels of the budget panel", TextureCVarChangedCallBack );
  48. ConVar texture_budget_panel_height( "texture_budget_panel_height", "284", FCVAR_ARCHIVE, "height in pixels of the budget panel", TextureCVarChangedCallBack );
  49. ConVar texture_budget_panel_bottom_of_history_fraction( "texture_budget_panel_bottom_of_history_fraction", ".25", FCVAR_ARCHIVE, "number between 0 and 1", TextureCVarChangedCallBack );
  50. ConVar texture_budget_background_alpha( "texture_budget_background_alpha", "128", FCVAR_ARCHIVE, "how translucent the budget panel is" );
  51. CTextureBudgetPanel *GetTextureBudgetPanel( void )
  52. {
  53. return g_pTextureBudgetPanel;
  54. }
  55. static void TextureCVarChangedCallBack( IConVar *pConVar, const char *pOldString, float flOldValue )
  56. {
  57. if ( GetTextureBudgetPanel() )
  58. {
  59. GetTextureBudgetPanel()->OnCVarStateChanged();
  60. }
  61. }
  62. CTextureBudgetPanel::CTextureBudgetPanel( vgui::Panel *pParent, const char *pElementName )
  63. : BaseClass( pParent, pElementName )
  64. {
  65. m_LastCounterGroup = -1;
  66. g_pTextureBudgetPanel = this;
  67. m_MaxValue = 1000;
  68. m_SumOfValues = 0;
  69. m_pModeLabel = new vgui::Label( this, "mode label", "" );
  70. m_pModeLabel->SetParent( pParent );
  71. SetVisible( false );
  72. vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
  73. }
  74. CTextureBudgetPanel::~CTextureBudgetPanel()
  75. {
  76. Assert( g_pTextureBudgetPanel == this );
  77. g_pTextureBudgetPanel = NULL;
  78. if ( m_pModeLabel )
  79. {
  80. delete m_pModeLabel;
  81. m_pModeLabel = NULL;
  82. }
  83. }
  84. void CTextureBudgetPanel::OnTick()
  85. {
  86. BaseClass::OnTick();
  87. if ( showbudget_texture.GetBool() )
  88. {
  89. m_pModeLabel->SetVisible( true );
  90. SetVisible( true );
  91. }
  92. else
  93. {
  94. m_pModeLabel->SetVisible( false );
  95. SetVisible( false );
  96. }
  97. }
  98. void CTextureBudgetPanel::Paint()
  99. {
  100. SnapshotTextureHistory();
  101. g_VProfCurrentProfile.ResetCounters( COUNTER_GROUP_TEXTURE_PER_FRAME );
  102. BaseClass::Paint();
  103. }
  104. void CTextureBudgetPanel::SendConfigDataToBase()
  105. {
  106. // Setup all the data.
  107. CBudgetPanelConfigData data;
  108. // Copy the budget group names in.
  109. for ( int i=0; i < g_VProfCurrentProfile.GetNumCounters(); i++ )
  110. {
  111. if ( g_VProfCurrentProfile.GetCounterGroup( i ) == GetCurrentCounterGroup() )
  112. {
  113. // Strip off the TexGroup__ prefix.
  114. const char *pGroupName = g_VProfCurrentProfile.GetCounterName( i );
  115. const char *pPrefixes[2] = { "TexGroup_global_", "TexGroup_frame_" };
  116. for ( int iPrefix=0; iPrefix < 2; iPrefix++ )
  117. {
  118. char alternateName[256];
  119. if ( strstr( pGroupName, pPrefixes[iPrefix] ) == pGroupName )
  120. {
  121. int len = strlen( pPrefixes[iPrefix] );
  122. Q_strncpy( alternateName, &pGroupName[len], len );
  123. alternateName[len] = 0;
  124. pGroupName = alternateName;
  125. break;
  126. }
  127. }
  128. CBudgetGroupInfo info;
  129. int r, g, b, a;
  130. g_VProfCurrentProfile.GetBudgetGroupColor( data.m_BudgetGroupInfo.Count(), r, g, b, a );
  131. info.m_Color.SetColor( r, g, b, a );
  132. info.m_Name = pGroupName;
  133. data.m_BudgetGroupInfo.AddToTail( info );
  134. }
  135. }
  136. // Copy all the cvars in.
  137. data.m_flBottomOfHistoryFraction = texture_budget_panel_bottom_of_history_fraction.GetFloat();
  138. data.m_flBarGraphRange = (m_MaxValue * 4) / 3;
  139. data.m_flTimeLabelInterval = data.m_flBarGraphRange / 4;
  140. data.m_nLinesPerTimeLabel = 4;
  141. data.m_flHistoryRange = (m_SumOfValues * 4) / 3;
  142. // Use the middle three fifths for history labels.
  143. data.m_HistoryLabelValues.SetSize( 3 );
  144. for ( int i=0; i < data.m_HistoryLabelValues.Count(); i++ )
  145. {
  146. data.m_HistoryLabelValues[i] = (i+1) * data.m_flHistoryRange / 4;
  147. }
  148. data.m_flBackgroundAlpha = texture_budget_background_alpha.GetFloat();
  149. data.m_xCoord = texture_budget_panel_x.GetInt();
  150. data.m_yCoord = texture_budget_panel_y.GetInt();
  151. data.m_Width = texture_budget_panel_width.GetInt();
  152. data.m_Height = texture_budget_panel_height.GetInt();
  153. // Shift it..
  154. if ( data.m_xCoord + data.m_Width > videomode->GetModeStereoWidth() )
  155. {
  156. data.m_xCoord = videomode->GetModeStereoWidth() - data.m_Width;
  157. }
  158. if ( data.m_yCoord + data.m_Height > videomode->GetModeStereoHeight() )
  159. {
  160. data.m_yCoord = videomode->GetModeStereoHeight() - data.m_Height;
  161. }
  162. // Send the config data to the base class.
  163. OnConfigDataChanged( data );
  164. }
  165. void CTextureBudgetPanel::PerformLayout()
  166. {
  167. BaseClass::PerformLayout();
  168. // Update our label that tells what kind of data we are.
  169. const char *pStr = "Per-frame texture stats";
  170. if ( texture_budget_panel_global.GetInt() )
  171. pStr = "Global texture stats";
  172. m_pModeLabel->SetText( pStr );
  173. int width = g_pMatSystemSurface->DrawTextLen( m_pModeLabel->GetFont(), "%s", pStr );
  174. m_pModeLabel->SetSize( width + 10, m_pModeLabel->GetTall() );
  175. int x, y;
  176. GetPos( x, y );
  177. m_pModeLabel->SetPos( x, y - m_pModeLabel->GetTall() );
  178. m_pModeLabel->SetFgColor( Color( 255, 255, 255, 255 ) );
  179. m_pModeLabel->SetBgColor( Color( 0, 0, 0, texture_budget_background_alpha.GetInt() ) );
  180. }
  181. void CTextureBudgetPanel::OnCVarStateChanged()
  182. {
  183. SendConfigDataToBase();
  184. }
  185. CounterGroup_t CTextureBudgetPanel::GetCurrentCounterGroup() const
  186. {
  187. if ( texture_budget_panel_global.GetInt() )
  188. return COUNTER_GROUP_TEXTURE_GLOBAL;
  189. else
  190. return COUNTER_GROUP_TEXTURE_PER_FRAME;
  191. }
  192. void CTextureBudgetPanel::SnapshotTextureHistory()
  193. {
  194. // Now sample all the data.
  195. CVProfile *pProf = &g_VProfCurrentProfile;
  196. m_SumOfValues = 0;
  197. for ( int i=0; i < pProf->GetNumCounters(); i++ )
  198. {
  199. if ( pProf->GetCounterGroup( i ) == GetCurrentCounterGroup() )
  200. {
  201. // The counters are in bytes and the panel is all in kilobytes.
  202. int value = pProf->GetCounterValue( i ) / 1024;
  203. m_SumOfValues += value;
  204. m_MaxValue = max( m_MaxValue, value );
  205. }
  206. }
  207. showbudget_texture_global_sum.SetValue( m_SumOfValues );
  208. // Send new config data if the range has expanded.
  209. bool bForceSendConfigData = false;
  210. if ( (float)m_MaxValue > GetConfigData().m_flBarGraphRange || m_SumOfValues > GetConfigData().m_flHistoryRange )
  211. {
  212. bForceSendConfigData = true;
  213. }
  214. // If we switched counter groups, reset everything.
  215. if ( m_LastCounterGroup != GetCurrentCounterGroup() )
  216. {
  217. ResetAll();
  218. m_LastCounterGroup = GetCurrentCounterGroup();
  219. }
  220. // Count up the current number of counters.
  221. int nCounters = 0;
  222. for ( int i=0; i < g_VProfCurrentProfile.GetNumCounters(); i++ )
  223. {
  224. if ( g_VProfCurrentProfile.GetCounterGroup( i ) == GetCurrentCounterGroup() )
  225. ++nCounters;
  226. }
  227. // Do we need to reset all the data?
  228. if ( bForceSendConfigData || nCounters != GetNumCachedBudgetGroups() )
  229. {
  230. SendConfigDataToBase();
  231. }
  232. // Now update the data for this frame.
  233. m_BudgetHistoryOffset = ( m_BudgetHistoryOffset + 1 ) % BUDGET_HISTORY_COUNT;
  234. int groupID = 0;
  235. for ( int i=0; i < pProf->GetNumCounters(); i++ )
  236. {
  237. if ( pProf->GetCounterGroup( i ) == GetCurrentCounterGroup() )
  238. {
  239. // The counters are in bytes and the panel is all in kilobytes.
  240. int value = pProf->GetCounterValue( i ) / 1024;
  241. m_BudgetGroupTimes[groupID].m_Time[m_BudgetHistoryOffset] = value;
  242. ++groupID;
  243. }
  244. }
  245. }
  246. void CTextureBudgetPanel::SetTimeLabelText()
  247. {
  248. for ( int i=0; i < m_TimeLabels.Count(); i++ )
  249. {
  250. char text[512];
  251. Q_snprintf( text, sizeof( text ), "%.1fM", (float)( i * GetConfigData().m_flTimeLabelInterval ) / 1024 );
  252. m_TimeLabels[i]->SetText( text );
  253. }
  254. }
  255. void CTextureBudgetPanel::SetHistoryLabelText()
  256. {
  257. for ( int i=0; i < m_HistoryLabels.Count(); i++ )
  258. {
  259. char text[512];
  260. Q_snprintf( text, sizeof( text ), "%.1fM", GetConfigData().m_HistoryLabelValues[i] / 1024 );
  261. m_HistoryLabels[i]->SetText( text );
  262. }
  263. }
  264. void CTextureBudgetPanel::ResetAll()
  265. {
  266. BaseClass::ResetAll();
  267. m_MaxValue = 0;
  268. m_SumOfValues = 0;
  269. }
  270. void CTextureBudgetPanel::DumpGlobalTextureStats( const CCommand &args )
  271. {
  272. // Setup all the data.
  273. CBudgetPanelConfigData data;
  274. // Copy the budget group names in.
  275. for ( int i=0; i < g_VProfCurrentProfile.GetNumCounters(); i++ )
  276. {
  277. if ( g_VProfCurrentProfile.GetCounterGroup( i ) == COUNTER_GROUP_TEXTURE_GLOBAL )
  278. {
  279. // Strip off the TexGroup__ prefix.
  280. const char *pGroupName = g_VProfCurrentProfile.GetCounterName( i );
  281. // The counters are in bytes and the panel is all in kilobytes.
  282. // int value = pProf->GetCounterValue( i ) / 1024;
  283. Warning( "%s: %d\n", pGroupName, ( int )g_VProfCurrentProfile.GetCounterValue( i ) );
  284. }
  285. }
  286. }
  287. #endif // VPROF_ENABLED