Timing improvements

master
Mark 2024-01-10 19:47:30 -08:00
parent be2cca79b0
commit 188dc9eb89
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
10 changed files with 100 additions and 35 deletions

1
Cargo.lock generated
View File

@ -714,6 +714,7 @@ dependencies = [
"crossbeam", "crossbeam",
"galactica-content", "galactica-content",
"galactica-galaxy", "galactica-galaxy",
"galactica-util",
"nalgebra", "nalgebra",
"rand", "rand",
"rapier2d", "rapier2d",

View File

@ -121,11 +121,11 @@ impl Game {
pub fn update(&mut self) { pub fn update(&mut self) {
let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale; let t: f32 = self.last_update.elapsed().as_secs_f32() * self.time_scale;
self.timing.start(); self.timing.start_frame();
self.timing.start_galaxy();
self.galaxy.step(t); self.galaxy.step(t);
self.timing.mark_galaxy(); self.timing.mark_galaxy();
self.timing.start();
self.systemsim.step(StepResources { self.systemsim.step(StepResources {
player: self.player, player: self.player,
player_controls: ShipControls { player_controls: ShipControls {
@ -137,9 +137,9 @@ impl Game {
ct: &self.content, ct: &self.content,
gx: &mut self.galaxy, gx: &mut self.galaxy,
particles: &mut self.new_particles, particles: &mut self.new_particles,
timing: &mut self.timing,
t, t,
}); });
self.timing.mark_physics();
if self.input.v_scroll != 0.0 { if self.input.v_scroll != 0.0 {
self.camera.zoom = (self.camera.zoom + self.input.v_scroll).clamp(ZOOM_MIN, ZOOM_MAX); self.camera.zoom = (self.camera.zoom + self.input.v_scroll).clamp(ZOOM_MIN, ZOOM_MAX);
@ -153,6 +153,7 @@ impl Game {
}; };
self.last_update = Instant::now(); self.last_update = Instant::now();
self.timing.mark_frame();
} }
pub fn get_frame_state(&mut self) -> RenderInput { pub fn get_frame_state(&mut self) -> RenderInput {
@ -166,7 +167,7 @@ impl Game {
player_data: self.player, player_data: self.player,
data: &self.galaxy, data: &self.galaxy,
current_system: SystemHandle { index: 0 }, current_system: SystemHandle { index: 0 },
timing: &self.timing, timing: &mut self.timing,
} }
} }
} }

View File

@ -41,7 +41,7 @@ pub struct RenderInput<'a> {
pub particles: &'a mut Vec<ParticleBuilder>, pub particles: &'a mut Vec<ParticleBuilder>,
/// Time we spent in each part of the game loop /// Time we spent in each part of the game loop
pub timing: &'a Timing, pub timing: &'a mut Timing,
} }
/// Renderer state. A reference to this struct is often passed to helper functions. /// Renderer state. A reference to this struct is often passed to helper functions.

View File

@ -19,7 +19,7 @@ use crate::{
impl super::GPUState { impl super::GPUState {
/// Main render function. Draws sprites on a window. /// Main render function. Draws sprites on a window.
pub fn render(&mut self, input: RenderInput) -> Result<(), wgpu::SurfaceError> { pub fn render(&mut self, input: RenderInput) -> Result<(), wgpu::SurfaceError> {
// Set up text renderer input.timing.start_render();
let output = self.surface.get_current_texture()?; let output = self.surface.get_current_texture()?;
let view = output.texture.create_view(&Default::default()); let view = output.texture.create_view(&Default::default());
@ -214,6 +214,7 @@ impl super::GPUState {
self.state.queue.submit(iter::once(encoder.finish())); self.state.queue.submit(iter::once(encoder.finish()));
output.present(); output.present();
input.timing.mark_render();
Ok(()) Ok(())
} }
} }

View File

@ -1,11 +1,9 @@
use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds}; use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds};
use std::time::Instant;
use crate::{datastructs::RenderState, RenderInput}; use crate::{datastructs::RenderState, RenderInput};
pub(super) struct FpsIndicator { pub(super) struct FpsIndicator {
buffer: Buffer, buffer: Buffer,
last_update: Instant,
update_counter: u32, update_counter: u32,
} }
@ -21,7 +19,6 @@ impl FpsIndicator {
Self { Self {
buffer, buffer,
last_update: Instant::now(),
update_counter: 0, update_counter: 0,
} }
} }
@ -39,15 +36,16 @@ impl FpsIndicator {
self.buffer.set_text( self.buffer.set_text(
&mut state.text_font_system, &mut state.text_font_system,
&format!( &format!(
"Game: {:.02?}\nPhys: {:.02?}\nRender: {:.02?}", "Frame: {:04.02?}%\nGame: {:04.02?}%\nShips: {:04.02?}%\nPhys: {:04.02?}%\nRender: {:.02?}",
1.0 / input.timing.galaxy, 100.0 * (input.timing.frame / input.timing.render),
1.0 / input.timing.physics, 100.0 * (input.timing.galaxy / input.timing.frame),
1.0 / (self.last_update.elapsed().as_secs_f32() / 100.0) 100.0 * (input.timing.physics_sim / input.timing.frame),
100.0 * (input.timing.physics_ship / input.timing.frame),
1.0 / input.timing.render
), ),
Attrs::new().family(Family::SansSerif), Attrs::new().family(Family::Monospace),
Shaping::Basic, Shaping::Basic,
); );
self.last_update = Instant::now();
} }
pub fn get_textarea(&self) -> TextArea { pub fn get_textarea(&self) -> TextArea {

View File

@ -1,8 +1,7 @@
use glyphon::TextArea; use glyphon::TextArea;
use crate::{datastructs::RenderState, RenderInput};
use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status}; use super::{fpsindicator::FpsIndicator, radar::Radar, status::Status};
use crate::{datastructs::RenderState, RenderInput};
pub struct UiManager { pub struct UiManager {
radar: Radar, radar: Radar,
@ -26,7 +25,7 @@ impl UiManager {
self.fps.update(input, state); self.fps.update(input, state);
} }
pub fn get_textareas(&self) -> impl Iterator<Item = TextArea> { pub fn get_textareas(&self) -> [TextArea; 1] {
(0..1).map(|_| self.fps.get_textarea()) [self.fps.get_textarea()]
} }
} }

