Profiler graph
parent
2f2ef80ec2
commit
7d1ac4d1f6
|
@ -656,9 +656,11 @@ void Client::step(float dtime)
|
||||||
/*infostream<<"Mesh update result queue size is "
|
/*infostream<<"Mesh update result queue size is "
|
||||||
<<m_mesh_update_thread.m_queue_out.size()
|
<<m_mesh_update_thread.m_queue_out.size()
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
|
|
||||||
|
int num_processed_meshes = 0;
|
||||||
while(m_mesh_update_thread.m_queue_out.size() > 0)
|
while(m_mesh_update_thread.m_queue_out.size() > 0)
|
||||||
{
|
{
|
||||||
|
num_processed_meshes++;
|
||||||
MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_front();
|
MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_front();
|
||||||
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p);
|
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p);
|
||||||
if(block)
|
if(block)
|
||||||
|
@ -699,6 +701,8 @@ void Client::step(float dtime)
|
||||||
m_con.Send(PEER_ID_SERVER, 1, reply, true);
|
m_con.Send(PEER_ID_SERVER, 1, reply, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(num_processed_meshes > 0)
|
||||||
|
g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -752,6 +756,7 @@ void Client::ReceiveAll()
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Receive();
|
Receive();
|
||||||
|
g_profiler->graphAdd("client_received_packets", 1);
|
||||||
}
|
}
|
||||||
catch(con::NoIncomingDataException &e)
|
catch(con::NoIncomingDataException &e)
|
||||||
{
|
{
|
||||||
|
|
226
src/game.cpp
226
src/game.cpp
|
@ -55,6 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "quicktune_shortcutter.h"
|
#include "quicktune_shortcutter.h"
|
||||||
#include "clientmap.h"
|
#include "clientmap.h"
|
||||||
#include "sky.h"
|
#include "sky.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Setting this to 1 enables a special camera mode that forces
|
Setting this to 1 enables a special camera mode that forces
|
||||||
|
@ -602,6 +603,159 @@ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ProfilerGraph
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct Piece{
|
||||||
|
Profiler::GraphValues values;
|
||||||
|
};
|
||||||
|
struct Meta{
|
||||||
|
float min;
|
||||||
|
float max;
|
||||||
|
video::SColor color;
|
||||||
|
Meta(float initial=0, video::SColor color=
|
||||||
|
video::SColor(255,255,255,255)):
|
||||||
|
min(initial),
|
||||||
|
max(initial),
|
||||||
|
color(color)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
std::list<Piece> m_log;
|
||||||
|
public:
|
||||||
|
u32 m_log_max_size;
|
||||||
|
|
||||||
|
ProfilerGraph():
|
||||||
|
m_log_max_size(200)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void put(const Profiler::GraphValues &values)
|
||||||
|
{
|
||||||
|
Piece piece;
|
||||||
|
piece.values = values;
|
||||||
|
m_log.push_back(piece);
|
||||||
|
while(m_log.size() > m_log_max_size)
|
||||||
|
m_log.erase(m_log.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver,
|
||||||
|
gui::IGUIFont* font) const
|
||||||
|
{
|
||||||
|
std::map<std::string, Meta> m_meta;
|
||||||
|
for(std::list<Piece>::const_iterator k = m_log.begin();
|
||||||
|
k != m_log.end(); k++)
|
||||||
|
{
|
||||||
|
const Piece &piece = *k;
|
||||||
|
for(Profiler::GraphValues::const_iterator i = piece.values.begin();
|
||||||
|
i != piece.values.end(); i++){
|
||||||
|
const std::string &id = i->first;
|
||||||
|
const float &value = i->second;
|
||||||
|
std::map<std::string, Meta>::iterator j =
|
||||||
|
m_meta.find(id);
|
||||||
|
if(j == m_meta.end()){
|
||||||
|
m_meta[id] = Meta(value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(value < j->second.min)
|
||||||
|
j->second.min = value;
|
||||||
|
if(value > j->second.max)
|
||||||
|
j->second.max = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign colors
|
||||||
|
static const video::SColor usable_colors[] = {
|
||||||
|
video::SColor(255,255,100,100),
|
||||||
|
video::SColor(255,90,225,90),
|
||||||
|
video::SColor(255,100,100,255)
|
||||||
|
};
|
||||||
|
static const u32 usable_colors_count =
|
||||||
|
sizeof(usable_colors) / sizeof(*usable_colors);
|
||||||
|
u32 next_color_i = 0;
|
||||||
|
for(std::map<std::string, Meta>::iterator i = m_meta.begin();
|
||||||
|
i != m_meta.end(); i++){
|
||||||
|
Meta &meta = i->second;
|
||||||
|
video::SColor color(255,200,200,200);
|
||||||
|
if(next_color_i < usable_colors_count)
|
||||||
|
color = usable_colors[next_color_i++];
|
||||||
|
meta.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 graphh = 50;
|
||||||
|
s32 textx = x_left + m_log_max_size + 15;
|
||||||
|
s32 textx2 = textx + 200 - 15;
|
||||||
|
|
||||||
|
// Draw background
|
||||||
|
/*{
|
||||||
|
u32 num_graphs = m_meta.size();
|
||||||
|
core::rect<s32> rect(x_left, y_bottom - num_graphs*graphh,
|
||||||
|
textx2, y_bottom);
|
||||||
|
video::SColor bgcolor(120,0,0,0);
|
||||||
|
driver->draw2DRectangle(bgcolor, rect, NULL);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
s32 meta_i = 0;
|
||||||
|
for(std::map<std::string, Meta>::const_iterator i = m_meta.begin();
|
||||||
|
i != m_meta.end(); i++){
|
||||||
|
const std::string &id = i->first;
|
||||||
|
const Meta &meta = i->second;
|
||||||
|
s32 x = x_left;
|
||||||
|
s32 y = y_bottom - meta_i * 50;
|
||||||
|
float show_min = meta.min;
|
||||||
|
float show_max = meta.max;
|
||||||
|
if(show_min >= 0 && show_max >= 0){
|
||||||
|
if(show_min <= show_max * 0.5)
|
||||||
|
show_min = 0;
|
||||||
|
}
|
||||||
|
s32 texth = 15;
|
||||||
|
char buf[10];
|
||||||
|
snprintf(buf, 10, "%.3g", show_max);
|
||||||
|
font->draw(narrow_to_wide(buf).c_str(),
|
||||||
|
core::rect<s32>(textx, y - graphh,
|
||||||
|
textx2, y - graphh + texth),
|
||||||
|
meta.color);
|
||||||
|
snprintf(buf, 10, "%.3g", show_min);
|
||||||
|
font->draw(narrow_to_wide(buf).c_str(),
|
||||||
|
core::rect<s32>(textx, y - texth,
|
||||||
|
textx2, y),
|
||||||
|
meta.color);
|
||||||
|
font->draw(narrow_to_wide(id).c_str(),
|
||||||
|
core::rect<s32>(textx, y - graphh/2 - texth/2,
|
||||||
|
textx2, y - graphh/2 + texth/2),
|
||||||
|
meta.color);
|
||||||
|
for(std::list<Piece>::const_iterator j = m_log.begin();
|
||||||
|
j != m_log.end(); j++)
|
||||||
|
{
|
||||||
|
const Piece &piece = *j;
|
||||||
|
float value = 0;
|
||||||
|
bool value_exists = false;
|
||||||
|
Profiler::GraphValues::const_iterator k =
|
||||||
|
piece.values.find(id);
|
||||||
|
if(k != piece.values.end()){
|
||||||
|
value = k->second;
|
||||||
|
value_exists = true;
|
||||||
|
}
|
||||||
|
if(!value_exists){
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
float scaledvalue = 1.0;
|
||||||
|
if(show_max != show_min)
|
||||||
|
scaledvalue = (value - show_min) / (show_max - show_min);
|
||||||
|
if(scaledvalue == 1.0 && value == 0){
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s32 ivalue = scaledvalue * graphh;
|
||||||
|
driver->draw2DLine(v2s32(x, y),
|
||||||
|
v2s32(x, y - ivalue),
|
||||||
|
meta.color);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
meta_i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void the_game(
|
void the_game(
|
||||||
bool &kill,
|
bool &kill,
|
||||||
bool random_input,
|
bool random_input,
|
||||||
|
@ -938,7 +1092,7 @@ void the_game(
|
||||||
L"<Profiler>",
|
L"<Profiler>",
|
||||||
core::rect<s32>(0,0,0,0),
|
core::rect<s32>(0,0,0,0),
|
||||||
false, false);
|
false, false);
|
||||||
guitext_profiler->setBackgroundColor(video::SColor(80,0,0,0));
|
guitext_profiler->setBackgroundColor(video::SColor(120,0,0,0));
|
||||||
guitext_profiler->setVisible(false);
|
guitext_profiler->setVisible(false);
|
||||||
|
|
||||||
/*GUIQuickInventory *quick_inventory = new GUIQuickInventory
|
/*GUIQuickInventory *quick_inventory = new GUIQuickInventory
|
||||||
|
@ -968,13 +1122,14 @@ void the_game(
|
||||||
u32 beginscenetime = 0;
|
u32 beginscenetime = 0;
|
||||||
u32 scenetime = 0;
|
u32 scenetime = 0;
|
||||||
u32 endscenetime = 0;
|
u32 endscenetime = 0;
|
||||||
|
u32 alltime = 0;
|
||||||
|
|
||||||
// A test
|
// A test
|
||||||
//throw con::PeerNotFoundException("lol");
|
//throw con::PeerNotFoundException("lol");
|
||||||
|
|
||||||
float recent_turn_speed = 0.0;
|
float recent_turn_speed = 0.0;
|
||||||
|
|
||||||
core::list<float> frametime_log;
|
ProfilerGraph graph;
|
||||||
|
|
||||||
float nodig_delay_timer = 0.0;
|
float nodig_delay_timer = 0.0;
|
||||||
float dig_time = 0.0;
|
float dig_time = 0.0;
|
||||||
|
@ -1000,7 +1155,7 @@ void the_game(
|
||||||
bool force_fog_off = false;
|
bool force_fog_off = false;
|
||||||
bool disable_camera_update = false;
|
bool disable_camera_update = false;
|
||||||
bool show_debug = g_settings->getBool("show_debug");
|
bool show_debug = g_settings->getBool("show_debug");
|
||||||
bool show_debug_frametime = false;
|
bool show_profiler_graph = false;
|
||||||
u32 show_profiler = 0;
|
u32 show_profiler = 0;
|
||||||
u32 show_profiler_max = 3; // Number of pages
|
u32 show_profiler_max = 3; // Number of pages
|
||||||
|
|
||||||
|
@ -1022,9 +1177,12 @@ void the_game(
|
||||||
// NOTE: So we have to use getTime() and call run()s between them
|
// NOTE: So we have to use getTime() and call run()s between them
|
||||||
u32 lasttime = device->getTimer()->getTime();
|
u32 lasttime = device->getTimer()->getTime();
|
||||||
|
|
||||||
while(device->run() && kill == false)
|
for(;;)
|
||||||
{
|
{
|
||||||
//std::cerr<<"frame"<<std::endl;
|
TimeTaker tt_all("mainloop: all");
|
||||||
|
|
||||||
|
if(device->run() == false || kill == true)
|
||||||
|
break;
|
||||||
|
|
||||||
if(client.accessDenied())
|
if(client.accessDenied())
|
||||||
{
|
{
|
||||||
|
@ -1142,16 +1300,6 @@ void the_game(
|
||||||
g_profiler->add("Elapsed time", dtime);
|
g_profiler->add("Elapsed time", dtime);
|
||||||
g_profiler->avg("FPS", 1./dtime);
|
g_profiler->avg("FPS", 1./dtime);
|
||||||
|
|
||||||
/*
|
|
||||||
Log frametime for visualization
|
|
||||||
*/
|
|
||||||
frametime_log.push_back(dtime);
|
|
||||||
if(frametime_log.size() > 100)
|
|
||||||
{
|
|
||||||
core::list<float>::Iterator i = frametime_log.begin();
|
|
||||||
frametime_log.erase(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Visualize frametime in terminal
|
Visualize frametime in terminal
|
||||||
*/
|
*/
|
||||||
|
@ -1434,25 +1582,25 @@ void the_game(
|
||||||
{
|
{
|
||||||
// Initial / 3x toggle: Chat only
|
// Initial / 3x toggle: Chat only
|
||||||
// 1x toggle: Debug text with chat
|
// 1x toggle: Debug text with chat
|
||||||
// 2x toggle: Debug text with frametime
|
// 2x toggle: Debug text with profiler graph
|
||||||
if(!show_debug)
|
if(!show_debug)
|
||||||
{
|
{
|
||||||
show_debug = true;
|
show_debug = true;
|
||||||
show_debug_frametime = false;
|
show_profiler_graph = false;
|
||||||
statustext = L"Debug info shown";
|
statustext = L"Debug info shown";
|
||||||
statustext_time = 0;
|
statustext_time = 0;
|
||||||
}
|
}
|
||||||
else if(show_debug_frametime)
|
else if(show_profiler_graph)
|
||||||
{
|
{
|
||||||
show_debug = false;
|
show_debug = false;
|
||||||
show_debug_frametime = false;
|
show_profiler_graph = false;
|
||||||
statustext = L"Debug info and frametime graph hidden";
|
statustext = L"Debug info and profiler graph hidden";
|
||||||
statustext_time = 0;
|
statustext_time = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
show_debug_frametime = true;
|
show_profiler_graph = true;
|
||||||
statustext = L"Frametime graph shown";
|
statustext = L"Profiler graph shown";
|
||||||
statustext_time = 0;
|
statustext_time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2413,7 +2561,7 @@ void the_game(
|
||||||
Drawing begins
|
Drawing begins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TimeTaker drawtimer("Drawing");
|
TimeTaker tt_draw("mainloop: draw");
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2479,22 +2627,11 @@ void the_game(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Frametime log
|
Profiler graph
|
||||||
*/
|
*/
|
||||||
if(show_debug_frametime)
|
if(show_profiler_graph)
|
||||||
{
|
{
|
||||||
s32 x = 10;
|
graph.draw(10, screensize.Y - 10, driver, font);
|
||||||
s32 y = screensize.Y - 10;
|
|
||||||
for(core::list<float>::Iterator
|
|
||||||
i = frametime_log.begin();
|
|
||||||
i != frametime_log.end();
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
driver->draw2DLine(v2s32(x,y),
|
|
||||||
v2s32(x,y-(*i)*1000),
|
|
||||||
video::SColor(255,255,255,255));
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2559,7 +2696,8 @@ void the_game(
|
||||||
endscenetime = timer.stop(true);
|
endscenetime = timer.stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawtime = drawtimer.stop(true);
|
drawtime = tt_draw.stop(true);
|
||||||
|
g_profiler->graphAdd("mainloop_draw", (float)drawtime/1000.0f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
End of drawing
|
End of drawing
|
||||||
|
@ -2579,6 +2717,16 @@ void the_game(
|
||||||
device->setWindowCaption(str.c_str());
|
device->setWindowCaption(str.c_str());
|
||||||
lastFPS = fps;
|
lastFPS = fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alltime = tt_all.stop(true);
|
||||||
|
g_profiler->graphAdd("mainloop_other", (float)(alltime-drawtime)/1000.0f);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Log times and stuff for visualization
|
||||||
|
*/
|
||||||
|
Profiler::GraphValues values;
|
||||||
|
g_profiler->graphGet(values);
|
||||||
|
graph.put(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include <jmutex.h>
|
#include <jmutex.h>
|
||||||
#include <jmutexautolock.h>
|
#include <jmutexautolock.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Time profiler
|
Time profiler
|
||||||
|
@ -146,10 +147,30 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef std::map<std::string, float> GraphValues;
|
||||||
|
|
||||||
|
void graphAdd(const std::string &id, float value)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
std::map<std::string, float>::iterator i =
|
||||||
|
m_graphvalues.find(id);
|
||||||
|
if(i == m_graphvalues.end())
|
||||||
|
m_graphvalues[id] = value;
|
||||||
|
else
|
||||||
|
i->second += value;
|
||||||
|
}
|
||||||
|
void graphGet(GraphValues &result)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
result = m_graphvalues;
|
||||||
|
m_graphvalues.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JMutex m_mutex;
|
JMutex m_mutex;
|
||||||
core::map<std::string, float> m_data;
|
core::map<std::string, float> m_data;
|
||||||
core::map<std::string, int> m_avgcounts;
|
core::map<std::string, int> m_avgcounts;
|
||||||
|
std::map<std::string, float> m_graphvalues;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ScopeProfilerType{
|
enum ScopeProfilerType{
|
||||||
|
|
Loading…
Reference in New Issue