mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Throttled mesh scheduling to improve remesh performance
This commit is contained in:
parent
6fc2096dae
commit
ef973faadf
@ -23,7 +23,7 @@ struct TerrainChunk {
|
||||
struct ChunkMeshState {
|
||||
pos: Vec2<i32>,
|
||||
started_tick: u64,
|
||||
active_worker: bool,
|
||||
active_worker: Option<u64>,
|
||||
}
|
||||
|
||||
/// A type produced by mesh worker threads corresponding to the position and mesh of a chunk.
|
||||
@ -129,7 +129,7 @@ impl Terrain {
|
||||
ChunkMeshState {
|
||||
pos,
|
||||
started_tick: current_tick,
|
||||
active_worker: false,
|
||||
active_worker: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -147,8 +147,16 @@ impl Terrain {
|
||||
.mesh_todo
|
||||
.values_mut()
|
||||
// Only spawn workers for meshing jobs without an active worker already.
|
||||
.filter(|todo| !todo.active_worker)
|
||||
.filter(|todo| {
|
||||
todo.active_worker
|
||||
.map(|worker_tick| worker_tick < todo.started_tick)
|
||||
.unwrap_or(true)
|
||||
})
|
||||
{
|
||||
if client.thread_pool().queued_count() > 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the area of the terrain we want. Because meshing needs to compute things like
|
||||
// ambient occlusion and edge elision, we also need the borders of the chunk's
|
||||
// neighbours too (hence the `- 1` and `+ 1`).
|
||||
@ -189,16 +197,17 @@ impl Terrain {
|
||||
let pos = todo.pos;
|
||||
|
||||
// Queue the worker thread.
|
||||
let started_tick = todo.started_tick;
|
||||
client.thread_pool().execute(move || {
|
||||
let _ = send.send(mesh_worker(
|
||||
pos,
|
||||
(min_z as f32, max_z as f32),
|
||||
current_tick,
|
||||
started_tick,
|
||||
volume,
|
||||
aabb,
|
||||
));
|
||||
});
|
||||
todo.active_worker = true;
|
||||
todo.active_worker = Some(todo.started_tick);
|
||||
}
|
||||
|
||||
// Receive a chunk mesh from a worker thread and upload it to the GPU, then store it.
|
||||
@ -208,7 +217,7 @@ impl Terrain {
|
||||
match self.mesh_todo.get(&response.pos) {
|
||||
// It's the mesh we want, insert the newly finished model into the terrain model
|
||||
// data structure (convert the mesh to a model first of course).
|
||||
Some(todo) if response.started_tick == todo.started_tick => {
|
||||
Some(todo) if response.started_tick <= todo.started_tick => {
|
||||
self.chunks.insert(
|
||||
response.pos,
|
||||
TerrainChunk {
|
||||
@ -230,7 +239,9 @@ impl Terrain {
|
||||
},
|
||||
);
|
||||
|
||||
self.mesh_todo.remove(&response.pos);
|
||||
if response.started_tick == todo.started_tick {
|
||||
self.mesh_todo.remove(&response.pos);
|
||||
}
|
||||
}
|
||||
// Chunk must have been removed, or it was spawned on an old tick. Drop the mesh
|
||||
// since it's either out of date or no longer needed.
|
||||
|
Loading…
Reference in New Issue
Block a user