View File

@ -19,6 +19,7 @@ workspace = true
[dependencies] [dependencies]
galactica-content = { workspace = true } galactica-content = { workspace = true }
galactica-galaxy = { workspace = true } galactica-galaxy = { workspace = true }
galactica-util = { workspace = true }
rapier2d = { workspace = true } rapier2d = { workspace = true }
nalgebra = { workspace = true } nalgebra = { workspace = true }

View File

@ -1,6 +1,7 @@
use crate::{objects::ShipControls, ParticleBuilder}; use crate::{objects::ShipControls, ParticleBuilder};
use galactica_content::Content; use galactica_content::Content;
use galactica_galaxy::{Galaxy, GxShipHandle}; use galactica_galaxy::{Galaxy, GxShipHandle};
use galactica_util::timing::Timing;
/// External resources we need to compute time steps /// External resources we need to compute time steps
#[derive(Debug)] #[derive(Debug)]
@ -22,4 +23,7 @@ pub struct StepResources<'a> {
/// The ship that the player controls /// The ship that the player controls
pub player: GxShipHandle, pub player: GxShipHandle,
/// Record detailed frame timing breakdown
pub timing: &'a mut Timing,
} }

View File

@ -385,7 +385,11 @@ impl SystemSim {
/// Step this physics system by `t` seconds /// Step this physics system by `t` seconds
pub fn step(&mut self, mut res: StepResources) { pub fn step(&mut self, mut res: StepResources) {
res.timing.start_physics_ships();
self.step_ships(&mut res); self.step_ships(&mut res);
res.timing.mark_physics_ships();
res.timing.start_physics_sim();
// Update physics // Update physics
self.wrapper.step(res.t, &self.collision_handler); self.wrapper.step(res.t, &self.collision_handler);
@ -457,6 +461,8 @@ impl SystemSim {
} }
}; };
} }
res.timing.mark_physics_sim();
} }
} }

