diff options
Diffstat (limited to 'utils/xbox/vxconsole/mem_profile.cpp')
| -rw-r--r-- | utils/xbox/vxconsole/mem_profile.cpp | 561 |
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; +} |