Avoid doing a full material compare if not even first texture does match

This commit is contained in:
sapier 2014-06-12 22:33:50 +02:00
parent 35ec3855f6
commit 334ec4bb1b

@ -58,7 +58,7 @@ ClientMap::ClientMap(
ClientMap::~ClientMap() ClientMap::~ClientMap()
{ {
/*JMutexAutoLock lock(mesh_mutex); /*JMutexAutoLock lock(mesh_mutex);
if(mesh != NULL) if(mesh != NULL)
{ {
mesh->drop(); mesh->drop();
@ -76,15 +76,15 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
{ {
} }
// Create a sector // Create a sector
ClientMapSector *sector = new ClientMapSector(this, p2d, m_gamedef); ClientMapSector *sector = new ClientMapSector(this, p2d, m_gamedef);
{ {
//JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
m_sectors[p2d] = sector; m_sectors[p2d] = sector;
} }
return sector; return sector;
} }
@ -95,7 +95,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
ClientMapSector *sector = NULL; ClientMapSector *sector = NULL;
//JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d); core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d);
if(n != NULL) if(n != NULL)
@ -198,7 +198,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
p_nodes_max.X / MAP_BLOCKSIZE + 1, p_nodes_max.X / MAP_BLOCKSIZE + 1,
p_nodes_max.Y / MAP_BLOCKSIZE + 1, p_nodes_max.Y / MAP_BLOCKSIZE + 1,
p_nodes_max.Z / MAP_BLOCKSIZE + 1); p_nodes_max.Z / MAP_BLOCKSIZE + 1);
// Number of blocks in rendering range // Number of blocks in rendering range
u32 blocks_in_range = 0; u32 blocks_in_range = 0;
// Number of blocks occlusion culled // Number of blocks occlusion culled
@ -223,7 +223,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
{ {
MapSector *sector = si->second; MapSector *sector = si->second;
v2s16 sp = sector->getPos(); v2s16 sp = sector->getPos();
if(m_control.range_all == false) if(m_control.range_all == false)
{ {
if(sp.X < p_blocks_min.X if(sp.X < p_blocks_min.X
@ -235,13 +235,13 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
std::list< MapBlock * > sectorblocks; std::list< MapBlock * > sectorblocks;
sector->getBlocks(sectorblocks); sector->getBlocks(sectorblocks);
/* /*
Loop through blocks in sector Loop through blocks in sector
*/ */
u32 sector_blocks_drawn = 0; u32 sector_blocks_drawn = 0;
std::list< MapBlock * >::iterator i; std::list< MapBlock * >::iterator i;
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++) for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
{ {
@ -251,10 +251,10 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
Compare block position to camera position, skip Compare block position to camera position, skip
if not seen on display if not seen on display
*/ */
if (block->mesh != NULL) if (block->mesh != NULL)
block->mesh->updateCameraOffset(m_camera_offset); block->mesh->updateCameraOffset(m_camera_offset);
float range = 100000 * BS; float range = 100000 * BS;
if(m_control.range_all == false) if(m_control.range_all == false)
range = m_control.wanted_range * BS; range = m_control.wanted_range * BS;
@ -273,7 +273,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
continue;*/ continue;*/
blocks_in_range++; blocks_in_range++;
/* /*
Ignore if mesh doesn't exist Ignore if mesh doesn't exist
*/ */
@ -334,7 +334,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
blocks_occlusion_culled++; blocks_occlusion_culled++;
continue; continue;
} }
// This block is in range. Reset usage timer. // This block is in range. Reset usage timer.
block->resetUsageTimer(); block->resetUsageTimer();
@ -383,18 +383,25 @@ struct MeshBufList
struct MeshBufListList struct MeshBufListList
{ {
std::list<MeshBufList> lists; std::list<MeshBufList> lists;
void clear() void clear()
{ {
lists.clear(); lists.clear();
} }
void add(scene::IMeshBuffer *buf) void add(scene::IMeshBuffer *buf)
{ {
for(std::list<MeshBufList>::iterator i = lists.begin(); for(std::list<MeshBufList>::iterator i = lists.begin();
i != lists.end(); ++i){ i != lists.end(); ++i){
MeshBufList &l = *i; MeshBufList &l = *i;
if(l.m == buf->getMaterial()){ video::SMaterial &m = buf->getMaterial();
// comparing a full material is quite expensive so we don't do it if
// not even first texture is equal
if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture)
continue;
if (l.m == m) {
l.bufs.push_back(buf); l.bufs.push_back(buf);
return; return;
} }
@ -411,7 +418,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT; bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
std::string prefix; std::string prefix;
if(pass == scene::ESNRP_SOLID) if(pass == scene::ESNRP_SOLID)
prefix = "CM: solid: "; prefix = "CM: solid: ";
@ -432,7 +439,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
/* /*
Get time for measuring timeout. Get time for measuring timeout.
Measuring time is very useful for long delays when the Measuring time is very useful for long delays when the
machine is swapping a lot. machine is swapping a lot.
*/ */
@ -456,7 +463,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
*/ */
v3s16 cam_pos_nodes = floatToInt(camera_position, BS); v3s16 cam_pos_nodes = floatToInt(camera_position, BS);
v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1); v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1);
v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d; v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
@ -472,14 +479,14 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
p_nodes_max.X / MAP_BLOCKSIZE + 1, p_nodes_max.X / MAP_BLOCKSIZE + 1,
p_nodes_max.Y / MAP_BLOCKSIZE + 1, p_nodes_max.Y / MAP_BLOCKSIZE + 1,
p_nodes_max.Z / MAP_BLOCKSIZE + 1); p_nodes_max.Z / MAP_BLOCKSIZE + 1);
u32 vertex_count = 0; u32 vertex_count = 0;
u32 meshbuffer_count = 0; u32 meshbuffer_count = 0;
// For limiting number of mesh animations per frame // For limiting number of mesh animations per frame
u32 mesh_animate_count = 0; u32 mesh_animate_count = 0;
u32 mesh_animate_count_far = 0; u32 mesh_animate_count_far = 0;
// Blocks that were drawn and had a mesh // Blocks that were drawn and had a mesh
u32 blocks_drawn = 0; u32 blocks_drawn = 0;
// Blocks which had a corresponding meshbuffer for this pass // Blocks which had a corresponding meshbuffer for this pass
@ -505,7 +512,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
// If the mesh of the block happened to get deleted, ignore it // If the mesh of the block happened to get deleted, ignore it
if(block->mesh == NULL) if(block->mesh == NULL)
continue; continue;
float d = 0.0; float d = 0.0;
if(isBlockInSight(block->getPos(), camera_position, if(isBlockInSight(block->getPos(), camera_position,
camera_direction, camera_fov, camera_direction, camera_fov,
@ -577,9 +584,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
} }
} }
} }
std::list<MeshBufList> &lists = drawbufs.lists; std::list<MeshBufList> &lists = drawbufs.lists;
int timecheck_counter = 0; int timecheck_counter = 0;
for(std::list<MeshBufList>::iterator i = lists.begin(); for(std::list<MeshBufList>::iterator i = lists.begin();
i != lists.end(); ++i) i != lists.end(); ++i)
@ -601,9 +608,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
} }
MeshBufList &list = *i; MeshBufList &list = *i;
driver->setMaterial(list.m); driver->setMaterial(list.m);
for(std::list<scene::IMeshBuffer*>::iterator j = list.bufs.begin(); for(std::list<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
j != list.bufs.end(); ++j) j != list.bufs.end(); ++j)
{ {
@ -660,13 +667,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
#endif #endif
} }
} // ScopeProfiler } // ScopeProfiler
// Log only on solid pass because values are the same // Log only on solid pass because values are the same
if(pass == scene::ESNRP_SOLID){ if(pass == scene::ESNRP_SOLID){
g_profiler->avg("CM: animated meshes", mesh_animate_count); g_profiler->avg("CM: animated meshes", mesh_animate_count);
g_profiler->avg("CM: animated meshes (far)", mesh_animate_count_far); g_profiler->avg("CM: animated meshes (far)", mesh_animate_count_far);
} }
g_profiler->avg(prefix+"vertices drawn", vertex_count); g_profiler->avg(prefix+"vertices drawn", vertex_count);
if(blocks_had_pass_meshbuf != 0) if(blocks_had_pass_meshbuf != 0)
g_profiler->avg(prefix+"meshbuffers per block", g_profiler->avg(prefix+"meshbuffers per block",
@ -717,7 +724,7 @@ static bool getVisibleBrightness(Map *map, v3f p0, v3f dir, float step,
pf += dir * step; pf += dir * step;
distance += step; distance += step;
step *= step_multiplier; step *= step_multiplier;
v3s16 p = floatToInt(pf, BS); v3s16 p = floatToInt(pf, BS);
MapNode n = map->getNodeNoEx(p); MapNode n = map->getNodeNoEx(p);
if(allow_allowing_non_sunlight_propagates && i == 0 && if(allow_allowing_non_sunlight_propagates && i == 0 &&