View File

@ -3,42 +3,96 @@ use std::time::Instant;
/// Utility struct. /// Utility struct.
/// Keeps track of the time we spent in each part of the game loop. /// Keeps track of the time we spent in each part of the game loop.
#[derive(Debug)]
pub struct Timing { pub struct Timing {
timer: Option<Instant>, /// The time we spent processing the whole frame
pub frame: f32,
frame_timer: Instant,
/// The time we spent simulating game state /// The time we spent simulating game state
pub galaxy: f32, pub galaxy: f32,
galaxy_timer: Instant,
/// The time we spent simulating physics /// The time we spent simulating physics
pub physics: f32, pub physics_sim: f32,
physics_sim_timer: Instant,
/// The time we spent updating physics ships
pub physics_ship: f32,
physics_ship_timer: Instant,
/// The time we spent simulating physics
pub render: f32,
render_timer: Instant,
} }
// TODO: macros
// TODO: document each duration
impl Timing { impl Timing {
/// Create a new timing struct /// Create a new timing struct
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
timer: None, frame: f32::NAN,
galaxy: f32::NAN, galaxy: f32::NAN,
physics: f32::NAN, physics_sim: f32::NAN,
physics_ship: f32::NAN,
render: f32::NAN,
galaxy_timer: Instant::now(),
physics_sim_timer: Instant::now(),
physics_ship_timer: Instant::now(),
render_timer: Instant::now(),
frame_timer: Instant::now(),
} }
} }
/// Start the timer /// Start frame timer
pub fn start(&mut self) { pub fn start_frame(&mut self) {
self.timer = Some(Instant::now()); self.frame_timer = Instant::now();
} }
/// Clear timer and record galaxy simulation time. /// Start galaxy timer
/// Assumes timer has been started pub fn start_galaxy(&mut self) {
self.galaxy_timer = Instant::now();
}
/// Start physics sim timer
pub fn start_physics_sim(&mut self) {
self.physics_sim_timer = Instant::now();
}
/// Start physics ship timer
pub fn start_physics_ships(&mut self) {
self.physics_ship_timer = Instant::now();
}
/// Start render timer
pub fn start_render(&mut self) {
self.render_timer = Instant::now();
}
/// Record galaxy simulation time.
pub fn mark_frame(&mut self) {
self.frame = self.frame_timer.elapsed().as_secs_f32();
}
/// Record galaxy simulation time.
pub fn mark_galaxy(&mut self) { pub fn mark_galaxy(&mut self) {
self.galaxy = self.timer.unwrap().elapsed().as_secs_f32(); self.galaxy = self.galaxy_timer.elapsed().as_secs_f32();
self.timer = None;
} }
/// Clear timer and record physics simulation time /// Record physics simulation time
/// Asumes timer has been started pub fn mark_physics_sim(&mut self) {
pub fn mark_physics(&mut self) { self.physics_sim = self.physics_sim_timer.elapsed().as_secs_f32();
self.physics = self.timer.unwrap().elapsed().as_secs_f32(); }
self.timer = None;
/// Record physics ship update time
pub fn mark_physics_ships(&mut self) {
self.physics_ship = self.physics_ship_timer.elapsed().as_secs_f32();
}
/// Record physics simulation time
pub fn mark_render(&mut self) {
self.render = self.render_timer.elapsed().as_secs_f32();
} }
} }