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.

992 lines
30 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // TEX_PROFILE.CPP
  4. //
  5. // Texture Profiling Display.
  6. //=====================================================================================//
  7. #include "vxconsole.h"
  8. #define TEXPROFILE_MAXCOUNTERS 64
  9. #define TEXPROFILE_MAXSAMPLES 512
  10. #define TEXPROFILE_MAJORTICKSIZE 4
  11. #define TEXPROFILE_MAJORTICKBYTES ( TEXPROFILE_MAJORTICKSIZE*1024.0f*1024.0f )
  12. #define TEXPROFILE_HISTORY_MAJORTICKHEIGHT 100
  13. #define TEXPROFILE_HISTORY_NUMMINORTICKS 3
  14. #define TEXPROFILE_HISTORY_LABELWIDTH 50
  15. #define TEXPROFILE_HISTORY_SCALESTEPS 5
  16. #define TEXPROFILE_HISTORY_MINSCALE 0.3f
  17. #define TEXPROFILE_HISTORY_MAXSCALE 3.0f
  18. #define TEXPROFILE_SAMPLES_ITEMHEIGHT 15
  19. #define TEXPROFILE_SAMPLES_BARHEIGHT 10
  20. #define TEXPROFILE_SAMPLES_MAJORTICKWIDTH 200
  21. #define TEXPROFILE_SAMPLES_LABELWIDTH 150
  22. #define TEXPROFILE_SAMPLES_LABELGAP 5
  23. #define TEXPROFILE_SAMPLES_NUMMINORTICKS 3
  24. #define TEXPROFILE_SAMPLES_PEAKHOLDTIME 3000
  25. #define TEXPROFILE_SAMPLES_SCALESTEPS 10
  26. #define TEXPROFILE_SAMPLES_MINSCALE 0.3f
  27. #define TEXPROFILE_SAMPLES_MAXSCALE 3.0f
  28. #define ID_TEXPROFILE_SAMPLES 1
  29. #define ID_TEXPROFILE_HISTORY 2
  30. typedef struct
  31. {
  32. unsigned int samples[TEXPROFILE_MAXSAMPLES];
  33. unsigned int peakSample;
  34. char label[64];
  35. COLORREF color;
  36. } profileCounter_t;
  37. HWND g_texProfile_hWndSamples;
  38. HWND g_texProfile_hWndHistory;
  39. int g_texProfile_numCounters;
  40. profileCounter_t g_texProfile_counters[TEXPROFILE_MAXCOUNTERS];
  41. RECT g_texProfile_samplesWindowRect;
  42. RECT g_texProfile_historyWindowRect;
  43. DWORD g_texProfile_lastPeakTime;
  44. bool g_texProfile_history_tickMarks = true;
  45. bool g_texProfile_history_colors = true;
  46. int g_texProfile_history_scale;
  47. bool g_texProfile_samples_tickMarks = true;
  48. bool g_texProfile_samples_colors = true;
  49. int g_texProfile_samples_scale;
  50. int g_texProfile_numSamples;
  51. int g_texProfile_currentFrame;
  52. //-----------------------------------------------------------------------------
  53. // TexProfile_LoadConfig
  54. //
  55. //-----------------------------------------------------------------------------
  56. void TexProfile_LoadConfig()
  57. {
  58. int numArgs;
  59. char buff[256];
  60. // profile samples
  61. Sys_GetRegistryString( "texProfileSamplesWindowRect", buff, "", sizeof( buff ) );
  62. numArgs = sscanf( buff, "%d %d %d %d", &g_texProfile_samplesWindowRect.left, &g_texProfile_samplesWindowRect.top, &g_texProfile_samplesWindowRect.right, &g_texProfile_samplesWindowRect.bottom );
  63. if ( numArgs != 4 || g_texProfile_samplesWindowRect.left < 0 || g_texProfile_samplesWindowRect.top < 0 || g_texProfile_samplesWindowRect.right < 0 || g_texProfile_samplesWindowRect.bottom < 0 )
  64. memset( &g_texProfile_samplesWindowRect, 0, sizeof( g_texProfile_samplesWindowRect ) );
  65. Sys_GetRegistryInteger( "texProfileSamplesScale", 0, g_texProfile_samples_scale );
  66. if ( g_texProfile_samples_scale < -TEXPROFILE_SAMPLES_SCALESTEPS || g_texProfile_samples_scale > TEXPROFILE_SAMPLES_SCALESTEPS )
  67. g_texProfile_samples_scale = 0;
  68. // profile history
  69. Sys_GetRegistryString( "texProfileHistoryWindowRect", buff, "", sizeof( buff ) );
  70. numArgs = sscanf( buff, "%d %d %d %d", &g_texProfile_historyWindowRect.left, &g_texProfile_historyWindowRect.top, &g_texProfile_historyWindowRect.right, &g_texProfile_historyWindowRect.bottom );
  71. if ( numArgs != 4 || g_texProfile_historyWindowRect.left < 0 || g_texProfile_historyWindowRect.top < 0 || g_texProfile_historyWindowRect.right < 0 || g_texProfile_historyWindowRect.bottom < 0 )
  72. memset( &g_texProfile_historyWindowRect, 0, sizeof( g_texProfile_historyWindowRect ) );
  73. Sys_GetRegistryInteger( "texProfileHistoryScale", 0, g_texProfile_history_scale );
  74. if ( g_texProfile_history_scale < -TEXPROFILE_HISTORY_SCALESTEPS || g_texProfile_history_scale > TEXPROFILE_HISTORY_SCALESTEPS )
  75. g_texProfile_history_scale = 0;
  76. Sys_GetRegistryInteger( "texProfileCurrentFrame", 0, g_texProfile_currentFrame );
  77. }
  78. //-----------------------------------------------------------------------------
  79. // TexProfile_SaveConfig
  80. //
  81. //-----------------------------------------------------------------------------
  82. void TexProfile_SaveConfig()
  83. {
  84. char buff[256];
  85. WINDOWPLACEMENT wp;
  86. // profile samples
  87. if ( g_texProfile_hWndSamples )
  88. {
  89. memset( &wp, 0, sizeof( wp ) );
  90. wp.length = sizeof( WINDOWPLACEMENT );
  91. GetWindowPlacement( g_texProfile_hWndSamples, &wp );
  92. g_texProfile_samplesWindowRect = wp.rcNormalPosition;
  93. sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
  94. Sys_SetRegistryString( "texProfileSamplesWindowRect", buff );
  95. }
  96. Sys_SetRegistryInteger( "texProfileSamplesScale", g_texProfile_samples_scale );
  97. // profile history
  98. if ( g_texProfile_hWndHistory )
  99. {
  100. memset( &wp, 0, sizeof( wp ) );
  101. wp.length = sizeof( WINDOWPLACEMENT );
  102. GetWindowPlacement( g_texProfile_hWndHistory, &wp );
  103. g_texProfile_historyWindowRect = wp.rcNormalPosition;
  104. sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
  105. Sys_SetRegistryString( "texProfileHistoryWindowRect", buff );
  106. }
  107. Sys_SetRegistryInteger( "texProfileHistoryScale", g_texProfile_history_scale );
  108. Sys_SetRegistryInteger( "texProfileCurrentFrame", g_texProfile_currentFrame );
  109. }
  110. //-----------------------------------------------------------------------------
  111. // TexProfile_SetTitle
  112. //
  113. //-----------------------------------------------------------------------------
  114. void TexProfile_SetTitle()
  115. {
  116. char titleBuff[128];
  117. if ( g_texProfile_hWndSamples )
  118. {
  119. strcpy( titleBuff, "D3D Usage Snapshot" );
  120. if ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME )
  121. strcat( titleBuff, " [ON]" );
  122. if ( g_texProfile_currentFrame )
  123. strcat( titleBuff, " [FRAME]" );
  124. SetWindowText( g_texProfile_hWndSamples, titleBuff );
  125. }
  126. if ( g_texProfile_hWndHistory )
  127. {
  128. strcpy( titleBuff, "D3D Usage History" );
  129. if ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME )
  130. strcat( titleBuff, " [ON]" );
  131. if ( g_texProfile_currentFrame )
  132. strcat( titleBuff, " [FRAME]" );
  133. SetWindowText( g_texProfile_hWndHistory, titleBuff );
  134. }
  135. }
  136. //-----------------------------------------------------------------------------
  137. // TexProfile_UpdateWindow
  138. //
  139. //-----------------------------------------------------------------------------
  140. void TexProfile_UpdateWindow()
  141. {
  142. if ( g_texProfile_hWndSamples && !IsIconic( g_texProfile_hWndSamples ) )
  143. {
  144. // visible - force a client repaint
  145. InvalidateRect( g_texProfile_hWndSamples, NULL, true );
  146. }
  147. if ( g_texProfile_hWndHistory && !IsIconic( g_texProfile_hWndHistory ) )
  148. {
  149. // visible - force a client repaint
  150. InvalidateRect( g_texProfile_hWndHistory, NULL, true );
  151. }
  152. }
  153. //-----------------------------------------------------------------------------
  154. // rc_SetTexProfile
  155. //
  156. //-----------------------------------------------------------------------------
  157. int rc_SetTexProfile( char* commandPtr )
  158. {
  159. int i;
  160. char* cmdToken;
  161. int retAddr;
  162. int retVal;
  163. int errCode = -1;
  164. xrProfile_t* localList;
  165. int profileList;
  166. int numProfiles;
  167. // get numProfiles
  168. cmdToken = GetToken( &commandPtr );
  169. if ( !cmdToken[0] )
  170. goto cleanUp;
  171. sscanf( cmdToken,"%x",&numProfiles );
  172. // get profile attributes
  173. cmdToken = GetToken( &commandPtr );
  174. if ( !cmdToken[0] )
  175. goto cleanUp;
  176. sscanf( cmdToken, "%x", &profileList );
  177. // get retAddr
  178. cmdToken = GetToken( &commandPtr );
  179. if ( !cmdToken[0] )
  180. goto cleanUp;
  181. sscanf( cmdToken,"%x",&retAddr );
  182. localList = new xrProfile_t[numProfiles];
  183. memset( localList, 0, numProfiles*sizeof( xrProfile_t ) );
  184. // get the caller's profile list
  185. DmGetMemory( ( void* )profileList, numProfiles*sizeof( xrProfile_t ), localList, NULL );
  186. g_texProfile_numCounters = numProfiles;
  187. if ( g_texProfile_numCounters > TEXPROFILE_MAXCOUNTERS-1 )
  188. g_texProfile_numCounters = TEXPROFILE_MAXCOUNTERS-1;
  189. for ( i=0; i<g_texProfile_numCounters; i++ )
  190. {
  191. // swap the structure
  192. localList[i].color = BigDWord( localList[i].color );
  193. // clear the old counter
  194. memset( &g_texProfile_counters[i], 0, sizeof( profileCounter_t ) );
  195. V_strncpy( g_texProfile_counters[i].label, localList[i].labelString, sizeof( g_texProfile_counters[i].label ) );
  196. g_texProfile_counters[i].color = localList[i].color;
  197. }
  198. // build out the reserved last counter as total count
  199. memset( &g_texProfile_counters[g_texProfile_numCounters], 0, sizeof( profileCounter_t ) );
  200. strcpy( g_texProfile_counters[g_texProfile_numCounters].label, "Total" );
  201. g_texProfile_counters[i].color = RGB( 255,255,255 );
  202. g_texProfile_numCounters++;
  203. // set the return code
  204. retVal = g_texProfile_numCounters-1;
  205. int xboxRetVal = BigDWord( retVal );
  206. DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL );
  207. DebugCommand( "0x%8.8x = SetTexProfile( 0x%8.8x, 0x%8.8x )\n", retVal, numProfiles, profileList );
  208. delete [] localList;
  209. // success
  210. errCode = 0;
  211. cleanUp:
  212. return ( errCode );
  213. }
  214. //-----------------------------------------------------------------------------
  215. // rc_SetTexProfileData
  216. //
  217. //-----------------------------------------------------------------------------
  218. int rc_SetTexProfileData( char* commandPtr )
  219. {
  220. int i;
  221. char* cmdToken;
  222. int errCode = -1;
  223. int counters;
  224. int currentSample;
  225. int total;
  226. bool newPeaks;
  227. unsigned int localCounters[TEXPROFILE_MAXCOUNTERS];
  228. DWORD newTime;
  229. // get profiles
  230. cmdToken = GetToken( &commandPtr );
  231. if ( !cmdToken[0] )
  232. goto cleanUp;
  233. sscanf( cmdToken, "%x", &counters );
  234. // get the caller's profile list
  235. if ( g_texProfile_numCounters )
  236. DmGetMemory( ( void* )counters, ( g_texProfile_numCounters-1 )*sizeof( int ), localCounters, NULL );
  237. // timeout peaks
  238. newTime = Sys_GetSystemTime();
  239. if ( newTime - g_texProfile_lastPeakTime > TEXPROFILE_SAMPLES_PEAKHOLDTIME )
  240. {
  241. g_texProfile_lastPeakTime = newTime;
  242. newPeaks = true;
  243. }
  244. else
  245. newPeaks = false;
  246. // next sample
  247. currentSample = g_texProfile_numSamples % TEXPROFILE_MAXSAMPLES;
  248. g_texProfile_numSamples++;
  249. total = 0;
  250. for ( i=0; i<g_texProfile_numCounters; i++ )
  251. {
  252. if ( i != g_texProfile_numCounters-1 )
  253. {
  254. g_texProfile_counters[i].samples[currentSample] = localCounters[i];
  255. total += localCounters[i];
  256. }
  257. else
  258. {
  259. // reserved total counter
  260. g_texProfile_counters[i].samples[currentSample] = total;
  261. }
  262. if ( newPeaks || g_texProfile_counters[i].peakSample < g_texProfile_counters[i].samples[currentSample] )
  263. g_texProfile_counters[i].peakSample = g_texProfile_counters[i].samples[currentSample];
  264. }
  265. DebugCommand( "SetTexProfileData( 0x%8.8x )\n", counters );
  266. TexProfile_UpdateWindow();
  267. // success
  268. errCode = 0;
  269. cleanUp:
  270. return ( errCode );
  271. }
  272. //-----------------------------------------------------------------------------
  273. // TexProfile_ZoomIn
  274. //
  275. //-----------------------------------------------------------------------------
  276. void TexProfile_ZoomIn( int& scale, int numSteps )
  277. {
  278. scale++;
  279. if ( scale > numSteps )
  280. {
  281. scale = numSteps;
  282. return;
  283. }
  284. TexProfile_UpdateWindow();
  285. }
  286. //-----------------------------------------------------------------------------
  287. // TexProfile_ZoomOut
  288. //
  289. //-----------------------------------------------------------------------------
  290. void TexProfile_ZoomOut( int& scale, int numSteps )
  291. {
  292. scale--;
  293. if ( scale < -numSteps )
  294. {
  295. scale = -numSteps;
  296. return;
  297. }
  298. TexProfile_UpdateWindow();
  299. }
  300. //-----------------------------------------------------------------------------
  301. // TexProfile_CalcScale
  302. //
  303. //-----------------------------------------------------------------------------
  304. float TexProfile_CalcScale( int scale, int numSteps, float min, float max )
  305. {
  306. float t;
  307. // from integral scale [-numSteps..numSteps] to float scale [min..max]
  308. t = ( float )( scale + numSteps )/( float )( 2*numSteps );
  309. t = min + t*( max-min );
  310. return t;
  311. }
  312. //-----------------------------------------------------------------------------
  313. // TexProfileSamples_Draw
  314. //
  315. //-----------------------------------------------------------------------------
  316. void TexProfileSamples_Draw( HDC hdc, RECT* clientRect )
  317. {
  318. int i;
  319. int j;
  320. int x;
  321. int y;
  322. int x0;
  323. int y0;
  324. int w;
  325. float t;
  326. float scale;
  327. float sample;
  328. char labelBuff[128];
  329. HPEN hBlackPen;
  330. HPEN hPenOld;
  331. HPEN hGreyPen;
  332. HBRUSH hColoredBrush;
  333. HBRUSH hbrushOld;
  334. HFONT hFontOld;
  335. RECT rect;
  336. int currentSample;
  337. int numTicks;
  338. int tickWidth;
  339. int windowWidth;
  340. int windowHeight;
  341. hBlackPen = CreatePen( PS_SOLID, 1, RGB( 0,0,0 ) );
  342. hGreyPen = CreatePen( PS_SOLID, 1, Sys_ColorScale( g_backgroundColor, 0.85f ) );
  343. hPenOld = ( HPEN )SelectObject( hdc, hBlackPen );
  344. hFontOld = SelectFont( hdc, g_hProportionalFont );
  345. SetBkColor( hdc, g_backgroundColor );
  346. // zoom
  347. scale = TexProfile_CalcScale( g_texProfile_samples_scale, TEXPROFILE_SAMPLES_SCALESTEPS, TEXPROFILE_SAMPLES_MINSCALE, TEXPROFILE_SAMPLES_MAXSCALE );
  348. tickWidth = ( int )( TEXPROFILE_SAMPLES_MAJORTICKWIDTH*scale );
  349. windowWidth = clientRect->right-clientRect->left;
  350. windowHeight = clientRect->bottom-clientRect->top;
  351. numTicks = ( windowWidth-TEXPROFILE_SAMPLES_LABELWIDTH )/tickWidth + 1;
  352. if ( numTicks < 0 )
  353. numTicks = 1;
  354. rect.left = 0;
  355. rect.right = TEXPROFILE_SAMPLES_LABELWIDTH;
  356. rect.top = 0;
  357. rect.bottom = TEXPROFILE_SAMPLES_ITEMHEIGHT;
  358. DrawText( hdc, "Name", -1, &rect, DT_LEFT );
  359. // draw size ticks
  360. x = TEXPROFILE_SAMPLES_LABELWIDTH;
  361. y = 0;
  362. for ( i=0; i<numTicks; i++ )
  363. {
  364. // tick labels
  365. rect.left = x-40;
  366. rect.right = x+40;
  367. rect.top = y;
  368. rect.bottom = y+TEXPROFILE_SAMPLES_ITEMHEIGHT;
  369. sprintf( labelBuff, "%dMB", i*TEXPROFILE_MAJORTICKSIZE );
  370. DrawText( hdc, labelBuff, -1, &rect, DT_CENTER );
  371. // major ticks
  372. x0 = x;
  373. y0 = y + TEXPROFILE_SAMPLES_ITEMHEIGHT;
  374. SelectObject( hdc, hBlackPen );
  375. MoveToEx( hdc, x0, y0, NULL );
  376. LineTo( hdc, x0, y0+windowHeight );
  377. if ( g_texProfile_samples_tickMarks && g_texProfile_samples_scale > -TEXPROFILE_SAMPLES_SCALESTEPS )
  378. {
  379. // minor ticks
  380. x0 = x;
  381. y0 = y + TEXPROFILE_SAMPLES_ITEMHEIGHT;
  382. SelectObject( hdc, hGreyPen );
  383. for ( j=0; j<TEXPROFILE_SAMPLES_NUMMINORTICKS; j++ )
  384. {
  385. x0 += tickWidth/( TEXPROFILE_SAMPLES_NUMMINORTICKS+1 );
  386. MoveToEx( hdc, x0, y0, NULL );
  387. LineTo( hdc, x0, y0+windowHeight );
  388. }
  389. }
  390. x += tickWidth;
  391. }
  392. // seperator
  393. SelectObject( hdc, hBlackPen );
  394. MoveToEx( hdc, 0, TEXPROFILE_SAMPLES_ITEMHEIGHT, NULL );
  395. LineTo( hdc, windowWidth, TEXPROFILE_SAMPLES_ITEMHEIGHT );
  396. // draw labels
  397. x = 0;
  398. y = TEXPROFILE_SAMPLES_ITEMHEIGHT;
  399. for ( i=0; i<g_texProfile_numCounters; i++ )
  400. {
  401. if ( !g_texProfile_counters[i].label )
  402. continue;
  403. rect.left = x;
  404. rect.right = x+TEXPROFILE_SAMPLES_LABELWIDTH-TEXPROFILE_SAMPLES_LABELGAP;
  405. rect.top = y;
  406. rect.bottom = y+TEXPROFILE_SAMPLES_ITEMHEIGHT;
  407. DrawText( hdc, g_texProfile_counters[i].label, -1, &rect, DT_VCENTER|DT_RIGHT|DT_SINGLELINE|DT_END_ELLIPSIS|DT_MODIFYSTRING );
  408. // draw the under line
  409. MoveToEx( hdc, x, y+TEXPROFILE_SAMPLES_ITEMHEIGHT, NULL );
  410. LineTo( hdc, x+TEXPROFILE_SAMPLES_LABELWIDTH, y+TEXPROFILE_SAMPLES_ITEMHEIGHT );
  411. y += TEXPROFILE_SAMPLES_ITEMHEIGHT;
  412. }
  413. // draw bars
  414. SelectObject( hdc, hBlackPen );
  415. x = TEXPROFILE_SAMPLES_LABELWIDTH;
  416. y = TEXPROFILE_SAMPLES_ITEMHEIGHT;
  417. currentSample = g_texProfile_numSamples-1;
  418. if ( currentSample < 0 )
  419. currentSample = 0;
  420. else
  421. currentSample %= TEXPROFILE_MAXSAMPLES;
  422. for ( i=0; i<g_texProfile_numCounters; i++ )
  423. {
  424. if ( !g_texProfile_counters[i].label )
  425. continue;
  426. hColoredBrush = CreateSolidBrush( g_texProfile_samples_colors ? g_texProfile_counters[i].color : g_backgroundColor );
  427. hbrushOld = ( HBRUSH )SelectObject( hdc, hColoredBrush );
  428. // bar - count is in bytes, scale to major tick
  429. t = ( float )g_texProfile_counters[i].samples[currentSample]/TEXPROFILE_MAJORTICKBYTES;
  430. w = ( int )( t * ( float )tickWidth );
  431. if ( w > windowWidth )
  432. w = windowWidth;
  433. x0 = x;
  434. y0 = y + ( TEXPROFILE_SAMPLES_ITEMHEIGHT-TEXPROFILE_SAMPLES_BARHEIGHT )/2 + 1;
  435. Rectangle( hdc, x0, y0, x0 + w, y0 + TEXPROFILE_SAMPLES_BARHEIGHT );
  436. // peak
  437. t = ( float )g_texProfile_counters[i].peakSample/TEXPROFILE_MAJORTICKBYTES;
  438. w = ( int )( t * ( float )tickWidth );
  439. if ( w > windowWidth )
  440. w = windowWidth;
  441. x0 = x + w;
  442. y0 = y + TEXPROFILE_SAMPLES_ITEMHEIGHT/2 + 1;
  443. POINT points[4];
  444. points[0].x = x0;
  445. points[0].y = y0-4;
  446. points[1].x = x0+4;
  447. points[1].y = y0;
  448. points[2].x = x0;
  449. points[2].y = y0+4;
  450. points[3].x = x0-4;
  451. points[3].y = y0;
  452. Polygon( hdc, points, 4 );
  453. SelectObject( hdc, hbrushOld );
  454. DeleteObject( hColoredBrush );
  455. // draw peak sizes
  456. sample = ( float )g_texProfile_counters[i].peakSample/1024.0f;
  457. if ( sample >= 0.01F )
  458. {
  459. sprintf( labelBuff, "%.2f MB", sample/1024.0f );
  460. rect.left = x0 + 8;
  461. rect.right = x0 + 8 + 100;
  462. rect.top = y;
  463. rect.bottom = y + TEXPROFILE_SAMPLES_ITEMHEIGHT;
  464. DrawText( hdc, labelBuff, -1, &rect, DT_VCENTER|DT_LEFT|DT_SINGLELINE );
  465. }
  466. y += TEXPROFILE_SAMPLES_ITEMHEIGHT;
  467. }
  468. SelectObject( hdc, hFontOld );
  469. SelectObject( hdc, hPenOld );
  470. DeleteObject( hBlackPen );
  471. DeleteObject( hGreyPen );
  472. }
  473. //-----------------------------------------------------------------------------
  474. // TexProfileHistory_Draw
  475. //
  476. //-----------------------------------------------------------------------------
  477. void TexProfileHistory_Draw( HDC hdc, RECT* clientRect )
  478. {
  479. char labelBuff[128];
  480. HPEN hBlackPen;
  481. HPEN hPenOld;
  482. HPEN hNullPen;
  483. HPEN hGreyPen;
  484. HBRUSH hColoredBrush;
  485. HBRUSH hBrushOld;
  486. HFONT hFontOld;
  487. int currentSample;
  488. int numTicks;
  489. int tickHeight;
  490. int windowWidth;
  491. int windowHeight;
  492. int x;
  493. int y;
  494. int y0;
  495. int i;
  496. int j;
  497. int h;
  498. int numbars;
  499. RECT rect;
  500. float t;
  501. float scale;
  502. hBlackPen = CreatePen( PS_SOLID, 1, RGB( 0,0,0 ) );
  503. hGreyPen = CreatePen( PS_SOLID, 1, Sys_ColorScale( g_backgroundColor, 0.85f ) );
  504. hNullPen = CreatePen( PS_NULL, 0, RGB( 0,0,0 ) );
  505. hPenOld = ( HPEN )SelectObject( hdc, hBlackPen );
  506. hFontOld = SelectFont( hdc, g_hProportionalFont );
  507. // zoom
  508. scale = TexProfile_CalcScale( g_texProfile_history_scale, TEXPROFILE_HISTORY_SCALESTEPS, TEXPROFILE_HISTORY_MINSCALE, TEXPROFILE_HISTORY_MAXSCALE );
  509. tickHeight = ( int )( TEXPROFILE_HISTORY_MAJORTICKHEIGHT*scale );
  510. windowWidth = clientRect->right-clientRect->left;
  511. windowHeight = clientRect->bottom-clientRect->top;
  512. numTicks = windowHeight/tickHeight + 2;
  513. if ( numTicks < 0 )
  514. numTicks = 1;
  515. SetBkColor( hdc, g_backgroundColor );
  516. x = 0;
  517. y = windowHeight;
  518. for ( i=0; i<numTicks; i++ )
  519. {
  520. // major ticks
  521. SelectObject( hdc, hBlackPen );
  522. MoveToEx( hdc, 0, y, NULL );
  523. LineTo( hdc, windowWidth, y );
  524. if ( g_texProfile_history_tickMarks && g_texProfile_history_scale > -TEXPROFILE_HISTORY_SCALESTEPS )
  525. {
  526. // minor ticks
  527. y0 = y;
  528. SelectObject( hdc, hGreyPen );
  529. for ( j=0; j<TEXPROFILE_HISTORY_NUMMINORTICKS; j++ )
  530. {
  531. y0 += tickHeight/( TEXPROFILE_SAMPLES_NUMMINORTICKS+1 );
  532. MoveToEx( hdc, 0, y0, NULL );
  533. LineTo( hdc, windowWidth, y0 );
  534. }
  535. }
  536. // tick labels
  537. if ( i )
  538. {
  539. rect.left = windowWidth-50;
  540. rect.right = windowWidth;
  541. rect.top = y-20;
  542. rect.bottom = y;
  543. sprintf( labelBuff, "%dMB", i*TEXPROFILE_MAJORTICKSIZE );
  544. DrawText( hdc, labelBuff, -1, &rect, DT_RIGHT|DT_SINGLELINE|DT_BOTTOM );
  545. }
  546. y -= tickHeight;
  547. }
  548. // vertical bars
  549. if ( g_texProfile_numSamples )
  550. {
  551. SelectObject( hdc, hNullPen );
  552. numbars = windowWidth-TEXPROFILE_HISTORY_LABELWIDTH;
  553. currentSample = g_texProfile_numSamples-1;
  554. for ( x=numbars-1; x>=0; x-=4 )
  555. {
  556. // all the counters at this sample
  557. y = windowHeight;
  558. for ( j=0; j<g_texProfile_numCounters-1; j++ )
  559. {
  560. if ( !g_texProfile_counters[j].label )
  561. continue;
  562. t = ( float )g_texProfile_counters[j].samples[currentSample % TEXPROFILE_MAXSAMPLES]/TEXPROFILE_MAJORTICKBYTES;
  563. h = ( int )( t * ( float )tickHeight );
  564. if ( h )
  565. {
  566. if ( h > windowHeight )
  567. h = windowHeight;
  568. hColoredBrush = CreateSolidBrush( g_texProfile_history_colors ? g_texProfile_counters[j].color : RGB( 80,80,80 ) );
  569. hBrushOld = ( HBRUSH )SelectObject( hdc, hColoredBrush );
  570. Rectangle( hdc, x-4, y-h, x, y+1 );
  571. y -= h;
  572. SelectObject( hdc, hBrushOld );
  573. DeleteObject( hColoredBrush );
  574. }
  575. }
  576. currentSample--;
  577. if ( currentSample < 0 )
  578. {
  579. // no data
  580. break;
  581. }
  582. }
  583. }
  584. SelectObject( hdc, hFontOld );
  585. SelectObject( hdc, hPenOld );
  586. DeleteObject( hBlackPen );
  587. DeleteObject( hGreyPen );
  588. }
  589. //-----------------------------------------------------------------------------
  590. // TexProfile_WndProc
  591. //
  592. //-----------------------------------------------------------------------------
  593. LRESULT CALLBACK TexProfile_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
  594. {
  595. WORD wID = LOWORD( wParam );
  596. HDC hdc;
  597. PAINTSTRUCT ps;
  598. RECT rect;
  599. int id;
  600. bool bIsSamples;
  601. bool bIsHistory;
  602. CREATESTRUCT *createStructPtr;
  603. bool bIsEnabled;
  604. // identify window
  605. id = ( int )GetWindowLong( hwnd, GWL_USERDATA+0 );
  606. bIsSamples = ( id == ID_TEXPROFILE_SAMPLES );
  607. bIsHistory = ( id == ID_TEXPROFILE_HISTORY );
  608. switch ( message )
  609. {
  610. case WM_CREATE:
  611. // set the window identifier
  612. createStructPtr = ( CREATESTRUCT* )lParam;
  613. SetWindowLong( hwnd, GWL_USERDATA+0, ( LONG )createStructPtr->lpCreateParams );
  614. // reset peaks
  615. g_texProfile_lastPeakTime = 0;
  616. return 0L;
  617. case WM_DESTROY:
  618. TexProfile_SaveConfig();
  619. if ( bIsSamples )
  620. g_texProfile_hWndSamples = NULL;
  621. else if ( bIsHistory )
  622. g_texProfile_hWndHistory = NULL;
  623. if ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME )
  624. {
  625. VProf_Enable( VPROF_OFF );
  626. }
  627. return 0L;
  628. case WM_INITMENU:
  629. if ( bIsSamples )
  630. {
  631. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_TICKMARKS, MF_BYCOMMAND | ( g_texProfile_samples_tickMarks ? MF_CHECKED : MF_UNCHECKED ) );
  632. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_COLORS, MF_BYCOMMAND | ( g_texProfile_samples_colors ? MF_CHECKED : MF_UNCHECKED ) );
  633. }
  634. else if ( bIsHistory )
  635. {
  636. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_TICKMARKS, MF_BYCOMMAND | ( g_texProfile_history_tickMarks ? MF_CHECKED : MF_UNCHECKED ) );
  637. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_COLORS, MF_BYCOMMAND | ( g_texProfile_history_colors ? MF_CHECKED : MF_UNCHECKED ) );
  638. }
  639. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_ENABLE, MF_BYCOMMAND | ( ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME ) ? MF_CHECKED : MF_UNCHECKED ) );
  640. CheckMenuItem( ( HMENU )wParam, IDM_TEXPROFILE_CURRENTFRAME, MF_BYCOMMAND | ( g_texProfile_currentFrame ? MF_CHECKED : MF_UNCHECKED ) );
  641. return 0L;
  642. case WM_PAINT:
  643. GetClientRect( hwnd, &rect );
  644. hdc = BeginPaint( hwnd, &ps );
  645. if ( bIsSamples )
  646. TexProfileSamples_Draw( hdc, &rect );
  647. else if ( bIsHistory )
  648. TexProfileHistory_Draw( hdc, &rect );
  649. EndPaint( hwnd, &ps );
  650. return 0L;
  651. case WM_SIZE:
  652. // force a redraw
  653. TexProfile_UpdateWindow();
  654. return 0L;
  655. case WM_KEYDOWN:
  656. switch ( wParam )
  657. {
  658. case VK_INSERT:
  659. if ( bIsSamples )
  660. TexProfile_ZoomIn( g_texProfile_samples_scale, TEXPROFILE_SAMPLES_SCALESTEPS );
  661. else if ( bIsHistory )
  662. TexProfile_ZoomIn( g_texProfile_history_scale, TEXPROFILE_HISTORY_SCALESTEPS );
  663. return 0L;
  664. case VK_DELETE:
  665. if ( bIsSamples )
  666. TexProfile_ZoomOut( g_texProfile_samples_scale, TEXPROFILE_SAMPLES_SCALESTEPS );
  667. else if ( bIsHistory )
  668. TexProfile_ZoomOut( g_texProfile_history_scale, TEXPROFILE_HISTORY_SCALESTEPS );
  669. return 0L;
  670. }
  671. break;
  672. case WM_COMMAND:
  673. switch ( wID )
  674. {
  675. case IDM_TEXPROFILE_TICKMARKS:
  676. if ( bIsSamples )
  677. g_texProfile_samples_tickMarks ^= 1;
  678. else if ( bIsHistory )
  679. g_texProfile_history_tickMarks ^= 1;
  680. TexProfile_UpdateWindow();
  681. return 0L;
  682. case IDM_TEXPROFILE_COLORS:
  683. if ( bIsSamples )
  684. g_texProfile_samples_colors ^= 1;
  685. else if ( bIsHistory )
  686. g_texProfile_history_colors ^= 1;
  687. TexProfile_UpdateWindow();
  688. return 0L;
  689. case IDM_TEXPROFILE_ZOOMIN:
  690. if ( bIsSamples )
  691. TexProfile_ZoomIn( g_texProfile_samples_scale, TEXPROFILE_SAMPLES_SCALESTEPS );
  692. else if ( bIsHistory )
  693. TexProfile_ZoomIn( g_texProfile_history_scale, TEXPROFILE_HISTORY_SCALESTEPS );
  694. return 0L;
  695. case IDM_TEXPROFILE_ZOOMOUT:
  696. if ( bIsSamples )
  697. TexProfile_ZoomOut( g_texProfile_samples_scale, TEXPROFILE_SAMPLES_SCALESTEPS );
  698. else if ( bIsHistory )
  699. TexProfile_ZoomOut( g_texProfile_history_scale, TEXPROFILE_HISTORY_SCALESTEPS );
  700. return 0L;
  701. case IDM_TEXPROFILE_ENABLE:
  702. bIsEnabled = ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME );
  703. bIsEnabled ^= 1;
  704. if ( !bIsEnabled )
  705. VProf_Enable( VPROF_OFF );
  706. else
  707. {
  708. if ( !g_texProfile_currentFrame )
  709. VProf_Enable( VPROF_TEXTURE );
  710. else
  711. VProf_Enable( VPROF_TEXTUREFRAME );
  712. }
  713. TexProfile_SetTitle();
  714. return 0L;
  715. case IDM_TEXPROFILE_CURRENTFRAME:
  716. bIsEnabled = ( VProf_GetState() == VPROF_TEXTURE || VProf_GetState() == VPROF_TEXTUREFRAME );
  717. g_texProfile_currentFrame ^= 1;
  718. if ( bIsEnabled )
  719. {
  720. if ( !g_texProfile_currentFrame )
  721. VProf_Enable( VPROF_TEXTURE );
  722. else
  723. VProf_Enable( VPROF_TEXTUREFRAME );
  724. }
  725. TexProfile_SetTitle();
  726. return 0L;
  727. }
  728. break;
  729. }
  730. return ( DefWindowProc( hwnd, message, wParam, lParam ) );
  731. }
  732. //-----------------------------------------------------------------------------
  733. // TexProfileHistory_Open
  734. //
  735. //-----------------------------------------------------------------------------
  736. void TexProfileHistory_Open()
  737. {
  738. HWND hWnd;
  739. if ( g_texProfile_hWndHistory )
  740. {
  741. // only one profile instance
  742. if ( IsIconic( g_texProfile_hWndHistory ) )
  743. ShowWindow( g_texProfile_hWndHistory, SW_RESTORE );
  744. SetForegroundWindow( g_texProfile_hWndHistory );
  745. return;
  746. }
  747. if ( VProf_GetState() == VPROF_OFF )
  748. {
  749. if ( !g_texProfile_currentFrame )
  750. VProf_Enable( VPROF_TEXTURE );
  751. else
  752. VProf_Enable( VPROF_TEXTUREFRAME );
  753. }
  754. hWnd = CreateWindowEx(
  755. WS_EX_CLIENTEDGE,
  756. "TEXPROFILEHISTORYCLASS",
  757. "",
  758. WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
  759. 0,
  760. 0,
  761. 600,
  762. 500,
  763. g_hDlgMain,
  764. NULL,
  765. g_hInstance,
  766. ( void* )ID_TEXPROFILE_HISTORY );
  767. g_texProfile_hWndHistory = hWnd;
  768. TexProfile_SetTitle();
  769. if ( g_texProfile_historyWindowRect.right && g_texProfile_historyWindowRect.bottom )
  770. MoveWindow( g_texProfile_hWndHistory, g_texProfile_historyWindowRect.left, g_texProfile_historyWindowRect.top, g_texProfile_historyWindowRect.right-g_texProfile_historyWindowRect.left, g_texProfile_historyWindowRect.bottom-g_texProfile_historyWindowRect.top, FALSE );
  771. ShowWindow( g_texProfile_hWndHistory, SHOW_OPENWINDOW );
  772. }
  773. //-----------------------------------------------------------------------------
  774. // TexProfileSamples_Open
  775. //
  776. //-----------------------------------------------------------------------------
  777. void TexProfileSamples_Open()
  778. {
  779. HWND hWnd;
  780. if ( g_texProfile_hWndSamples )
  781. {
  782. // only one profile instance
  783. if ( IsIconic( g_texProfile_hWndSamples ) )
  784. ShowWindow( g_texProfile_hWndSamples, SW_RESTORE );
  785. SetForegroundWindow( g_texProfile_hWndSamples );
  786. return;
  787. }
  788. if ( VProf_GetState() == VPROF_OFF )
  789. {
  790. if ( !g_texProfile_currentFrame )
  791. VProf_Enable( VPROF_TEXTURE );
  792. else
  793. VProf_Enable( VPROF_TEXTUREFRAME );
  794. }
  795. hWnd = CreateWindowEx(
  796. WS_EX_CLIENTEDGE,
  797. "TEXPROFILESAMPLESCLASS",
  798. "",
  799. WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
  800. 0,
  801. 0,
  802. 600,
  803. 500,
  804. g_hDlgMain,
  805. NULL,
  806. g_hInstance,
  807. ( void* )ID_TEXPROFILE_SAMPLES );
  808. g_texProfile_hWndSamples = hWnd;
  809. TexProfile_SetTitle();
  810. if ( g_texProfile_samplesWindowRect.right && g_texProfile_samplesWindowRect.bottom )
  811. MoveWindow( g_texProfile_hWndSamples, g_texProfile_samplesWindowRect.left, g_texProfile_samplesWindowRect.top, g_texProfile_samplesWindowRect.right-g_texProfile_samplesWindowRect.left, g_texProfile_samplesWindowRect.bottom-g_texProfile_samplesWindowRect.top, FALSE );
  812. ShowWindow( g_texProfile_hWndSamples, SHOW_OPENWINDOW );
  813. }
  814. //-----------------------------------------------------------------------------
  815. // TexProfile_Clear
  816. //
  817. //-----------------------------------------------------------------------------
  818. void TexProfile_Clear()
  819. {
  820. // clear counters and history
  821. g_texProfile_numCounters = 0;
  822. g_texProfile_numSamples = 0;
  823. TexProfile_UpdateWindow();
  824. }
  825. //-----------------------------------------------------------------------------
  826. // TexProfile_Init
  827. //
  828. //-----------------------------------------------------------------------------
  829. bool TexProfile_Init()
  830. {
  831. WNDCLASS wndclass;
  832. // set up our window class
  833. memset( &wndclass, 0, sizeof( wndclass ) );
  834. wndclass.style = 0;
  835. wndclass.lpfnWndProc = TexProfile_WndProc;
  836. wndclass.cbClsExtra = 0;
  837. wndclass.cbWndExtra = 0;
  838. wndclass.hInstance = g_hInstance;
  839. wndclass.hIcon = g_hIcons[ICON_APPLICATION];
  840. wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  841. wndclass.hbrBackground = g_hBackgroundBrush;
  842. wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_TEXPROFILE );
  843. wndclass.lpszClassName = "TEXPROFILESAMPLESCLASS";
  844. if ( !RegisterClass( &wndclass ) )
  845. return false;
  846. // set up our window class
  847. memset( &wndclass, 0, sizeof( wndclass ) );
  848. wndclass.style = 0;
  849. wndclass.lpfnWndProc = TexProfile_WndProc;
  850. wndclass.cbClsExtra = 0;
  851. wndclass.cbWndExtra = 0;
  852. wndclass.hInstance = g_hInstance;
  853. wndclass.hIcon = g_hIcons[ICON_APPLICATION];
  854. wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  855. wndclass.hbrBackground = g_hBackgroundBrush;
  856. wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_TEXPROFILE );
  857. wndclass.lpszClassName = "TEXPROFILEHISTORYCLASS";
  858. if ( !RegisterClass( &wndclass ) )
  859. return false;
  860. TexProfile_LoadConfig();
  861. return true;
  862. }