1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Better F6 profiler (#8750)

Update the profiler names to make more sense of what they actually represent
Move the profiler code from header to its source file
Use monospace font to align lines
Format the statistics line to align better with surrounding values
Refresh the profiler each 3 seconds (roughly)
This commit is contained in:
SmallJoker 2019-08-13 19:56:55 +02:00 committed by GitHub
parent e9ceead81d
commit 539f016c1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 256 additions and 324 deletions

View file

@ -116,7 +116,6 @@ void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes,
void ClientMap::updateDrawList()
{
ScopeProfiler sp(g_profiler, "CM::updateDrawList()", SPT_AVG);
g_profiler->add("CM::updateDrawList() count", 1);
for (auto &i : m_drawlist) {
MapBlock *block = i.second;
@ -138,23 +137,10 @@ void ClientMap::updateDrawList()
v3s16 p_blocks_max;
getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max);
// Number of blocks in rendering range
u32 blocks_in_range = 0;
// Number of blocks with mesh in rendering range
u32 blocks_in_range_with_mesh = 0;
// Number of blocks occlusion culled
u32 blocks_occlusion_culled = 0;
// Number of blocks in rendering range but don't have a mesh
u32 blocks_in_range_without_mesh = 0;
// Blocks that had mesh that would have been drawn according to
// rendering range (if max blocks limit didn't kick in)
u32 blocks_would_have_drawn = 0;
// Blocks that were drawn and had a mesh
u32 blocks_drawn = 0;
// Blocks which had a corresponding meshbuffer for this pass
//u32 blocks_had_pass_meshbuf = 0;
// Blocks from which stuff was actually drawn
//u32 blocks_without_stuff = 0;
// Distance to farthest drawn block
float farthest_drawn = 0;
// No occlusion culling when free_move is on and camera is
// inside ground
@ -185,11 +171,11 @@ void ClientMap::updateDrawList()
u32 sector_blocks_drawn = 0;
for (auto block : sectorblocks) {
for (MapBlock *block : sectorblocks) {
/*
Compare block position to camera position, skip
if not seen on display
*/
Compare block position to camera position, skip
if not seen on display
*/
if (block->mesh)
block->mesh->updateCameraOffset(m_camera_offset);
@ -203,20 +189,20 @@ void ClientMap::updateDrawList()
camera_direction, camera_fov, range, &d))
continue;
blocks_in_range++;
/*
Ignore if mesh doesn't exist
*/
if (!block->mesh) {
blocks_in_range_without_mesh++;
if (!block->mesh)
continue;
}
blocks_in_range_with_mesh++;
/*
Occlusion culling
*/
if (occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes)) {
if ((!m_control.range_all && d > m_control.wanted_range * BS) ||
(occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) {
blocks_occlusion_culled++;
continue;
}
@ -224,36 +210,20 @@ void ClientMap::updateDrawList()
// This block is in range. Reset usage timer.
block->resetUsageTimer();
// Limit block count in case of a sudden increase
blocks_would_have_drawn++;
if (blocks_drawn >= m_control.wanted_max_blocks &&
!m_control.range_all &&
d > m_control.wanted_range * BS)
continue;
// Add to set
block->refGrab();
m_drawlist[block->getPos()] = block;
sector_blocks_drawn++;
blocks_drawn++;
if (d / BS > farthest_drawn)
farthest_drawn = d / BS;
} // foreach sectorblocks
if (sector_blocks_drawn != 0)
m_last_drawn_sectors.insert(sp);
}
g_profiler->avg("CM: blocks in range", blocks_in_range);
g_profiler->avg("CM: blocks occlusion culled", blocks_occlusion_culled);
if (blocks_in_range != 0)
g_profiler->avg("CM: blocks in range without mesh (frac)",
(float)blocks_in_range_without_mesh / blocks_in_range);
g_profiler->avg("CM: blocks drawn", blocks_drawn);
g_profiler->avg("CM: farthest drawn", farthest_drawn);
g_profiler->avg("CM: wanted max blocks", m_control.wanted_max_blocks);
g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh);
g_profiler->avg("MapBlocks occlusion culled [#]", blocks_occlusion_culled);
g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size());
}
struct MeshBufList
@ -306,9 +276,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
std::string prefix;
if (pass == scene::ESNRP_SOLID)
prefix = "CM: solid: ";
prefix = "renderMap(SOLID): ";
else
prefix = "CM: transparent: ";
prefix = "renderMap(TRANSPARENT): ";
/*
This is called two times per frame, reset on the non-transparent one
@ -316,14 +286,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
if (pass == scene::ESNRP_SOLID)
m_last_drawn_sectors.clear();
/*
Get time for measuring timeout.
Measuring time is very useful for long delays when the
machine is swapping a lot.
*/
std::time_t time1 = time(0);
/*
Get animation parameters
*/
@ -340,26 +302,15 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
*/
u32 vertex_count = 0;
u32 meshbuffer_count = 0;
// For limiting number of mesh animations per frame
u32 mesh_animate_count = 0;
u32 mesh_animate_count_far = 0;
// Blocks that were drawn and had a mesh
u32 blocks_drawn = 0;
// Blocks which had a corresponding meshbuffer for this pass
u32 blocks_had_pass_meshbuf = 0;
// Blocks from which stuff was actually drawn
u32 blocks_without_stuff = 0;
//u32 mesh_animate_count_far = 0;
/*
Draw the selected MapBlocks
*/
{
ScopeProfiler sp(g_profiler, prefix + "drawing blocks", SPT_AVG);
MeshBufListList drawbufs;
for (auto &i : m_drawlist) {
@ -381,15 +332,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
assert(mapBlockMesh);
// Pretty random but this should work somewhat nicely
bool faraway = d >= BS * 50;
//bool faraway = d >= m_control.wanted_range * BS;
if (mapBlockMesh->isAnimationForced() || !faraway ||
mesh_animate_count_far < (m_control.range_all ? 200 : 50)) {
mesh_animate_count < (m_control.range_all ? 200 : 50)) {
bool animated = mapBlockMesh->animate(faraway, animation_time,
crack, daynight_ratio);
if (animated)
mesh_animate_count++;
if (animated && faraway)
mesh_animate_count_far++;
} else {
mapBlockMesh->decreaseAnimationForceTimer();
}
@ -437,46 +386,33 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
}
}
TimeTaker draw("Drawing mesh buffers");
// Render all layers in order
for (auto &lists : drawbufs.lists) {
int timecheck_counter = 0;
for (MeshBufList &list : lists) {
timecheck_counter++;
if (timecheck_counter > 50) {
timecheck_counter = 0;
std::time_t time2 = time(0);
if (time2 > time1 + 4) {
infostream << "ClientMap::renderMap(): "
"Rendering takes ages, returning."
<< std::endl;
return;
}
// Check and abort if the machine is swapping a lot
if (draw.getTimerTime() > 2000) {
infostream << "ClientMap::renderMap(): Rendering took >2s, " <<
"returning." << std::endl;
return;
}
driver->setMaterial(list.m);
for (scene::IMeshBuffer *buf : list.bufs) {
driver->drawMeshBuffer(buf);
vertex_count += buf->getVertexCount();
meshbuffer_count++;
}
}
}
} // ScopeProfiler
g_profiler->avg(prefix + "draw meshes [ms]", draw.stop(true));
// Log only on solid pass because values are the same
if (pass == scene::ESNRP_SOLID) {
g_profiler->avg("CM: animated meshes", mesh_animate_count);
g_profiler->avg("CM: animated meshes (far)", mesh_animate_count_far);
g_profiler->avg("renderMap(): animated meshes [#]", mesh_animate_count);
}
g_profiler->avg(prefix + "vertices drawn", vertex_count);
if (blocks_had_pass_meshbuf != 0)
g_profiler->avg(prefix + "meshbuffers per block",
(float)meshbuffer_count / (float)blocks_had_pass_meshbuf);
if (blocks_drawn != 0)
g_profiler->avg(prefix + "empty blocks (frac)",
(float)blocks_without_stuff / blocks_drawn);
g_profiler->avg(prefix + "vertices drawn [#]", vertex_count);
}
static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
@ -555,6 +491,7 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step,
int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
int oldvalue, bool *sunlight_seen_result)
{
ScopeProfiler sp(g_profiler, "CM::getBackgroundBrightness", SPT_AVG);
static v3f z_directions[50] = {
v3f(-100, 0, 0)
};