mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user