Adjusted terrain loading and meshing performance

Former-commit-id: b55800b559289bf925d56096f29c0cfbc22439d2
This commit is contained in:
Joshua Barretto 2019-04-25 17:52:08 +01:00
parent 0b0c71592c
commit f136a63f69
3 changed files with 98 additions and 89 deletions

View File

@ -170,106 +170,113 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
let mut incoming_buf = Vec::new();
'work: while running.load(Ordering::Relaxed) {
// Get stream errors
match stream.take_error() {
Ok(Some(e)) | Err(e) => {
recv_tx.send(Err(e.into())).unwrap();
break 'work;
},
Ok(None) => {},
}
// Try getting messages from the send channel
for _ in 0..1000 {
match send_rx.try_recv() {
Ok(send_msg) => {
// Serialize message
let mut msg_bytes = bincode::serialize(&send_msg).unwrap();
// Assemble into packet
let mut packet_bytes = msg_bytes
.len()
.to_le_bytes()
.as_ref()
.to_vec();
packet_bytes.append(&mut msg_bytes);
// Split packet into chunks
packet_bytes
.chunks(4096)
.map(|chunk| chunk.to_vec())
.for_each(|chunk| outgoing_chunks.push_back(chunk))
},
Err(mpsc::TryRecvError::Empty) => break,
// Worker error
Err(e) => {
let _ = recv_tx.send(Err(e.into()));
for _ in 0..30 {
// Get stream errors
match stream.take_error() {
Ok(Some(e)) | Err(e) => {
recv_tx.send(Err(e.into())).unwrap();
break 'work;
},
Ok(None) => {},
}
}
// Try sending bytes through the TCP stream
for _ in 0..1000 {
//println!("HERE! Outgoing len: {}", outgoing_chunks.len());
match outgoing_chunks.pop_front() {
Some(chunk) => match stream.write_all(&chunk) {
Ok(()) => {},
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// Return chunk to the queue to try again later
outgoing_chunks.push_front(chunk);
break;
// Try getting messages from the send channel
for _ in 0..100 {
match send_rx.try_recv() {
Ok(send_msg) => {
// Serialize message
let mut msg_bytes = bincode::serialize(&send_msg).unwrap();
// Assemble into packet
let mut packet_bytes = msg_bytes
.len()
.to_le_bytes()
.as_ref()
.to_vec();
packet_bytes.append(&mut msg_bytes);
// Split packet into chunks
packet_bytes
.chunks(4096)
.map(|chunk| chunk.to_vec())
.for_each(|chunk| outgoing_chunks.push_back(chunk))
},
Err(mpsc::TryRecvError::Empty) => break,
// Worker error
Err(e) => {
let _ = recv_tx.send(Err(e.into()));
break 'work;
},
}
}
// Try sending bytes through the TCP stream
for _ in 0..100 {
//println!("HERE! Outgoing len: {}", outgoing_chunks.len());
match outgoing_chunks.pop_front() {
Some(mut chunk) => match stream.write(&chunk) {
Ok(n) => if n == chunk.len() {},
Ok(n) => {
outgoing_chunks.push_front(chunk.split_off(n));
break;
},
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
// Return chunk to the queue to try again later
outgoing_chunks.push_front(chunk);
break;
},
// Worker error
Err(e) => {
println!("SEND ERROR: {:?}", e);
recv_tx.send(Err(e.into())).unwrap();
break 'work;
},
},
None => break,
}
}
// Try receiving bytes from the TCP stream
for _ in 0..100 {
let mut buf = [0; 4096];
match stream.read(&mut buf) {
Ok(n) => incoming_buf.extend_from_slice(&buf[0..n]),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => break,
Err(e) if e.kind() == io::ErrorKind::Interrupted => {},
// Worker error
Err(e) => {
recv_tx.send(Err(e.into())).unwrap();
break 'work;
},
},
None => break,
}
}
}
// Try receiving bytes from the TCP stream
for _ in 0..1000 {
let mut buf = [0; 1024];
// Try turning bytes into messages
for _ in 0..100 {
match incoming_buf.get(0..8) {
Some(len_bytes) => {
let len = usize::from_le_bytes(<[u8; 8]>::try_from(len_bytes).unwrap()); // Can't fail
match stream.read(&mut buf) {
Ok(n) => incoming_buf.extend_from_slice(&buf[0..n]),
Err(e) if e.kind() == io::ErrorKind::WouldBlock => break,
Err(e) if e.kind() == io::ErrorKind::Interrupted => {},
// Worker error
Err(e) => {
recv_tx.send(Err(e.into())).unwrap();
break 'work;
},
}
}
if len > MAX_MSG_SIZE {
recv_tx.send(Err(Error::InvalidMessage)).unwrap();
break 'work;
} else if incoming_buf.len() >= len + 8 {
match bincode::deserialize(&incoming_buf[8..len + 8]) {
Ok(msg) => recv_tx.send(Ok(msg)).unwrap(),
Err(err) => {
println!("Invalid message: {:?}", err);
recv_tx.send(Err(err.into())).unwrap()
},
}
// Try turning bytes into messages
for _ in 0..1000 {
match incoming_buf.get(0..8) {
Some(len_bytes) => {
let len = usize::from_le_bytes(<[u8; 8]>::try_from(len_bytes).unwrap()); // Can't fail
if len > MAX_MSG_SIZE {
recv_tx.send(Err(Error::InvalidMessage)).unwrap();
break 'work;
} else if incoming_buf.len() >= len + 8 {
match bincode::deserialize(&incoming_buf[8..len + 8]) {
Ok(msg) => recv_tx.send(Ok(msg)).unwrap(),
Err(err) => {
println!("Invalid message: {:?}", err);
recv_tx.send(Err(err.into())).unwrap()
},
incoming_buf = incoming_buf.split_off(len + 8);
} else {
break;
}
incoming_buf = incoming_buf.split_off(len + 8);
} else {
break;
}
},
None => break,
},
None => break,
}
}
}

View File

@ -257,7 +257,7 @@ impl<S: Skeleton> FigureState<S> {
let mat =
Mat4::<f32>::identity() *
Mat4::translation_3d(pos) *
Mat4::rotation_z(-dir.x.atan2(dir.y));// + f32//::consts)::PI / 2.0);
Mat4::rotation_z(-dir.x.atan2(dir.y) + f32::consts::PI / 2.0);
let locals = FigureLocals::new(mat);
renderer.update_consts(&mut self.locals, &[locals]).unwrap();

View File

@ -165,8 +165,10 @@ impl Terrain {
todo.active_worker = true;
});
// Receive chunk meshes from worker threads, upload them to the GPU and then store them
while let Ok(response) = self.mesh_recv.recv_timeout(Duration::new(0, 0)) {
// Receive a chunk mesh from a worker thread, upload it to the GPU and then store it
// Only pull out one chunk per frame to avoid an unacceptable amount of blocking lag due
// to the GPU upload. That still gives us a 60 chunks / second budget to play with.
if let Ok(response) = self.mesh_recv.recv_timeout(Duration::new(0, 0)) {
match self.mesh_todo.iter().find(|todo| todo.pos == 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)
@ -180,7 +182,7 @@ impl Terrain {
},
// 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
_ => continue,
_ => {},
}
}
}