void CTimeProfiler::AddTime(const std::string& name, unsigned time) { GML_STDMUTEX_LOCK_NOPROF(time); // AddTime std::map<std::string, TimeRecord>::iterator pi; if ( (pi = profile.find(name)) != profile.end() ) { pi->second.total+=time; pi->second.current+=time; pi->second.frames[currentPosition]+=time; } else { profile[name].total=time; profile[name].current=time; profile[name].percent=0; memset(profile[name].frames, 0, 128*sizeof(unsigned)); static UnsyncedRNG rand; rand.Seed(SDL_GetTicks()); profile[name].color.x = rand.RandFloat(); profile[name].color.y = rand.RandFloat(); profile[name].color.z = rand.RandFloat(); profile[name].showGraph=true; } }
void CTimeProfiler::Update() { GML_STDMUTEX_LOCK_NOPROF(time); // Update ++currentPosition; currentPosition &= 127; std::map<std::string,TimeRecord>::iterator pi; for (pi = profile.begin(); pi != profile.end(); ++pi) { pi->second.frames[currentPosition]=0; } const unsigned curTime = SDL_GetTicks(); const unsigned timeDiff = curTime - lastBigUpdate; if (timeDiff > 500) // twice every second { for (std::map<std::string,TimeRecord>::iterator pi = profile.begin(); pi != profile.end(); ++pi) { pi->second.percent = ((float)pi->second.current) / ((float)timeDiff); pi->second.current=0; } lastBigUpdate = curTime; } }
void CLogOutput::SetFileName(std::string fname) { GML_STDMUTEX_LOCK_NOPROF(log); // SetFileName assert(!initialized); fileName = fname; }
void CLogOutput::End() { GML_STDMUTEX_LOCK_NOPROF(log); // End SafeDelete(filelog); //log_file_removeLogFile(filePath.c_str()); }
void CTimeProfiler::AddTime(const std::string& name, unsigned time) { GML_STDMUTEX_LOCK_NOPROF(time); // AddTime std::map<std::string, TimeRecord>::iterator pi; if ( (pi = profile.find(name)) != profile.end() ) { // profile already exists pi->second.total+=time; pi->second.current+=time; pi->second.frames[currentPosition]+=time; } else { // create a new profile profile[name].total=time; profile[name].current=time; profile[name].percent=0; memset(profile[name].frames, 0, TimeRecord::frames_size*sizeof(unsigned)); static UnsyncedRNG rand; rand.Seed(SDL_GetTicks()); profile[name].color.x = rand.RandFloat(); profile[name].color.y = rand.RandFloat(); profile[name].color.z = rand.RandFloat(); // only show "CPU load" by default profile[name].showGraph = (name == "CPU load"); } }
bool ProfileDrawer::MousePress(int x, int y, int button) { GML_STDMUTEX_LOCK_NOPROF(time); // MousePress const float mx = MouseX(x); const float my = MouseY(y); // check if a Timer selection box was hit if (mx<start_x || mx>end_x || my<end_y-profiler.profile.size()*0.024f-0.01f || my>end_y) { return false; } const int selIndex = (int) ((end_y - my) / 0.024f); // switch the selected Timers showGraph value if ((selIndex >= 0) && (selIndex < profiler.profile.size())) { std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi = profiler.profile.begin(); for (int i = 0; i < selIndex; i++) { ++pi; } pi->second.showGraph = !pi->second.showGraph; } return false; }
void CLogOutput::Flush() { GML_STDMUTEX_LOCK_NOPROF(log); // Flush if (filelog != NULL) { filelog->flush(); } }
bool ProfileDrawer::IsAbove(int x, int y) { GML_STDMUTEX_LOCK_NOPROF(time); // IsAbove const float mx=MouseX(x); const float my=MouseY(y); if(mx<0.65f || mx>0.99f || my<0.99f - profiler.profile.size()*0.024f-0.01f || my>0.99f) return false; return true; }
bool ProfileDrawer::IsAbove(int x, int y) { GML_STDMUTEX_LOCK_NOPROF(time); // IsAbove const float mx = MouseX(x); const float my = MouseY(y); // check if a Timer selection box was hit if (mx<start_x || mx>end_x || my<end_y - profiler.profile.size()*0.024f-0.01f || my>end_y) { return false; } return true; }
bool ProfileDrawer::MousePress(int x, int y, int button) { GML_STDMUTEX_LOCK_NOPROF(time); // MousePress float mx=MouseX(x); float my=MouseY(y); if(mx<0.65f || mx>0.99f || my<0.99f-profiler.profile.size()*0.024f-0.01f || my>0.99f) return false; int num=(int) ((0.99f-my)/0.024f); int a=0; std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; for(pi=profiler.profile.begin();pi!=profiler.profile.end() && a!=num;++pi,a++){ } if(pi!=profiler.profile.end()) pi->second.showGraph=!pi->second.showGraph; return false; }
float CTimeProfiler::GetPercent(const char *name) { GML_STDMUTEX_LOCK_NOPROF(time); // GetTimePercent return profile[name].percent; }
void ProfileDrawer::Draw() { GML_STDMUTEX_LOCK_NOPROF(time); // Draw // draw the background of the window glDisable(GL_TEXTURE_2D); glColor4f(0.0f, 0.0f, 0.5f, 0.5f); if(!profiler.profile.empty()){ glBegin(GL_TRIANGLE_STRIP); glVertex3f(start_x, end_y, 0); glVertex3f(end_x, end_y, 0); glVertex3f(start_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); glVertex3f(end_x, end_y-profiler.profile.size()*0.024f-0.01f, 0); glEnd(); } std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; // draw the textual info (total-time, short-time percentual time, timer-name) int y = 0; font->Begin(); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { #if GML_MUTEX_PROFILER if (pi->first.size()<5 || pi->first.substr(pi->first.size()-5,5).compare("Mutex")!=0) { --y; continue; } const float fStartY = start_y - y * 0.020f; #else const float fStartY = start_y - y * 0.024f; #endif const float s = ((float)pi->second.total) / 1000.0f; const float p = pi->second.percent * 100; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.09f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", s); // print percent of CPU time used within the last 500ms fStartX += 0.08f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", p); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM, "%s", pi->first.c_str()); } font->End(); // draw the Timer selection boxes glPushMatrix(); glTranslatef(start_x + 0.005f, start_y, 0); glScalef(0.015f, 0.02f, 0.02f); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi){ glColorf3((float3)pi->second.color); glBegin(GL_QUADS); glVertex3f(0,0,0); glVertex3f(1,0,0); glVertex3f(1,1,0); glVertex3f(0,1,0); glEnd(); // draw the 'graph view disabled' cross if (!pi->second.showGraph) { glColor3f(1,0,0); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(1,1,0); glVertex3f(1,0,0); glVertex3f(0,1,0); glEnd(); } glTranslatef(0,-1.2f,0); } glPopMatrix(); // draw the graph for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) { if (!pi->second.showGraph) { continue; } CVertexArray* va = GetVertexArray(); va->Initialize(); const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size; for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) { // profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame) // This may be more then 1.0f, in case an operation // which ran over many frames, ended in this one. const float p = ((float)pi->second.frames[a]) / 1000.0f * GAME_SPEED; const float x = start_x + (a * steps_x); const float y = 0.02f + (p * 0.4f); va->AddVertex0(float3(x, y, 0.0f)); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glEnable(GL_TEXTURE_2D); }
void CLogOutput::End() { GML_STDMUTEX_LOCK_NOPROF(log); // End SafeDelete(filelog); }
void ProfileDrawer::Draw() { GML_STDMUTEX_LOCK_NOPROF(time); // Draw glPushMatrix(); glDisable(GL_TEXTURE_2D); glColor4f(0,0,0.5f,0.5f); if(!profiler.profile.empty()){ glBegin(GL_TRIANGLE_STRIP); glVertex3f(0.65f,0.99f,0); glVertex3f(0.99f,0.99f,0); glVertex3f(0.65f,0.99f-profiler.profile.size()*0.024f-0.01f,0); glVertex3f(0.99f,0.99f-profiler.profile.size()*0.024f-0.01f,0); glEnd(); } std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi; int y = 0; font->Begin(); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { #if GML_MUTEX_PROFILER if(pi->first.size()<5 || pi->first.substr(pi->first.size()-5,5).compare("Mutex")!=0) { --y; continue; } #endif font->glFormat(0.655f, 0.960f - y * 0.024f, 1.0f, FONT_SCALE | FONT_NORM, "%20s %6.2fs %5.2f%%", pi->first.c_str(), ((float)pi->second.total) / 1000.f, pi->second.percent * 100); } font->End(); glTranslatef(0.655f,0.965f,0); glScalef(0.015f,0.02f,0.02f); glDisable(GL_TEXTURE_2D); for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi){ glColorf3((float3)pi->second.color); glBegin(GL_QUADS); glVertex3f(0,0,0); glVertex3f(1,0,0); glVertex3f(1,1,0); glVertex3f(0,1,0); glEnd(); if(!pi->second.showGraph){ glColor3f(1,0,0); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(1,1,0); glVertex3f(1,0,0); glVertex3f(0,1,0); glEnd(); } glTranslatef(0,-1.2f,0); } glPopMatrix(); for(pi=profiler.profile.begin();pi!=profiler.profile.end();++pi){ if(!pi->second.showGraph) continue; CVertexArray* va=GetVertexArray(); va->Initialize(); for(int a=0;a<128;++a){ float p=((float)pi->second.frames[a])/1000.f*30; va->AddVertex0(float3(0.6f+a*0.003f,0.02f+p*0.4f,0.0f)); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glEnable(GL_TEXTURE_2D); }