|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Samples.DirectX.UtilityToolkit;
using AGE_Engine3D.RenderObjects;
using AGE_Engine3D.Text;
using AGE_Engine3D.Math;
using Tao.OpenGl;
namespace AGE_Engine3D
{
public class Profiler : IRenderOpenGL
{
#region Fields
int NUM_PROFILE_SAMPLE = 50;
ProfileSample[] Samples = null;
ProfileSampleHistory[] History = null;
double StartProfile = 0.0;
double EndProfile = 0.0;
double ElapsedTime = 0.0;
List<string> ProfileText = null;
bool _Isvisible = true;
Matrix_44 _WorldMatrix = Matrix_44.Identity();
public bool IsVisable { get { return _Isvisible; } }
#endregion
#region Methods
public void ProfileInit(int NumberOfProfile)
{
this.NUM_PROFILE_SAMPLE = NumberOfProfile;
Samples = new ProfileSample[NUM_PROFILE_SAMPLE];
History = new ProfileSampleHistory[NUM_PROFILE_SAMPLE];
for (int i = 0; i < NUM_PROFILE_SAMPLE; i++)
{
Samples[i].IsValid = false;
History[i].IsValid = false;
}
this.StartProfile = DXTimer.GetTime();
}
public void ProfileStartTime()
{
this.StartProfile = DXTimer.GetTime();
}
public void ProfileBegin(string Name)
{
int i = 0;
while (i < this.NUM_PROFILE_SAMPLE && Samples[i].IsValid)
{
if (this.Samples[i].Name == Name)
{
this.Samples[i].OpenProfiles++;
this.Samples[i].ProfileInstance++;
this.Samples[i].StartTime = DXTimer.GetTime();
if (this.Samples[i].OpenProfiles > 1)
Console.WriteLine("Max 1 Open At Once");
return;
}
i++;
}
if (i >= this.NUM_PROFILE_SAMPLE)
{
Console.WriteLine("Exceeded Max Available Profile Samples");
return;
}
this.Samples[i].Name = Name;
this.Samples[i].IsValid = true;
this.Samples[i].OpenProfiles = 1;
this.Samples[i].ProfileInstance = 1;
this.Samples[i].Accumulator = 0;
this.Samples[i].StartTime = DXTimer.GetTime();
this.Samples[i].ChildrenSampleTime = 0.0f;
}
public void ProfileEnd(string Name)
{
int i = 0;
uint NumParents = 0;
while (i < this.NUM_PROFILE_SAMPLE && Samples[i].IsValid == true)
{
if (Samples[i].Name == Name)
{//Found the Sample
int inner = 0;
int parent = -1;
double EndTime = DXTimer.GetTime();
Samples[i].OpenProfiles--;
//Count the Parents and Find the Immediate Parent
while (this.Samples[inner].IsValid == true)
{
if (Samples[inner].OpenProfiles > 0)
{//Found a Parent
NumParents++;
if (parent < 0)
{
parent = inner;
}
else if (Samples[inner].StartTime >= Samples[parent].StartTime)
{//Replace Parent with a more immediate parent
parent = inner;
}
}
inner++;
}
//Remember the current number of parents of the sample
this.Samples[i].NumParents = NumParents;
if (parent >= 0)
{//Record this time in the ChildrenSampleTime
Samples[parent].ChildrenSampleTime += (EndTime - Samples[i].StartTime);
}
Samples[i].Accumulator += (EndTime - Samples[i].StartTime);
return;
}
i++;
}
}
public void FinishProfile()
{
this.GetProfileData();
}
private void GetProfileData()
{
if (this.ProfileText == null) this.ProfileText = new List<string>();
else this.ProfileText.Clear();
List<string> result = this.ProfileText;
int i = 0;
this.EndProfile = DXTimer.GetTime();
this.ElapsedTime = this.EndProfile - this.StartProfile;
double InvDelta = 1 / (this.ElapsedTime);
result.Add(" Ave | Min | Max | # | Profile Name ");
result.Add("---------------------------------------------------------------------");
while (i < this.NUM_PROFILE_SAMPLE && Samples[i].IsValid)
{
double sampleTime, percentTime, AveTime, MinTime, MaxTime;
if (this.Samples[i].OpenProfiles < 0)
Console.WriteLine("ProfileEnd() called Without a ProfileBegin()");
else if (this.Samples[i].OpenProfiles > 0)
Console.WriteLine("ProfileBegin() called Without a ProfileEnd()");
sampleTime = this.Samples[i].Accumulator - this.Samples[i].ChildrenSampleTime;
percentTime = sampleTime * InvDelta * 100;
AveTime = MinTime = MaxTime = percentTime;
this.StoreProfileInHistory(this.Samples[i].Name, percentTime);
this.GetProFileFromHistory(this.Samples[i].Name, ref AveTime, ref MinTime, ref MaxTime);
String Output = AveTime.ToString(" #00.0 ") + "|" + MinTime.ToString(" #00.0 ") + "|" +
MaxTime.ToString(" #00.0 ") + "|" + Samples[i].ProfileInstance.ToString(" 00 ") + "|";
for (int Indent = 0; Indent < Samples[i].NumParents; Indent++)
{
Output = Output + " ";
}
Output = Output + Samples[i].Name;
result.Add(Output);
i++;
}
for (i = 0; i < this.NUM_PROFILE_SAMPLE; i++)
{
Samples[i].IsValid = false;
}
}
void StoreProfileInHistory(string Name, double percent)
{
int i = 0;
double OldRatio;
double NewRatio = 0.8 * this.ElapsedTime;
if (NewRatio > 1)
NewRatio = 1;
OldRatio = 1 - NewRatio;
while (i < this.NUM_PROFILE_SAMPLE && this.History[i].IsValid)
{
if (this.History[i].Name == Name)
{
this.History[i].Ave = (this.History[i].Ave * this.History[i].NumCalc + percent) /
(this.History[i].NumCalc + 1);
this.History[i].NumCalc++;
if (percent < this.History[i].Min)
this.History[i].Min = percent;
if (percent > this.History[i].MAx)
this.History[i].MAx = percent;
return;
}
i++;
}
if (i < this.NUM_PROFILE_SAMPLE)
{
this.History[i].Name = Name;
this.History[i].IsValid = true;
this.History[i].Ave = this.History[i].Min = this.History[i].MAx = percent;
}
else
Console.WriteLine("Exceeded Max Available Profile Samples");
}
void GetProFileFromHistory(string Name, ref double Ave, ref double Min, ref double Max)
{
for (int i = 0; i < this.NUM_PROFILE_SAMPLE; i++)
{
if (this.History[i].IsValid && this.History[i].Name == Name)
{
Ave = this.History[i].Ave;
Min = this.History[i].Min;
Max = this.History[i].MAx;
return;
}
}
Ave = Min = Max = 0;
}
public void RenderOpenGL()
{
if (this.ProfileText != null)
{
if (this.ProfileText.Count > 0)
{
IFont DefaultFont = ResourceManager.GetFont("Verdana");
float FontHieght = DefaultFont.CharHeight*1.25f;
if (DefaultFont != null)
{
#region Set the Model View Matrix
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glTranslatef(0,SceneGraph.ScreenHeight, 0);
#endregion
Gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
Gl.glTranslatef(0, -13, 0);
Gl.glScalef(20, 20, 1);
foreach (string text in this.ProfileText)
{
DefaultFont.glPrint(text);
Gl.glTranslatef(0, -FontHieght, 0);
}
DefaultFont.glPrint("---------------------------------------------------------------------");
Gl.glTranslatef(0, -FontHieght, 0);
DefaultFont.glPrint("Frames Per Second :" + DXTimer.lastFrameRate);
Gl.glTranslatef(0, -FontHieght, 0);
double ElapsedTime = System.Math.Round(1000*DXTimer.GetElapsedTime(),1);
DefaultFont.glPrint("Elapsed Time (ms) :" + ElapsedTime.ToString("####"));
}
}
}
}
#endregion
}
public struct ProfileSample
{
public bool IsValid;
public uint ProfileInstance;
public int OpenProfiles;
public string Name;
public double StartTime;
public double Accumulator;
public double ChildrenSampleTime;
public uint NumParents;
}
public struct ProfileSampleHistory
{
public bool IsValid;
public string Name;
public double Ave;
public double Min;
public double MAx;
public long NumCalc;
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am a licensed Electrical Engineer at Lea+Elliott, Inc. We specialize in the planning, procurement and implementation of transportation systems, with special emphasis on automated and emerging technologies.