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.
 
 
 
 
 
 

983 lines
28 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// CPU_PROFILE.CPP
//
// Cpu Profiling Display
//=====================================================================================//
#include "vxconsole.h"
#define PROFILE_MAXCOUNTERS 64
#define PROFILE_MAXSAMPLES 512
#define PROFILE_HISTORY_TIMINGHEIGHT 100
#define PROFILE_HISTORY_NUMMINORTICKS 3
#define PROFILE_HISTORY_LABELWIDTH 50
#define PROFILE_HISTORY_SCALESTEPS 5
#define PROFILE_HISTORY_MINSCALE 0.3f
#define PROFILE_HISTORY_MAXSCALE 3.0f
#define PROFILE_SAMPLES_ITEMHEIGHT 15
#define PROFILE_SAMPLES_BARHEIGHT 10
#define PROFILE_SAMPLES_TIMINGWIDTH 200
#define PROFILE_SAMPLES_LABELWIDTH 150
#define PROFILE_SAMPLES_LABELGAP 5
#define PROFILE_SAMPLES_NUMMINORTICKS 3
#define PROFILE_SAMPLES_PEAKHOLDTIME 3000
#define PROFILE_SAMPLES_SCALESTEPS 10
#define PROFILE_SAMPLES_MINSCALE 0.3f
#define PROFILE_SAMPLES_MAXSCALE 3.0f
#define ID_CPUPROFILE_SAMPLES 1
#define ID_CPUPROFILE_HISTORY 2
typedef struct
{
unsigned int samples[PROFILE_MAXSAMPLES];
unsigned int peakSample;
char label[64];
COLORREF color;
} profileCounter_t;
HWND g_cpuProfile_hWndSamples;
HWND g_cpuProfile_hWndHistory;
int g_cpuProfile_numCounters;
profileCounter_t g_cpuProfile_counters[PROFILE_MAXCOUNTERS];
RECT g_cpuProfile_samplesWindowRect;
RECT g_cpuProfile_historyWindowRect;
DWORD g_cpuProfile_lastPeakTime;
bool g_cpuProfile_history_tickMarks = true;
bool g_cpuProfile_history_colors = true;
int g_cpuProfile_history_scale;
bool g_cpuProfile_samples_tickMarks = true;
bool g_cpuProfile_samples_colors = true;
int g_cpuProfile_samples_scale;
int g_cpuProfile_numSamples;
int g_cpuProfile_fpsLabels;
//-----------------------------------------------------------------------------
// CpuProfile_SaveConfig
//
//-----------------------------------------------------------------------------
void CpuProfile_SaveConfig()
{
char buff[256];
WINDOWPLACEMENT wp;
// profile samples
if ( g_cpuProfile_hWndSamples )
{
memset( &wp, 0, sizeof( wp ) );
wp.length = sizeof( WINDOWPLACEMENT );
GetWindowPlacement( g_cpuProfile_hWndSamples, &wp );
g_cpuProfile_samplesWindowRect = wp.rcNormalPosition;
sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
Sys_SetRegistryString( "profileSamplesWindowRect", buff );
}
Sys_SetRegistryInteger( "profileSamplesScale", g_cpuProfile_samples_scale );
// profile history
if ( g_cpuProfile_hWndHistory )
{
memset( &wp, 0, sizeof( wp ) );
wp.length = sizeof( WINDOWPLACEMENT );
GetWindowPlacement( g_cpuProfile_hWndHistory, &wp );
g_cpuProfile_historyWindowRect = wp.rcNormalPosition;
sprintf( buff, "%d %d %d %d", wp.rcNormalPosition.left, wp.rcNormalPosition.top, wp.rcNormalPosition.right, wp.rcNormalPosition.bottom );
Sys_SetRegistryString( "profileHistoryWindowRect", buff );
}
Sys_SetRegistryInteger( "profileHistoryScale", g_cpuProfile_history_scale );
Sys_SetRegistryInteger( "cpuProfileFpsLabels", g_cpuProfile_fpsLabels );
}
//-----------------------------------------------------------------------------
// CpuProfile_LoadConfig
//
//-----------------------------------------------------------------------------
void CpuProfile_LoadConfig()
{
int numArgs;
char buff[256];
// profile samples
Sys_GetRegistryString( "profileSamplesWindowRect", buff, "", sizeof( buff ) );
numArgs = sscanf( buff, "%d %d %d %d", &g_cpuProfile_samplesWindowRect.left, &g_cpuProfile_samplesWindowRect.top, &g_cpuProfile_samplesWindowRect.right, &g_cpuProfile_samplesWindowRect.bottom );
if ( numArgs != 4 )
memset( &g_cpuProfile_samplesWindowRect, 0, sizeof( g_cpuProfile_samplesWindowRect ) );
Sys_GetRegistryInteger( "profileSamplesScale", 0, g_cpuProfile_samples_scale );
if ( g_cpuProfile_samples_scale < -PROFILE_SAMPLES_SCALESTEPS || g_cpuProfile_samples_scale > PROFILE_SAMPLES_SCALESTEPS )
g_cpuProfile_samples_scale = 0;
// profile history
Sys_GetRegistryString( "profileHistoryWindowRect", buff, "", sizeof( buff ) );
numArgs = sscanf( buff, "%d %d %d %d", &g_cpuProfile_historyWindowRect.left, &g_cpuProfile_historyWindowRect.top, &g_cpuProfile_historyWindowRect.right, &g_cpuProfile_historyWindowRect.bottom );
if ( numArgs != 4 )
memset( &g_cpuProfile_historyWindowRect, 0, sizeof( g_cpuProfile_historyWindowRect ) );
Sys_GetRegistryInteger( "profileHistoryScale", 0, g_cpuProfile_history_scale );
if ( g_cpuProfile_history_scale < -PROFILE_HISTORY_SCALESTEPS || g_cpuProfile_history_scale > PROFILE_HISTORY_SCALESTEPS )
g_cpuProfile_history_scale = 0;
Sys_GetRegistryInteger( "cpuProfileFpsLabels", 0, g_cpuProfile_fpsLabels );
}
//-----------------------------------------------------------------------------
// CpuProfile_SetTitle
//
//-----------------------------------------------------------------------------
void CpuProfile_SetTitle()
{
char titleBuff[128];
if ( g_cpuProfile_hWndSamples )
{
strcpy( titleBuff, "CPU Usage Snapshot" );
if ( VProf_GetState() == VPROF_CPU )
strcat( titleBuff, " [ON]" );
SetWindowText( g_cpuProfile_hWndSamples, titleBuff );
}
if ( g_cpuProfile_hWndHistory )
{
strcpy( titleBuff, "CPU Usage History" );
if ( VProf_GetState() == VPROF_CPU )
strcat( titleBuff, " [ON]" );
SetWindowText( g_cpuProfile_hWndHistory, titleBuff );
}
}
//-----------------------------------------------------------------------------
// CpuProfile_UpdateWindow
//
//-----------------------------------------------------------------------------
void CpuProfile_UpdateWindow()
{
if ( g_cpuProfile_hWndSamples && !IsIconic( g_cpuProfile_hWndSamples ) )
{
// visible - force a client repaint
InvalidateRect( g_cpuProfile_hWndSamples, NULL, true );
}
if ( g_cpuProfile_hWndHistory && !IsIconic( g_cpuProfile_hWndHistory ) )
{
// visible - force a client repaint
InvalidateRect( g_cpuProfile_hWndHistory, NULL, true );
}
}
//-----------------------------------------------------------------------------
// rc_SetCpuProfile
//
//-----------------------------------------------------------------------------
int rc_SetCpuProfile( char* commandPtr )
{
int i;
char* cmdToken;
int retAddr;
int errCode = -1;
xrProfile_t* localList;
int profileList;
int numProfiles;
int retVal;
// get numProfiles
cmdToken = GetToken( &commandPtr );
if ( !cmdToken[0] )
goto cleanUp;
sscanf( cmdToken,"%x",&numProfiles );
// get profile attributes
cmdToken = GetToken( &commandPtr );
if ( !cmdToken[0] )
goto cleanUp;
sscanf( cmdToken, "%x", &profileList );
// get retAddr
cmdToken = GetToken( &commandPtr );
if ( !cmdToken[0] )
goto cleanUp;
sscanf( cmdToken,"%x",&retAddr );
localList = new xrProfile_t[numProfiles];
memset( localList, 0, numProfiles*sizeof( xrProfile_t ) );
// get the caller's profile list
DmGetMemory( ( void* )profileList, numProfiles*sizeof( xrProfile_t ), localList, NULL );
g_cpuProfile_numCounters = numProfiles;
if ( g_cpuProfile_numCounters > PROFILE_MAXCOUNTERS-1 )
g_cpuProfile_numCounters = PROFILE_MAXCOUNTERS-1;
for ( i=0; i<g_cpuProfile_numCounters; i++ )
{
// swap the structure
localList[i].color = BigDWord( localList[i].color );
// clear the old counter
memset( &g_cpuProfile_counters[i], 0, sizeof( profileCounter_t ) );
V_strncpy( g_cpuProfile_counters[i].label, localList[i].labelString, sizeof( g_cpuProfile_counters[i].label ) );
g_cpuProfile_counters[i].color = localList[i].color;
}
// build out the reserved last counter as total count
memset( &g_cpuProfile_counters[g_cpuProfile_numCounters], 0, sizeof( profileCounter_t ) );
strcpy( g_cpuProfile_counters[g_cpuProfile_numCounters].label, "Total" );
g_cpuProfile_counters[i].color = RGB( 255,255,255 );
g_cpuProfile_numCounters++;
// set the return code
retVal = g_cpuProfile_numCounters-1;
int xboxRetVal = BigDWord( retVal );
DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL );
DebugCommand( "0x%8.8x = SetCpuProfile( 0x%8.8x, 0x%8.8x )\n", retVal, numProfiles, profileList );
delete [] localList;
// success
errCode = 0;
cleanUp:
return ( errCode );
}
//-----------------------------------------------------------------------------
// rc_SetCpuProfileData
//
//-----------------------------------------------------------------------------
int rc_SetCpuProfileData( char* commandPtr )
{
int i;
int total;
char* cmdToken;
int errCode = -1;
int counters;
int currentSample;
bool newPeaks;
unsigned int localCounters[PROFILE_MAXCOUNTERS];
DWORD newTime;
// get profiles
cmdToken = GetToken( &commandPtr );
if ( !cmdToken[0] )
{
goto cleanUp;
}
sscanf( cmdToken, "%x", &counters );
// get the caller's profile list
if ( g_cpuProfile_numCounters )
{
DmGetMemory( ( void* )counters, ( g_cpuProfile_numCounters-1 )*sizeof( int ), localCounters, NULL );
}
// timeout peaks
newTime = Sys_GetSystemTime();
if ( newTime - g_cpuProfile_lastPeakTime > PROFILE_SAMPLES_PEAKHOLDTIME )
{
g_cpuProfile_lastPeakTime = newTime;
newPeaks = true;
}
else
{
newPeaks = false;
}
// next sample
currentSample = g_cpuProfile_numSamples % PROFILE_MAXSAMPLES;
g_cpuProfile_numSamples++;
total = 0;
for ( i=0; i<g_cpuProfile_numCounters; i++ )
{
// swap
localCounters[i] = BigDWord( localCounters[i] );
if ( i != g_cpuProfile_numCounters-1 )
{
g_cpuProfile_counters[i].samples[currentSample] = localCounters[i];
total += localCounters[i];
}
else
{
// reserved total counter
g_cpuProfile_counters[i].samples[currentSample] = total;
}
if ( newPeaks || g_cpuProfile_counters[i].peakSample < g_cpuProfile_counters[i].samples[currentSample] )
{
g_cpuProfile_counters[i].peakSample = g_cpuProfile_counters[i].samples[currentSample];
}
}
DebugCommand( "SetCpuProfileData( 0x%8.8x )\n", counters );
CpuProfile_UpdateWindow();
// success
errCode = 0;
cleanUp:
return ( errCode );
}
//-----------------------------------------------------------------------------
// CpuProfile_ZoomIn
//
//-----------------------------------------------------------------------------
void CpuProfile_ZoomIn( int& scale, int numSteps )
{
scale++;
if ( scale > numSteps )
{
scale = numSteps;
return;
}
CpuProfile_UpdateWindow();
}
//-----------------------------------------------------------------------------
// CpuProfile_ZoomOut
//
//-----------------------------------------------------------------------------
void CpuProfile_ZoomOut( int& scale, int numSteps )
{
scale--;
if ( scale < -numSteps )
{
scale = -numSteps;
return;
}
CpuProfile_UpdateWindow();
}
//-----------------------------------------------------------------------------
// CpuProfile_CalcScale
//
//-----------------------------------------------------------------------------
float CpuProfile_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;
}
//-----------------------------------------------------------------------------
// ProfileSamples_Draw
//
//-----------------------------------------------------------------------------
void ProfileSamples_Draw( HDC hdc, RECT* clientRect )
{
int i;
int j;
int x;
int y;
int x0;
int y0;
int w;
float t;
float scale;
float sampleTime;
char labelBuff[128];
HPEN hBlackPen;
HPEN hPenOld;
HPEN hGreyPen;
HBRUSH hColoredBrush;
HBRUSH hbrushOld;
HFONT hFontOld;
RECT rect;
int currentSample;
int numTicks;
int timingWidth;
int windowWidth;
int windowHeight;
hBlackPen = CreatePen( PS_SOLID, 1, RGB( 0,0,0 ) );
hGreyPen = CreatePen( PS_SOLID, 1, Sys_ColorScale( g_backgroundColor, 0.85f ) );
hPenOld = ( HPEN )SelectObject( hdc, hBlackPen );
hFontOld = SelectFont( hdc, g_hProportionalFont );
SetBkColor( hdc, g_backgroundColor );
// zoom
scale = CpuProfile_CalcScale( g_cpuProfile_samples_scale, PROFILE_SAMPLES_SCALESTEPS, PROFILE_SAMPLES_MINSCALE, PROFILE_SAMPLES_MAXSCALE );
timingWidth = ( int )( PROFILE_SAMPLES_TIMINGWIDTH*scale );
windowWidth = clientRect->right-clientRect->left;
windowHeight = clientRect->bottom-clientRect->top;
numTicks = ( windowWidth-PROFILE_SAMPLES_LABELWIDTH )/timingWidth + 1;
if ( numTicks < 0 )
numTicks = 1;
rect.left = 0;
rect.right = PROFILE_SAMPLES_LABELWIDTH;
rect.top = 0;
rect.bottom = PROFILE_SAMPLES_ITEMHEIGHT;
DrawText( hdc, "Name", -1, &rect, DT_LEFT );
// draw timing ticks
x = PROFILE_SAMPLES_LABELWIDTH;
y = 0;
for ( i=0; i<numTicks; i++ )
{
// tick labels
rect.left = x-40;
rect.right = x+40;
rect.top = y;
rect.bottom = y+PROFILE_SAMPLES_ITEMHEIGHT;
if ( !g_cpuProfile_fpsLabels )
sprintf( labelBuff, "%.2fms", i*( 1000.0f/60.0f ) );
else
sprintf( labelBuff, "%.2ffps", i == 0 ? 0 : 60.0f/i );
DrawText( hdc, labelBuff, -1, &rect, DT_CENTER );
// major ticks
x0 = x;
y0 = y + PROFILE_SAMPLES_ITEMHEIGHT;
SelectObject( hdc, hBlackPen );
MoveToEx( hdc, x0, y0, NULL );
LineTo( hdc, x0, y0+windowHeight );
if ( g_cpuProfile_samples_tickMarks && g_cpuProfile_samples_scale > -PROFILE_SAMPLES_SCALESTEPS )
{
// minor ticks
x0 = x;
y0 = y + PROFILE_SAMPLES_ITEMHEIGHT;
SelectObject( hdc, hGreyPen );
for ( j=0; j<PROFILE_SAMPLES_NUMMINORTICKS; j++ )
{
x0 += timingWidth/( PROFILE_SAMPLES_NUMMINORTICKS+1 );
MoveToEx( hdc, x0, y0, NULL );
LineTo( hdc, x0, y0+windowHeight );
}
}
x += timingWidth;
}
// seperator
SelectObject( hdc, hBlackPen );
MoveToEx( hdc, 0, PROFILE_SAMPLES_ITEMHEIGHT, NULL );
LineTo( hdc, windowWidth, PROFILE_SAMPLES_ITEMHEIGHT );
// draw labels
x = 0;
y = PROFILE_SAMPLES_ITEMHEIGHT;
for ( i=0; i<g_cpuProfile_numCounters; i++ )
{
if ( !g_cpuProfile_counters[i].label )
continue;
rect.left = x;
rect.right = x+PROFILE_SAMPLES_LABELWIDTH-PROFILE_SAMPLES_LABELGAP;
rect.top = y;
rect.bottom = y+PROFILE_SAMPLES_ITEMHEIGHT;
DrawText( hdc, g_cpuProfile_counters[i].label, -1, &rect, DT_VCENTER|DT_RIGHT|DT_SINGLELINE|DT_END_ELLIPSIS|DT_MODIFYSTRING );
// draw the under line
MoveToEx( hdc, x, y+PROFILE_SAMPLES_ITEMHEIGHT, NULL );
LineTo( hdc, x+PROFILE_SAMPLES_LABELWIDTH, y+PROFILE_SAMPLES_ITEMHEIGHT );
y += PROFILE_SAMPLES_ITEMHEIGHT;
}
// draw bars
SelectObject( hdc, hBlackPen );
x = PROFILE_SAMPLES_LABELWIDTH;
y = PROFILE_SAMPLES_ITEMHEIGHT;
currentSample = g_cpuProfile_numSamples-1;
if ( currentSample < 0 )
currentSample = 0;
else
currentSample %= PROFILE_MAXSAMPLES;
for ( i=0; i<g_cpuProfile_numCounters; i++ )
{
if ( !g_cpuProfile_counters[i].label )
continue;
hColoredBrush = CreateSolidBrush( g_cpuProfile_samples_colors ? g_cpuProfile_counters[i].color : g_backgroundColor );
hbrushOld = ( HBRUSH )SelectObject( hdc, hColoredBrush );
// bar - count is in us i.e. 1 major tick = 16667us
t = ( float )g_cpuProfile_counters[i].samples[currentSample]/( 1000000.0f/60.0f );
w = ( int )( t * ( float )timingWidth );
if ( w > windowWidth )
w = windowWidth;
x0 = x;
y0 = y + ( PROFILE_SAMPLES_ITEMHEIGHT-PROFILE_SAMPLES_BARHEIGHT )/2 + 1;
Rectangle( hdc, x0, y0, x0 + w, y0 + PROFILE_SAMPLES_BARHEIGHT );
// peak
t = ( float )g_cpuProfile_counters[i].peakSample/( 1000000.0f/60.0f );
w = ( int )( t * ( float )timingWidth );
if ( w > windowWidth )
w = windowWidth;
x0 = x + w;
y0 = y + PROFILE_SAMPLES_ITEMHEIGHT/2 + 1;
POINT points[4];
points[0].x = x0;
points[0].y = y0-4;
points[1].x = x0+4;
points[1].y = y0;
points[2].x = x0;
points[2].y = y0+4;
points[3].x = x0-4;
points[3].y = y0;
Polygon( hdc, points, 4 );
SelectObject( hdc, hbrushOld );
DeleteObject( hColoredBrush );
// draw peak times
sampleTime = ( float )g_cpuProfile_counters[i].peakSample/1000.0f;
if ( sampleTime >= 0.01F )
{
sprintf( labelBuff, "%.2f", sampleTime );
rect.left = x0 + 8;
rect.right = x0 + 8 + 100;
rect.top = y;
rect.bottom = y + PROFILE_SAMPLES_ITEMHEIGHT;
DrawText( hdc, labelBuff, -1, &rect, DT_VCENTER|DT_LEFT|DT_SINGLELINE );
}
y += PROFILE_SAMPLES_ITEMHEIGHT;
}
SelectObject( hdc, hFontOld );
SelectObject( hdc, hPenOld );
DeleteObject( hBlackPen );
DeleteObject( hGreyPen );
}
//-----------------------------------------------------------------------------
// ProfileHistory_Draw
//
//-----------------------------------------------------------------------------
void ProfileHistory_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 timingHeight;
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 = CpuProfile_CalcScale( g_cpuProfile_history_scale, PROFILE_HISTORY_SCALESTEPS, PROFILE_HISTORY_MINSCALE, PROFILE_HISTORY_MAXSCALE );
timingHeight = ( int )( PROFILE_HISTORY_TIMINGHEIGHT*scale );
windowWidth = clientRect->right-clientRect->left;
windowHeight = clientRect->bottom-clientRect->top;
numTicks = windowHeight/timingHeight + 2;
if ( numTicks < 0 )
numTicks = 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_cpuProfile_history_tickMarks && g_cpuProfile_history_scale > -PROFILE_HISTORY_SCALESTEPS )
{
// minor ticks
y0 = y;
SelectObject( hdc, hGreyPen );
for ( j=0; j<PROFILE_HISTORY_NUMMINORTICKS; j++ )
{
y0 += timingHeight/( PROFILE_SAMPLES_NUMMINORTICKS+1 );
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;
if ( !g_cpuProfile_fpsLabels )
sprintf( labelBuff, "%.2fms", i*( 1000.0f/60.0f ) );
else
sprintf( labelBuff, "%.2ffps", 60.0f/i );
DrawText( hdc, labelBuff, -1, &rect, DT_RIGHT|DT_SINGLELINE|DT_BOTTOM );
}
y -= timingHeight;
}
// vertical bars
if ( g_cpuProfile_numSamples )
{
SelectObject( hdc, hNullPen );
numbars = windowWidth-PROFILE_HISTORY_LABELWIDTH;
currentSample = g_cpuProfile_numSamples-1;
for ( x=numbars-1; x>=0; x-=4 )
{
// all the counters at this sample
y = windowHeight;
for ( j=0; j<g_cpuProfile_numCounters-1; j++ )
{
if ( !g_cpuProfile_counters[j].label )
continue;
t = ( float )g_cpuProfile_counters[j].samples[currentSample % PROFILE_MAXSAMPLES]/( 1000000.0f/60.0f );
h = ( int )( t * ( float )timingHeight );
if ( h )
{
if ( h > windowHeight )
h = windowHeight;
hColoredBrush = CreateSolidBrush( g_cpuProfile_history_colors ? g_cpuProfile_counters[j].color : 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 );
}
//-----------------------------------------------------------------------------
// CpuProfile_WndProc
//
//-----------------------------------------------------------------------------
LRESULT CALLBACK CpuProfile_WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
WORD wID = LOWORD( wParam );
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
int id;
bool bIsSamples;
bool bIsHistory;
CREATESTRUCT *createStructPtr;
// identify window
id = ( int )GetWindowLong( hwnd, GWL_USERDATA+0 );
bIsSamples = ( id == ID_CPUPROFILE_SAMPLES );
bIsHistory = ( id == ID_CPUPROFILE_HISTORY );
switch ( message )
{
case WM_CREATE:
// set the window identifier
createStructPtr = ( CREATESTRUCT* )lParam;
SetWindowLong( hwnd, GWL_USERDATA+0, ( LONG )createStructPtr->lpCreateParams );
// reset peaks
g_cpuProfile_lastPeakTime = 0;
return 0L;
case WM_DESTROY:
CpuProfile_SaveConfig();
if ( bIsSamples )
g_cpuProfile_hWndSamples = NULL;
else if ( bIsHistory )
g_cpuProfile_hWndHistory = NULL;
if ( VProf_GetState() == VPROF_CPU )
{
VProf_Enable( VPROF_OFF );
}
return 0L;
case WM_INITMENU:
if ( bIsSamples )
{
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_TICKMARKS, MF_BYCOMMAND | ( g_cpuProfile_samples_tickMarks ? MF_CHECKED : MF_UNCHECKED ) );
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_COLORS, MF_BYCOMMAND | ( g_cpuProfile_samples_colors ? MF_CHECKED : MF_UNCHECKED ) );
}
else if ( bIsHistory )
{
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_TICKMARKS, MF_BYCOMMAND | ( g_cpuProfile_history_tickMarks ? MF_CHECKED : MF_UNCHECKED ) );
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_COLORS, MF_BYCOMMAND | ( g_cpuProfile_history_colors ? MF_CHECKED : MF_UNCHECKED ) );
}
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_FPSLABELS, MF_BYCOMMAND | ( g_cpuProfile_fpsLabels ? MF_CHECKED : MF_UNCHECKED ) );
CheckMenuItem( ( HMENU )wParam, IDM_CPUPROFILE_ENABLE, MF_BYCOMMAND | ( VProf_GetState() == VPROF_CPU ? MF_CHECKED : MF_UNCHECKED ) );
return 0L;
case WM_PAINT:
GetClientRect( hwnd, &rect );
hdc = BeginPaint( hwnd, &ps );
if ( bIsSamples )
ProfileSamples_Draw( hdc, &rect );
else if ( bIsHistory )
ProfileHistory_Draw( hdc, &rect );
EndPaint( hwnd, &ps );
return 0L;
case WM_SIZE:
// force a redraw
CpuProfile_UpdateWindow();
return 0L;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_INSERT:
if ( bIsSamples )
CpuProfile_ZoomIn( g_cpuProfile_samples_scale, PROFILE_SAMPLES_SCALESTEPS );
else if ( bIsHistory )
CpuProfile_ZoomIn( g_cpuProfile_history_scale, PROFILE_HISTORY_SCALESTEPS );
return 0L;
case VK_DELETE:
if ( bIsSamples )
CpuProfile_ZoomOut( g_cpuProfile_samples_scale, PROFILE_SAMPLES_SCALESTEPS );
else if ( bIsHistory )
CpuProfile_ZoomOut( g_cpuProfile_history_scale, PROFILE_HISTORY_SCALESTEPS );
return 0L;
}
break;
case WM_COMMAND:
switch ( wID )
{
case IDM_CPUPROFILE_TICKMARKS:
if ( bIsSamples )
g_cpuProfile_samples_tickMarks ^= 1;
else if ( bIsHistory )
g_cpuProfile_history_tickMarks ^= 1;
CpuProfile_UpdateWindow();
return 0L;
case IDM_CPUPROFILE_COLORS:
if ( bIsSamples )
g_cpuProfile_samples_colors ^= 1;
else if ( bIsHistory )
g_cpuProfile_history_colors ^= 1;
CpuProfile_UpdateWindow();
return 0L;
case IDM_CPUPROFILE_FPSLABELS:
g_cpuProfile_fpsLabels ^= 1;
CpuProfile_UpdateWindow();
return 0L;
case IDM_CPUPROFILE_ZOOMIN:
if ( bIsSamples )
CpuProfile_ZoomIn( g_cpuProfile_samples_scale, PROFILE_SAMPLES_SCALESTEPS );
else if ( bIsHistory )
CpuProfile_ZoomIn( g_cpuProfile_history_scale, PROFILE_HISTORY_SCALESTEPS );
return 0L;
case IDM_CPUPROFILE_ZOOMOUT:
if ( bIsSamples )
CpuProfile_ZoomOut( g_cpuProfile_samples_scale, PROFILE_SAMPLES_SCALESTEPS );
else if ( bIsHistory )
CpuProfile_ZoomOut( g_cpuProfile_history_scale, PROFILE_HISTORY_SCALESTEPS );
return 0L;
case IDM_CPUPROFILE_ENABLE:
bool bEnable = ( VProf_GetState() == VPROF_CPU );
bEnable ^= 1;
if ( !bEnable )
VProf_Enable( VPROF_OFF );
else
VProf_Enable( VPROF_CPU );
CpuProfile_SetTitle();
return 0L;
}
break;
}
return ( DefWindowProc( hwnd, message, wParam, lParam ) );
}
//-----------------------------------------------------------------------------
// CpuProfileHistory_Open
//
//-----------------------------------------------------------------------------
void CpuProfileHistory_Open()
{
HWND hWnd;
if ( g_cpuProfile_hWndHistory )
{
// only one profile instance
if ( IsIconic( g_cpuProfile_hWndHistory ) )
ShowWindow( g_cpuProfile_hWndHistory, SW_RESTORE );
SetForegroundWindow( g_cpuProfile_hWndHistory );
return;
}
if ( VProf_GetState() == VPROF_OFF )
{
VProf_Enable( VPROF_CPU );
}
hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"CPUPROFILEHISTORYCLASS",
"",
WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
0,
0,
600,
500,
g_hDlgMain,
NULL,
g_hInstance,
( void* )ID_CPUPROFILE_HISTORY );
g_cpuProfile_hWndHistory = hWnd;
CpuProfile_SetTitle();
if ( g_cpuProfile_historyWindowRect.right && g_cpuProfile_historyWindowRect.bottom )
MoveWindow( g_cpuProfile_hWndHistory, g_cpuProfile_historyWindowRect.left, g_cpuProfile_historyWindowRect.top, g_cpuProfile_historyWindowRect.right-g_cpuProfile_historyWindowRect.left, g_cpuProfile_historyWindowRect.bottom-g_cpuProfile_historyWindowRect.top, FALSE );
ShowWindow( g_cpuProfile_hWndHistory, SHOW_OPENWINDOW );
}
//-----------------------------------------------------------------------------
// CpuProfileSamples_Open
//
//-----------------------------------------------------------------------------
void CpuProfileSamples_Open()
{
HWND hWnd;
if ( g_cpuProfile_hWndSamples )
{
// only one profile instance
if ( IsIconic( g_cpuProfile_hWndSamples ) )
ShowWindow( g_cpuProfile_hWndSamples, SW_RESTORE );
SetForegroundWindow( g_cpuProfile_hWndSamples );
return;
}
if ( VProf_GetState() == VPROF_OFF )
{
VProf_Enable( VPROF_CPU );
}
hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"CPUPROFILESAMPLESCLASS",
"",
WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_SIZEBOX|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
0,
0,
600,
500,
g_hDlgMain,
NULL,
g_hInstance,
( void* )ID_CPUPROFILE_SAMPLES );
g_cpuProfile_hWndSamples = hWnd;
CpuProfile_SetTitle();
if ( g_cpuProfile_samplesWindowRect.right && g_cpuProfile_samplesWindowRect.bottom )
MoveWindow( g_cpuProfile_hWndSamples, g_cpuProfile_samplesWindowRect.left, g_cpuProfile_samplesWindowRect.top, g_cpuProfile_samplesWindowRect.right-g_cpuProfile_samplesWindowRect.left, g_cpuProfile_samplesWindowRect.bottom-g_cpuProfile_samplesWindowRect.top, FALSE );
ShowWindow( g_cpuProfile_hWndSamples, SHOW_OPENWINDOW );
}
//-----------------------------------------------------------------------------
// CpuProfile_Clear
//
//-----------------------------------------------------------------------------
void CpuProfile_Clear()
{
// clear counters and history
g_cpuProfile_numCounters = 0;
g_cpuProfile_numSamples = 0;
CpuProfile_UpdateWindow();
}
//-----------------------------------------------------------------------------
// CpuProfile_Init
//
//-----------------------------------------------------------------------------
bool CpuProfile_Init()
{
WNDCLASS wndclass;
// set up our window class
memset( &wndclass, 0, sizeof( wndclass ) );
wndclass.style = 0;
wndclass.lpfnWndProc = CpuProfile_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_CPUPROFILE );
wndclass.lpszClassName = "CPUPROFILESAMPLESCLASS";
if ( !RegisterClass( &wndclass ) )
return false;
// set up our window class
memset( &wndclass, 0, sizeof( wndclass ) );
wndclass.style = 0;
wndclass.lpfnWndProc = CpuProfile_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_CPUPROFILE );
wndclass.lpszClassName = "CPUPROFILEHISTORYCLASS";
if ( !RegisterClass( &wndclass ) )
return false;
CpuProfile_LoadConfig();
return true;
}