summaryrefslogtreecommitdiff
path: root/utils/xbox/vxconsole/mem_profile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/xbox/vxconsole/mem_profile.cpp')
-rw-r--r--utils/xbox/vxconsole/mem_profile.cpp561
1 files changed, 561 insertions, 0 deletions
diff --git a/utils/xbox/vxconsole/mem_profile.cpp b/utils/xbox/vxconsole/mem_profile.cpp
new file mode 100644
index 0000000..d15aee3
--- /dev/null
+++ b/utils/xbox/vxconsole/mem_profile.cpp
@@ -0,0 +1,561 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// MEM_PROFILE.CPP
+//
+// Memory Profiling Display
+//=====================================================================================//
+#include "vxconsole.h"
+
+#define PROFILE_MAXSAMPLES 512
+#define PROFILE_MEMORYHEIGHT 100
+#define PROFILE_NUMMINORTICKS 3
+#define PROFILE_LABELWIDTH 50
+#define PROFILE_SCALESTEPS 8
+#define PROFILE_MINSCALE 0.2f
+#define PROFILE_MAXSCALE 3.0f
+#define PROFILE_NUMMINORTICKS 3
+#define PROFILE_MAJORTICKMB 16
+#define PROFILE_WARNINGMB 10
+#define PROFILE_SEVEREMB 5
+
+#define ID_MEMPROFILE 1
+
+HWND g_memProfile_hWnd;
+RECT g_memProfile_WindowRect;
+int g_memProfile_tickMarks;
+int g_memProfile_colors;
+int g_memProfile_scale;
+UINT_PTR g_memProfile_Timer;
+int g_memProfile_numSamples;
+int g_memProfile_samples[PROFILE_MAXSAMPLES];
+
+//-----------------------------------------------------------------------------
+// MemProfile_SaveConfig
+//
+//-----------------------------------------------------------------------------
+void MemProfile_SaveConfig()
+{
+ char buff[256];
+ WINDOWPLACEMENT wp;
+
+ // profile history
+ if ( g_memProfile_hWnd )
+ {
+ memset( &wp, 0, sizeof( wp ) );
+ wp.length = sizeof( WINDOWPLACEMENT );
+ GetWindowPlacement( g_memProfile_hWnd, &wp );
+ g_memProfile_WindowRect = wp.rcNormalPosition;
+ sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
+ Sys_SetRegistryString( "MemProfileWindowRect", buff );
+ }
+
+ Sys_SetRegistryInteger( "MemProfileScale", g_memProfile_scale );
+ Sys_SetRegistryInteger( "MemProfileTickMarks", g_memProfile_tickMarks );
+ Sys_SetRegistryInteger( "MemProfileColors", g_memProfile_colors );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_LoadConfig
+//
+//-----------------------------------------------------------------------------
+void MemProfile_LoadConfig()
+{
+ int numArgs;
+ char buff[256];
+
+ // profile history
+ Sys_GetRegistryString( "MemProfileWindowRect", buff, "", sizeof( buff ) );
+ numArgs = sscanf( buff, "%d %d %d %d", &g_memProfile_WindowRect.left, &g_memProfile_WindowRect.top, &g_memProfile_WindowRect.right, &g_memProfile_WindowRect.bottom );
+ if ( numArgs != 4 )
+ {
+ memset( &g_memProfile_WindowRect, 0, sizeof( g_memProfile_WindowRect ) );
+ }
+
+ Sys_GetRegistryInteger( "MemProfileScale", 0, g_memProfile_scale );
+ if ( g_memProfile_scale < -PROFILE_SCALESTEPS || g_memProfile_scale > PROFILE_SCALESTEPS )
+ {
+ g_memProfile_scale = 0;
+ }
+
+ Sys_GetRegistryInteger( "MemProfileTickMarks", 1, g_memProfile_tickMarks );
+ Sys_GetRegistryInteger( "MemProfileColors", 1, g_memProfile_colors );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_SetTitle
+//
+//-----------------------------------------------------------------------------
+void MemProfile_SetTitle()
+{
+ char titleBuff[128];
+
+ if ( g_memProfile_hWnd )
+ {
+ strcpy( titleBuff, "Free Memory Available" );
+ if ( g_memProfile_Timer )
+ {
+ strcat( titleBuff, " [ON]" );
+ }
+
+ SetWindowText( g_memProfile_hWnd, titleBuff );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_EnableProfiling
+//
+//-----------------------------------------------------------------------------
+void MemProfile_EnableProfiling( bool bEnable )
+{
+ if ( !g_memProfile_hWnd )
+ {
+ return;
+ }
+
+ UINT_PTR timer = TIMERID_MEMPROFILE;
+ if ( bEnable && !g_memProfile_Timer )
+ {
+ // run at 10Hz
+ g_memProfile_Timer = SetTimer( g_memProfile_hWnd, timer, 100, NULL );
+ }
+ else if ( !bEnable && g_memProfile_Timer )
+ {
+ KillTimer( g_memProfile_hWnd, timer );
+ g_memProfile_Timer = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_UpdateWindow
+//
+//-----------------------------------------------------------------------------
+void MemProfile_UpdateWindow()
+{
+ if ( g_memProfile_hWnd && !IsIconic( g_memProfile_hWnd ) )
+ {
+ // visible - force a client repaint
+ InvalidateRect( g_memProfile_hWnd, NULL, true );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// rc_FreeMemory
+//
+//-----------------------------------------------------------------------------
+int rc_FreeMemory( char* commandPtr )
+{
+ int errCode = -1;
+ int freeMemory;
+
+ char *cmdToken = GetToken( &commandPtr );
+ if ( !cmdToken[0] )
+ {
+ goto cleanUp;
+ }
+ sscanf( cmdToken, "%x", &freeMemory );
+
+ g_memProfile_samples[g_memProfile_numSamples % PROFILE_MAXSAMPLES] = freeMemory;
+ g_memProfile_numSamples++;
+
+ DebugCommand( "FreeMemory( 0x%8.8x )\n", freeMemory );
+
+ MemProfile_UpdateWindow();
+
+ // success
+ errCode = 0;
+
+cleanUp:
+ return ( errCode );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_ZoomIn
+//
+//-----------------------------------------------------------------------------
+void MemProfile_ZoomIn( int& scale, int numSteps )
+{
+ scale++;
+ if ( scale > numSteps )
+ {
+ scale = numSteps;
+ return;
+ }
+ MemProfile_UpdateWindow();
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_ZoomOut
+//
+//-----------------------------------------------------------------------------
+void MemProfile_ZoomOut( int& scale, int numSteps )
+{
+ scale--;
+ if ( scale < -numSteps )
+ {
+ scale = -numSteps;
+ return;
+ }
+ MemProfile_UpdateWindow();
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_CalcScale
+//
+//-----------------------------------------------------------------------------
+float MemProfile_CalcScale( int scale, int numSteps, float min, float max )
+{
+ float t;
+
+ // from integral scale [-numSteps..numSteps] to float scale [min..max]
+ t = ( float )( scale + numSteps )/( float )( 2*numSteps );
+ t = min + t*( max-min );
+
+ return t;
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_Draw
+//
+//-----------------------------------------------------------------------------
+void MemProfile_Draw( HDC hdc, RECT* clientRect )
+{
+ char labelBuff[128];
+ HPEN hBlackPen;
+ HPEN hPenOld;
+ HPEN hNullPen;
+ HPEN hGreyPen;
+ HBRUSH hColoredBrush;
+ HBRUSH hBrushOld;
+ HFONT hFontOld;
+ int currentSample;
+ int numTicks;
+ int memoryHeight;
+ int windowWidth;
+ int windowHeight;
+ int x;
+ int y;
+ int y0;
+ int i;
+ int j;
+ int h;
+ int numbars;
+ RECT rect;
+ float t;
+ float scale;
+
+ hBlackPen = CreatePen( PS_SOLID, 1, RGB( 0,0,0 ) );
+ hGreyPen = CreatePen( PS_SOLID, 1, Sys_ColorScale( g_backgroundColor, 0.85f ) );
+ hNullPen = CreatePen( PS_NULL, 0, RGB( 0,0,0 ) );
+ hPenOld = ( HPEN )SelectObject( hdc, hBlackPen );
+ hFontOld = SelectFont( hdc, g_hProportionalFont );
+
+ // zoom
+ scale = MemProfile_CalcScale( g_memProfile_scale, PROFILE_SCALESTEPS, PROFILE_MINSCALE, PROFILE_MAXSCALE );
+ memoryHeight = ( int )( PROFILE_MEMORYHEIGHT*scale );
+ windowWidth = clientRect->right-clientRect->left;
+ windowHeight = clientRect->bottom-clientRect->top;
+
+ numTicks = windowHeight/memoryHeight + 2;
+ if ( numTicks < 0 )
+ {
+ numTicks = 1;
+ }
+ else if ( numTicks > 512/PROFILE_MAJORTICKMB + 1 )
+ {
+ numTicks = 512/PROFILE_MAJORTICKMB + 1;
+ }
+
+ SetBkColor( hdc, g_backgroundColor );
+
+ x = 0;
+ y = windowHeight;
+ for ( i=0; i<numTicks; i++ )
+ {
+ // major ticks
+ SelectObject( hdc, hBlackPen );
+ MoveToEx( hdc, 0, y, NULL );
+ LineTo( hdc, windowWidth, y );
+
+ if ( g_memProfile_tickMarks )
+ {
+ // could be very zoomed out, gap must be enough for label, otherwise don't draw
+ int gapY = memoryHeight/( PROFILE_NUMMINORTICKS+1 );
+ if ( gapY >= 10 )
+ {
+ // minor ticks
+ y0 = y;
+ SelectObject( hdc, hGreyPen );
+ for ( j=0; j<PROFILE_NUMMINORTICKS; j++ )
+ {
+ y0 += gapY;
+ MoveToEx( hdc, 0, y0, NULL );
+ LineTo( hdc, windowWidth, y0 );
+ }
+ }
+ }
+
+ // tick labels
+ if ( i )
+ {
+ rect.left = windowWidth - 50;
+ rect.right = windowWidth;
+ rect.top = y - 20;
+ rect.bottom = y;
+ sprintf( labelBuff, "%d MB", i*PROFILE_MAJORTICKMB );
+ DrawText( hdc, labelBuff, -1, &rect, DT_RIGHT|DT_SINGLELINE|DT_BOTTOM );
+ }
+
+ y -= memoryHeight;
+ }
+
+ // vertical bars
+ if ( g_memProfile_numSamples )
+ {
+ SelectObject( hdc, hNullPen );
+
+ numbars = windowWidth-PROFILE_LABELWIDTH;
+ currentSample = g_memProfile_numSamples-1;
+ for ( x=numbars-1; x>=0; x-=4 )
+ {
+ float sample = g_memProfile_samples[currentSample % PROFILE_MAXSAMPLES]/( 1024.0f * 1024.0f );
+
+ y = windowHeight;
+ t = sample/(float)PROFILE_MAJORTICKMB;
+ h = ( int )( t * ( float )memoryHeight );
+ if ( h )
+ {
+ if ( h > windowHeight )
+ h = windowHeight;
+
+ COLORREF barColor;
+ if ( sample >= PROFILE_WARNINGMB )
+ {
+ barColor = RGB( 100, 255, 100 );
+ }
+ else if ( sample >= PROFILE_SEVEREMB )
+ {
+ barColor = RGB( 255, 255, 100 );
+ }
+ else
+ {
+ barColor = RGB( 255, 0, 0 );
+ }
+
+ hColoredBrush = CreateSolidBrush( g_memProfile_colors ? barColor : RGB( 80, 80, 80 ) );
+ hBrushOld = ( HBRUSH )SelectObject( hdc, hColoredBrush );
+
+ Rectangle( hdc, x-4, y-h, x, y+1 );
+ y -= h;
+
+ SelectObject( hdc, hBrushOld );
+ DeleteObject( hColoredBrush );
+ }
+
+ currentSample--;
+ if ( currentSample < 0 )
+ {
+ // no data
+ break;
+ }
+ }
+ }
+
+ SelectObject( hdc, hFontOld );
+ SelectObject( hdc, hPenOld );
+ DeleteObject( hBlackPen );
+ DeleteObject( hGreyPen );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_TimerProc
+//
+//-----------------------------------------------------------------------------
+void MemProfile_TimerProc( HWND hwnd, UINT_PTR idEvent )
+{
+ static bool busy = false;
+
+ if ( busy )
+ {
+ return;
+ }
+
+ busy = true;
+
+ if ( g_connectedToApp )
+ {
+ // send as async
+ DmAPI_SendCommand( VXCONSOLE_COMMAND_PREFIX "!" "__memory__ quiet", false );
+ }
+
+ busy = false;
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_WndProc
+//
+//-----------------------------------------------------------------------------
+LRESULT CALLBACK MemProfile_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ WORD wID = LOWORD( wParam );
+ HDC hdc;
+ PAINTSTRUCT ps;
+ RECT rect;
+ CREATESTRUCT *createStructPtr;
+
+ switch ( message )
+ {
+ case WM_CREATE:
+ // set the window identifier
+ createStructPtr = ( CREATESTRUCT* )lParam;
+ SetWindowLong( hwnd, GWL_USERDATA+0, ( LONG )createStructPtr->lpCreateParams );
+
+ // clear samples
+ g_memProfile_numSamples = 0;
+ memset( g_memProfile_samples, 0, sizeof( g_memProfile_samples ) );
+ return 0L;
+
+ case WM_DESTROY:
+ MemProfile_SaveConfig();
+ MemProfile_EnableProfiling( false );
+ g_memProfile_hWnd = NULL;
+ return 0L;
+
+ case WM_INITMENU:
+ CheckMenuItem( ( HMENU )wParam, IDM_MEMPROFILE_TICKMARKS, MF_BYCOMMAND | ( g_memProfile_tickMarks ? MF_CHECKED : MF_UNCHECKED ) );
+ CheckMenuItem( ( HMENU )wParam, IDM_MEMPROFILE_COLORS, MF_BYCOMMAND | ( g_memProfile_colors ? MF_CHECKED : MF_UNCHECKED ) );
+ CheckMenuItem( ( HMENU )wParam, IDM_MEMPROFILE_ENABLE, MF_BYCOMMAND | ( g_memProfile_Timer != NULL ? MF_CHECKED : MF_UNCHECKED ) );
+ return 0L;
+
+ case WM_PAINT:
+ GetClientRect( hwnd, &rect );
+ hdc = BeginPaint( hwnd, &ps );
+ MemProfile_Draw( hdc, &rect );
+ EndPaint( hwnd, &ps );
+ return 0L;
+
+ case WM_SIZE:
+ // force a redraw
+ MemProfile_UpdateWindow();
+ return 0L;
+
+ case WM_TIMER:
+ if ( wID == TIMERID_MEMPROFILE )
+ {
+ MemProfile_TimerProc( hwnd, TIMERID_MEMPROFILE );
+ return 0L;
+ }
+ break;
+
+ case WM_KEYDOWN:
+ switch ( wParam )
+ {
+ case VK_INSERT:
+ MemProfile_ZoomIn( g_memProfile_scale, PROFILE_SCALESTEPS );
+ return 0L;
+
+ case VK_DELETE:
+ MemProfile_ZoomOut( g_memProfile_scale, PROFILE_SCALESTEPS );
+ return 0L;
+ }
+ break;
+
+ case WM_COMMAND:
+ switch ( wID )
+ {
+ case IDM_MEMPROFILE_TICKMARKS:
+ g_memProfile_tickMarks ^= 1;
+ MemProfile_UpdateWindow();
+ return 0L;
+
+ case IDM_MEMPROFILE_COLORS:
+ g_memProfile_colors ^= 1;
+ MemProfile_UpdateWindow();
+ return 0L;
+
+ case IDM_MEMPROFILE_ZOOMIN:
+ MemProfile_ZoomIn( g_memProfile_scale, PROFILE_SCALESTEPS );
+ return 0L;
+
+ case IDM_MEMPROFILE_ZOOMOUT:
+ MemProfile_ZoomOut( g_memProfile_scale, PROFILE_SCALESTEPS );
+ return 0L;
+
+ case IDM_MEMPROFILE_ENABLE:
+ bool bEnable = ( g_memProfile_Timer != NULL );
+ bEnable ^= 1;
+ MemProfile_EnableProfiling( bEnable );
+ MemProfile_SetTitle();
+ return 0L;
+ }
+ break;
+ }
+ return ( DefWindowProc( hwnd, message, wParam, lParam ) );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_Open
+//
+//-----------------------------------------------------------------------------
+void MemProfile_Open()
+{
+ HWND hWnd;
+
+ if ( g_memProfile_hWnd )
+ {
+ // only one profile instance
+ if ( IsIconic( g_memProfile_hWnd ) )
+ ShowWindow( g_memProfile_hWnd, SW_RESTORE );
+ SetForegroundWindow( g_memProfile_hWnd );
+ return;
+ }
+
+ hWnd = CreateWindowEx(
+ WS_EX_CLIENTEDGE,
+ "MEMPROFILECLASS",
+ "",
+ WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
+ 0,
+ 0,
+ 600,
+ 500,
+ g_hDlgMain,
+ NULL,
+ g_hInstance,
+ ( void* )ID_MEMPROFILE );
+ g_memProfile_hWnd = hWnd;
+
+ MemProfile_EnableProfiling( true );
+ MemProfile_SetTitle();
+
+ if ( g_memProfile_WindowRect.right && g_memProfile_WindowRect.bottom )
+ MoveWindow( g_memProfile_hWnd, g_memProfile_WindowRect.left, g_memProfile_WindowRect.top, g_memProfile_WindowRect.right-g_memProfile_WindowRect.left, g_memProfile_WindowRect.bottom-g_memProfile_WindowRect.top, FALSE );
+ ShowWindow( g_memProfile_hWnd, SHOW_OPENWINDOW );
+}
+
+//-----------------------------------------------------------------------------
+// MemProfile_Init
+//
+//-----------------------------------------------------------------------------
+bool MemProfile_Init()
+{
+ WNDCLASS wndclass;
+
+ // set up our window class
+ memset( &wndclass, 0, sizeof( wndclass ) );
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = MemProfile_WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInstance;
+ wndclass.hIcon = g_hIcons[ICON_APPLICATION];
+ wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
+ wndclass.hbrBackground = g_hBackgroundBrush;
+ wndclass.lpszMenuName = MAKEINTRESOURCE( MENU_MEMPROFILE );
+ wndclass.lpszClassName = "MEMPROFILECLASS";
+ if ( !RegisterClass( &wndclass ) )
+ return false;
+
+ MemProfile_LoadConfig();
+
+ return true;
+}